Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1421708

[PATCH v3 03/14] pwm: rockchip: Fix period and duty_cycle approximation

Path csiph.com!eternal-september.org!feeder.eternal-september.org!aioe.org!gothmog.csi.it!bofh.it!news.nic.it!robomod
From Boris Brezillon <boris.brezillon@free-electrons.com>
Newsgroups linux.kernel
Subject [PATCH v3 03/14] pwm: rockchip: Fix period and duty_cycle approximation
Date Tue, 14 Jun 2016 11:20:02 +0200
Message-ID <rJSFQ-2Rh-47@gated-at.bofh.it> (permalink)
References <rJSFP-2Rh-5@gated-at.bofh.it>
X-Mailer git-send-email 2.7.4
Sender robomod@news.nic.it
List-ID <linux-kernel.vger.kernel.org>
X-Mailing-List linux-kernel@vger.kernel.org
Approved robomod@news.nic.it
Lines 69
Organization linux.* mail to news gateway
X-Original-Cc Heiko Stuebner <heiko@sntech.de>, linux-rockchip@lists.infradead.org, Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>, Mark Rutland <mark.rutland@arm.com>, Ian Campbell <ijc+devicetree@hellion.org.uk>, Kumar Gala <galak@codeaurora.org>, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Milo Kim <milo.kim@ti.com>, Doug Anderson <dianders@google.com>, Caesar Wang <wxt@rock-chips.com>, Stephen Barber <smbarber@chromium.org>, Brian Norris <briannorris@chromium.org>, Ajit Pal Singh <ajitpal.singh@st.com>, Srinivas Kandagatla <srinivas.kandagatla@gmail.com>, Maxime Coquelin <maxime.coquelin@st.com>, Patrice Chotard <patrice.chotard@st.com>, kernel@stlinux.com, Laxman Dewangan <ldewangan@nvidia.com>, Boris Brezillon <boris.brezillon@free-electrons.com>
X-Original-Date Tue, 14 Jun 2016 11:13:11 +0200
X-Original-Message-ID <1465895602-31008-4-git-send-email-boris.brezillon@free-electrons.com>
X-Original-References <1465895602-31008-1-git-send-email-boris.brezillon@free-electrons.com>
X-Original-Sender linux-kernel-owner@vger.kernel.org
Xref csiph.com linux.kernel:1421708

Show key headers only | View raw


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 time 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 * 112666667, 1000000000) *
	   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>
---
 drivers/pwm/pwm-rockchip.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 7d9cc90..68d72ce 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -114,12 +114,11 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * default prescaler value for all practical clock rate values.
 	 */
 	div = clk_rate * period_ns;
-	do_div(div, pc->data->prescaler * NSEC_PER_SEC);
-	period = div;
+	period = DIV_ROUND_CLOSEST_ULL(div,
+				       pc->data->prescaler * NSEC_PER_SEC);
 
 	div = clk_rate * duty_ns;
-	do_div(div, pc->data->prescaler * NSEC_PER_SEC);
-	duty = div;
+	duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
 
 	ret = clk_enable(pc->clk);
 	if (ret)
-- 
2.7.4

Back to linux.kernel | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

[PATCH v3 00/14] regulator: pwm: various improvements Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 04/14] pwm: rockchip: Add support for hardware readout Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 05/14] pwm: rockchip: Avoid glitches on already running PWMs Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 09/14] regulator: pwm: Adjust PWM config at probe time Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 02/14] pwm: Add two helpers to ease relative duty cycle manipulation Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 08/14] pwm: sti: Avoid glitches on already running PWMs Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 13/14] regulator: pwm: Support extra continuous mode cases Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200
  [PATCH v3 03/14] pwm: rockchip: Fix period and duty_cycle approximation Boris Brezillon <boris.brezillon@free-electrons.com> - 2016-06-14 11:20 +0200

csiph-web