UPSTREAM: pwm: rockchip: Fix period and duty cycle approximation
authorBoris Brezillon <boris.brezillon@free-electrons.com>
Tue, 14 Jun 2016 09:13:11 +0000 (11:13 +0200)
committerHuang, Tao <huangtao@rock-chips.com>
Mon, 6 Mar 2017 10:28:40 +0000 (18:28 +0800)
commitd0a5c68483f67cb85c72a56c2740074540210483
tree84fd7c0a61b473814b249a475f2875f1ac82aad3
parentccdd1537531ad6272c422685e4355b0a983ce806
UPSTREAM: pwm: rockchip: Fix period and duty cycle approximation

The current implementation always round down the duty and period values,
while it would be better to round them to the closest integer.

These changes are needed in preparation of atomic update support to
prevent a period/duty cycle drift when executing several times the
'pwm_get_state() / modify / pwm_apply_state()' sequence.

Say you have an expected period of 3.333 us and a clk rate of
112.666667 MHz -- the clock frequency doesn't divide evenly, so the
period (stashed in nanoseconds) shrinks when we convert to the register
value and back, as follows:

  pwm_apply_state(): register = period * 112666667 / 1000000000;
  pwm_get_state(): period = register * 1000000000 / 112666667;

or in other words:

  period = period * 112666667 / 1000000000 * 1000000000 / 112666667;

which yields a sequence like:

  3333 -> 3328
  3328 -> 3319
  3319 -> 3310
  3310 -> 3301
  3301 -> 3292
  3292 -> ... (etc) ...

With this patch, we'd see instead:

  period = div_round_closest(period * 1126666671000000000) *
                   1000000000 / 112666667;

which yields a stable sequence:

  3333 -> 3337
  3337 -> 3337
  3337 -> ... (etc) ...

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
(cherry picked from commit 12f9ce4a519845070d338253ab9528b5d7e2df34)

Change-Id: Ife75404e663d1380725d634ac621b2ca9f831791
Signed-off-by: David Wu <david.wu@rock-chips.com>
drivers/pwm/pwm-rockchip.c