From: "Uwe Kleine-König" <ukleinek@kernel.org>
To: keguang.zhang@gmail.com
Cc: Binbin Zhou <zhoubinbin@loongson.cn>,
linux-pwm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] pwm: loongson: Fix low pulse buffer register handling
Date: Wed, 17 Jun 2026 18:03:59 +0200 [thread overview]
Message-ID: <ajLDoiFEO_8Y5_1S@monoceros> (raw)
In-Reply-To: <20260616-pwm-loongson-fix-v1-1-491dbf260a7f@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3351 bytes --]
On Tue, Jun 16, 2026 at 07:13:17PM +0800, Keguang Zhang via B4 Relay wrote:
> From: Keguang Zhang <keguang.zhang@gmail.com>
>
> The Loongson PWM register at offset 0x4 is documented as the Low
> Pulse Buffer Register, which stores the low pulse width rather than
> the duty cycle.
>
> However, this register was incorrectly defined and treated as a
> duty-cycle register. As a result, the duty cycle and low pulse cycle
> are swapped in the generated PWM waveform.
>
> Program the low pulse (period - duty) into the register and
> adjust pwm_loongson_get_state() accordingly when reconstructing the
> duty cycle.
>
> Also return -ERANGE when the requested period exceeds the hardware
> 32-bit limit instead of silently truncating the value.
This is the intended behaviour.
> Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com>
> ---
> drivers/pwm/pwm-loongson.c | 29 ++++++++++++++---------------
> 1 file changed, 14 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c
> index 31a57edecfd0..dc77f82fd888 100644
> --- a/drivers/pwm/pwm-loongson.c
> +++ b/drivers/pwm/pwm-loongson.c
> @@ -22,6 +22,7 @@
> */
>
> #include <linux/acpi.h>
> +#include <linux/bitfield.h>
> #include <linux/clk.h>
> #include <linux/device.h>
> #include <linux/init.h>
> @@ -33,10 +34,12 @@
> #include <linux/units.h>
>
> /* Loongson PWM registers */
> -#define LOONGSON_PWM_REG_DUTY 0x4 /* Low Pulse Buffer Register */
> +#define LOONGSON_PWM_REG_LOW 0x4 /* Low Pulse Buffer Register */
> #define LOONGSON_PWM_REG_PERIOD 0x8 /* Pulse Period Buffer Register */
> #define LOONGSON_PWM_REG_CTRL 0xc /* Control Register */
>
> +#define LOONGSON_PWM_MAX_PERIOD GENMASK(31, 0)
> +
> /* Control register bits */
> #define LOONGSON_PWM_CTRL_REG_EN BIT(0) /* Counter Enable Bit */
> #define LOONGSON_PWM_CTRL_REG_OE BIT(3) /* Pulse Output Enable Control Bit, Valid Low */
> @@ -118,20 +121,16 @@ static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> static int pwm_loongson_config(struct pwm_chip *chip, struct pwm_device *pwm,
> u64 duty_ns, u64 period_ns)
> {
> - u64 duty, period;
> + u64 low, period;
> struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
>
> - /* duty = duty_ns * ddata->clk_rate / NSEC_PER_SEC */
> - duty = mul_u64_u64_div_u64(duty_ns, ddata->clk_rate, NSEC_PER_SEC);
> - if (duty > U32_MAX)
> - duty = U32_MAX;
> -
> - /* period = period_ns * ddata->clk_rate / NSEC_PER_SEC */
> period = mul_u64_u64_div_u64(period_ns, ddata->clk_rate, NSEC_PER_SEC);
> - if (period > U32_MAX)
> - period = U32_MAX;
> + if ((!FIELD_FIT(LOONGSON_PWM_MAX_PERIOD, period)))
> + return -ERANGE;
As noted above, this is wrong. If period is too big, you're supposed to
pick the biggest possible period and not return an error.
> +
> + low = mul_u64_u64_div_u64(period_ns - duty_ns, ddata->clk_rate, NSEC_PER_SEC);
this is also wrong. You're supposed to pick a configuration where the
duty is the biggest not bigger than the requested value. However as
mul_u64_u64_div_u64 rounds down, you're rounding in the wrong direction.
The register layout suggests that the period starts with the inactive
part, did you reverify that?
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2026-06-17 16:04 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 11:13 [PATCH 0/2] pwm: loongson: Fix PWM configuration handling Keguang Zhang via B4 Relay
2026-06-16 11:13 ` Keguang Zhang
2026-06-16 11:13 ` [PATCH 1/2] pwm: loongson: Fix low pulse buffer register handling Keguang Zhang via B4 Relay
2026-06-16 11:13 ` Keguang Zhang
2026-06-17 16:03 ` Uwe Kleine-König [this message]
2026-06-16 11:13 ` [PATCH 2/2] pwm: loongson: Reload PWM configuration through counter reset Keguang Zhang via B4 Relay
2026-06-16 11:13 ` Keguang Zhang
2026-06-17 16:11 ` Uwe Kleine-König
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=ajLDoiFEO_8Y5_1S@monoceros \
--to=ukleinek@kernel.org \
--cc=keguang.zhang@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=zhoubinbin@loongson.cn \
/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.