From: Neil Armstrong <narmstrong@baylibre.com>
To: "David Rivshin (Allworx)" <drivshin.allworx@gmail.com>,
linux-pwm@vger.kernel.org,
Thierry Reding <thierry.reding@gmail.com>
Cc: linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Tony Lindgren <tony@atomide.com>,
Grant Erickson <marathon96@gmail.com>, NeilBrown <neilb@suse.de>,
Joachim Eastwood <manabian@gmail.com>
Subject: Re: [PATCH 1/4] pwm: omap-dmtimer: fix inaccurate period/duty_cycle calculation
Date: Wed, 3 Feb 2016 11:23:43 +0100 [thread overview]
Message-ID: <56B1D52F.70907@baylibre.com> (raw)
In-Reply-To: <1454128014-22866-2-git-send-email-drivshin.allworx@gmail.com>
On 01/30/2016 05:26 AM, David Rivshin (Allworx) wrote:
> From: David Rivshin <drivshin@allworx.com>
>
> Fix the calculation of load_value and match_value. Currently they
> are slightly too low, which produces a noticeably wrong PWM rate with
> sufficiently short periods (i.e. when 1/period approaches clk_rate/2).
>
> Example:
> clk_rate=32768Hz, period=122070ns, duty_cycle=61035ns (8192Hz/50% PWM)
> Correct values: load = 0xfffffffc, match = 0xfffffffd
> Current values: load = 0xfffffffa, match = 0xfffffffc
> effective PWM: period=183105ns, duty_cycle=91553ns (5461Hz/50% PWM)
>
> Fixes: 6604c6556db9 ("pwm: Add PWM driver for OMAP using dual-mode timers")
> Signed-off-by: David Rivshin <drivshin@allworx.com>
OK for me.
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Thanks !
> ---
> drivers/pwm/pwm-omap-dmtimer.c | 27 ++++++++++++++++++++-------
> 1 file changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
> index 826634e..0083e75 100644
> --- a/drivers/pwm/pwm-omap-dmtimer.c
> +++ b/drivers/pwm/pwm-omap-dmtimer.c
> @@ -31,6 +31,7 @@
> #include <linux/time.h>
>
> #define DM_TIMER_LOAD_MIN 0xfffffffe
> +#define DM_TIMER_MAX 0xffffffff
>
> struct pwm_omap_dmtimer_chip {
> struct pwm_chip chip;
> @@ -46,13 +47,13 @@ to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
> return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
> }
>
> -static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns)
> +static u32 pwm_omap_dmtimer_get_clock_cycles(unsigned long clk_rate, int ns)
> {
> u64 c = (u64)clk_rate * ns;
>
> do_div(c, NSEC_PER_SEC);
>
> - return DM_TIMER_LOAD_MIN - c;
> + return c;
> }
>
> static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
> @@ -99,7 +100,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
> int duty_ns, int period_ns)
> {
> struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
> - int load_value, match_value;
> + u32 period_cycles, duty_cycles;
> + u32 load_value, match_value;
> struct clk *fclk;
> unsigned long clk_rate;
> bool timer_active;
> @@ -133,11 +135,22 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
> /*
> * Calculate the appropriate load and match values based on the
> * specified period and duty cycle. The load value determines the
> - * cycle time and the match value determines the duty cycle.
> + * period time and the match value determines the duty time.
> + *
> + * The period lasts for (DM_TIMER_MAX-load_value+1) clock cycles.
> + * Similarly, the active time lasts (match_value-load_value+1) cycles.
> + * The non-active time is the remainder: (DM_TIMER_MAX-match_value)
> + * clock cycles.
> + *
> + * References:
> + * OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
> + * AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
> */
> - load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns);
> - match_value = pwm_omap_dmtimer_calc_value(clk_rate,
> - period_ns - duty_ns);
> + period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
> + duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
> +
> + load_value = (DM_TIMER_MAX - period_cycles) + 1;
> + match_value = load_value + duty_cycles - 1;
>
> /*
> * We MUST stop the associated dual-mode timer before attempting to
>
WARNING: multiple messages have this Message-ID (diff)
From: narmstrong@baylibre.com (Neil Armstrong)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/4] pwm: omap-dmtimer: fix inaccurate period/duty_cycle calculation
Date: Wed, 3 Feb 2016 11:23:43 +0100 [thread overview]
Message-ID: <56B1D52F.70907@baylibre.com> (raw)
In-Reply-To: <1454128014-22866-2-git-send-email-drivshin.allworx@gmail.com>
On 01/30/2016 05:26 AM, David Rivshin (Allworx) wrote:
> From: David Rivshin <drivshin@allworx.com>
>
> Fix the calculation of load_value and match_value. Currently they
> are slightly too low, which produces a noticeably wrong PWM rate with
> sufficiently short periods (i.e. when 1/period approaches clk_rate/2).
>
> Example:
> clk_rate=32768Hz, period=122070ns, duty_cycle=61035ns (8192Hz/50% PWM)
> Correct values: load = 0xfffffffc, match = 0xfffffffd
> Current values: load = 0xfffffffa, match = 0xfffffffc
> effective PWM: period=183105ns, duty_cycle=91553ns (5461Hz/50% PWM)
>
> Fixes: 6604c6556db9 ("pwm: Add PWM driver for OMAP using dual-mode timers")
> Signed-off-by: David Rivshin <drivshin@allworx.com>
OK for me.
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Thanks !
> ---
> drivers/pwm/pwm-omap-dmtimer.c | 27 ++++++++++++++++++++-------
> 1 file changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
> index 826634e..0083e75 100644
> --- a/drivers/pwm/pwm-omap-dmtimer.c
> +++ b/drivers/pwm/pwm-omap-dmtimer.c
> @@ -31,6 +31,7 @@
> #include <linux/time.h>
>
> #define DM_TIMER_LOAD_MIN 0xfffffffe
> +#define DM_TIMER_MAX 0xffffffff
>
> struct pwm_omap_dmtimer_chip {
> struct pwm_chip chip;
> @@ -46,13 +47,13 @@ to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
> return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
> }
>
> -static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns)
> +static u32 pwm_omap_dmtimer_get_clock_cycles(unsigned long clk_rate, int ns)
> {
> u64 c = (u64)clk_rate * ns;
>
> do_div(c, NSEC_PER_SEC);
>
> - return DM_TIMER_LOAD_MIN - c;
> + return c;
> }
>
> static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
> @@ -99,7 +100,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
> int duty_ns, int period_ns)
> {
> struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
> - int load_value, match_value;
> + u32 period_cycles, duty_cycles;
> + u32 load_value, match_value;
> struct clk *fclk;
> unsigned long clk_rate;
> bool timer_active;
> @@ -133,11 +135,22 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
> /*
> * Calculate the appropriate load and match values based on the
> * specified period and duty cycle. The load value determines the
> - * cycle time and the match value determines the duty cycle.
> + * period time and the match value determines the duty time.
> + *
> + * The period lasts for (DM_TIMER_MAX-load_value+1) clock cycles.
> + * Similarly, the active time lasts (match_value-load_value+1) cycles.
> + * The non-active time is the remainder: (DM_TIMER_MAX-match_value)
> + * clock cycles.
> + *
> + * References:
> + * OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
> + * AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
> */
> - load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns);
> - match_value = pwm_omap_dmtimer_calc_value(clk_rate,
> - period_ns - duty_ns);
> + period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
> + duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
> +
> + load_value = (DM_TIMER_MAX - period_cycles) + 1;
> + match_value = load_value + duty_cycles - 1;
>
> /*
> * We MUST stop the associated dual-mode timer before attempting to
>
next prev parent reply other threads:[~2016-02-03 10:23 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-30 4:26 [PATCH 0/4] pwm: omap-dmtimer: fix period/duty_cycle calculation David Rivshin (Allworx)
2016-01-30 4:26 ` David Rivshin (Allworx)
2016-01-30 4:26 ` [PATCH 1/4] pwm: omap-dmtimer: fix inaccurate " David Rivshin (Allworx)
2016-01-30 4:26 ` David Rivshin (Allworx)
2016-02-03 10:23 ` Neil Armstrong [this message]
2016-02-03 10:23 ` Neil Armstrong
2016-02-15 20:24 ` Adam Ford
2016-02-15 20:24 ` Adam Ford
2016-03-04 15:17 ` Thierry Reding
2016-03-04 15:17 ` Thierry Reding
2016-01-30 4:26 ` [PATCH 2/4] pwm: omap-dmtimer: add sanity checking for load and match values David Rivshin (Allworx)
2016-01-30 4:26 ` David Rivshin (Allworx)
2016-02-01 18:35 ` David Rivshin (Allworx)
2016-02-01 18:35 ` David Rivshin (Allworx)
2016-02-03 10:24 ` Neil Armstrong
2016-02-03 10:24 ` Neil Armstrong
2016-01-30 4:26 ` [PATCH 3/4] pwm: omap-dmtimer: round load and match values rather than truncate David Rivshin (Allworx)
2016-01-30 4:26 ` David Rivshin (Allworx)
2016-02-03 10:24 ` Neil Armstrong
2016-02-03 10:24 ` Neil Armstrong
2016-03-04 15:18 ` Thierry Reding
2016-03-04 15:18 ` Thierry Reding
2016-01-30 4:26 ` [PATCH 4/4] pwm: omap-dmtimer: add dev_dbg() message for effective period and duty cycle David Rivshin (Allworx)
2016-01-30 4:26 ` David Rivshin (Allworx)
2016-01-30 14:51 ` Neil Armstrong
2016-01-30 14:51 ` Neil Armstrong
2016-02-01 18:22 ` David Rivshin (Allworx)
2016-02-01 18:22 ` David Rivshin (Allworx)
2016-02-01 18:59 ` Tony Lindgren
2016-02-01 18:59 ` Tony Lindgren
2016-02-02 16:23 ` Thierry Reding
2016-02-02 16:23 ` Thierry Reding
2016-02-02 23:44 ` David Rivshin (Allworx)
2016-02-02 23:44 ` David Rivshin (Allworx)
2016-02-03 14:14 ` Thierry Reding
2016-02-03 14:14 ` Thierry Reding
2016-02-05 19:51 ` David Rivshin (Allworx)
2016-02-05 19:51 ` David Rivshin (Allworx)
2016-02-05 19:51 ` David Rivshin (Allworx)
2016-02-09 12:49 ` Neil Armstrong
2016-02-09 12:49 ` Neil Armstrong
2016-01-30 14:52 ` [PATCH 0/4] pwm: omap-dmtimer: fix period/duty_cycle calculation Neil Armstrong
2016-01-30 14:52 ` Neil Armstrong
2016-02-01 20:14 ` David Rivshin (Allworx)
2016-02-01 20:14 ` David Rivshin (Allworx)
2016-02-27 1:31 ` David Rivshin (Allworx)
2016-02-27 1:31 ` David Rivshin (Allworx)
2016-03-04 15:19 ` Thierry Reding
2016-03-04 15:19 ` Thierry Reding
2016-03-04 16:27 ` David Rivshin (Allworx)
2016-03-04 16:27 ` David Rivshin (Allworx)
2016-03-04 16:29 ` Adam Ford
2016-03-04 20:01 ` David Rivshin (Allworx)
2016-03-04 20:01 ` David Rivshin (Allworx)
2016-03-04 20:03 ` Adam Ford
2016-03-04 20:03 ` Adam Ford
2016-03-04 21:18 ` Thierry Reding
2016-03-04 21:18 ` Thierry Reding
2016-03-04 23:20 ` David Rivshin (Allworx)
2016-03-04 23:20 ` David Rivshin (Allworx)
2016-03-08 23:23 ` Adam Ford
2016-03-08 23:23 ` Adam Ford
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56B1D52F.70907@baylibre.com \
--to=narmstrong@baylibre.com \
--cc=drivshin.allworx@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-omap@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=manabian@gmail.com \
--cc=marathon96@gmail.com \
--cc=neilb@suse.de \
--cc=thierry.reding@gmail.com \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.