* [PATCH v3 0/2] pwm: loongson: Fix PWM configuration handling
@ 2026-07-15 11:05 Keguang Zhang via B4 Relay
2026-07-15 11:05 ` [PATCH v3 1/2] pwm: loongson: Fix low pulse buffer register handling Keguang Zhang via B4 Relay
2026-07-15 11:05 ` [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset Keguang Zhang via B4 Relay
0 siblings, 2 replies; 7+ messages in thread
From: Keguang Zhang via B4 Relay @ 2026-07-15 11:05 UTC (permalink / raw)
To: Binbin Zhou, Uwe Kleine-König; +Cc: linux-pwm, linux-kernel, Keguang Zhang
This series fixes two issues in the Loongson PWM driver:
- Fix the handling of the Low Pulse Buffer Register, which was
incorrectly treated as a duty-cycle register.
- Reset the PWM counter when disabling the PWM and release it when
enabling the PWM so that updated LOW and PERIOD values are latched
before the PWM starts running again.
The fixes were verified on LS1B, LS1C, and LS2K0300 boards.
Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com>
---
Changes in v3:
- Calculate the low pulse as period - duty after rounding the duty cycle.
- Handle LOW > PERIOD in pwm_loongson_get_state().
- Add a Fixes tag to the second patch.
- Link to v2: https://lore.kernel.org/r/20260626-pwm-loongson-fix-v2-0-5492db953879@gmail.com
Changes in v2:
- Drop the -ERANGE return change and restore the original behavior.
- Use mul_u64_u64_div_u64_roundup() to calculate the low pulse width.
- Update the commit message accordingly.
- Link to v1: https://lore.kernel.org/r/20260616-pwm-loongson-fix-v1-0-491dbf260a7f@gmail.com
---
Keguang Zhang (2):
pwm: loongson: Fix low pulse buffer register handling
pwm: loongson: Reload PWM configuration through counter reset
drivers/pwm/pwm-loongson.c | 40 ++++++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 14 deletions(-)
---
base-commit: cc2b5f627e8ccbae1188ef2d8be3e451d7f933a5
change-id: 20260612-pwm-loongson-fix-183763451e93
Best regards,
--
Keguang Zhang <keguang.zhang@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v3 1/2] pwm: loongson: Fix low pulse buffer register handling 2026-07-15 11:05 [PATCH v3 0/2] pwm: loongson: Fix PWM configuration handling Keguang Zhang via B4 Relay @ 2026-07-15 11:05 ` Keguang Zhang via B4 Relay 2026-09-07 9:18 ` Uwe Kleine-König 2026-07-15 11:05 ` [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset Keguang Zhang via B4 Relay 1 sibling, 1 reply; 7+ messages in thread From: Keguang Zhang via B4 Relay @ 2026-07-15 11:05 UTC (permalink / raw) To: Binbin Zhou, Uwe Kleine-König; +Cc: linux-pwm, linux-kernel, Keguang Zhang 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. Fixes: 2b62c89448dd ("pwm: Add Loongson PWM controller support") Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com> --- drivers/pwm/pwm-loongson.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c index f2fb35b7af2b..e703217a6d5e 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,13 @@ #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_LOW GENMASK(31, 0) +#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 +122,21 @@ 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, duty, 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))) + period = LOONGSON_PWM_MAX_PERIOD; - pwm_loongson_writel(ddata, duty, LOONGSON_PWM_REG_DUTY); + /* duty = duty_ns * ddata->clk_rate / NSEC_PER_SEC */ + duty = mul_u64_u64_div_u64_roundup(duty_ns, ddata->clk_rate, NSEC_PER_SEC); + low = period - duty; + if ((!FIELD_FIT(LOONGSON_PWM_MAX_LOW, low))) + low = LOONGSON_PWM_MAX_LOW; + + pwm_loongson_writel(ddata, low, LOONGSON_PWM_REG_LOW); pwm_loongson_writel(ddata, period, LOONGSON_PWM_REG_PERIOD); return 0; @@ -166,15 +171,20 @@ static int pwm_loongson_apply(struct pwm_chip *chip, struct pwm_device *pwm, static int pwm_loongson_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { - u32 duty, period, ctrl; + u32 low, period, ctrl; struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); - duty = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_DUTY); + low = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_LOW); period = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_PERIOD); ctrl = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); - /* duty & period have a max of 2^32, so we can't overflow */ - state->duty_cycle = DIV64_U64_ROUND_UP((u64)duty * NSEC_PER_SEC, ddata->clk_rate); + /* low & period have a max of 2^32, so we can't overflow */ + if (low > period) + state->duty_cycle = 0; + else + state->duty_cycle = + DIV64_U64_ROUND_UP((u64)(period - low) * NSEC_PER_SEC, ddata->clk_rate); + state->period = DIV64_U64_ROUND_UP((u64)period * NSEC_PER_SEC, ddata->clk_rate); state->polarity = (ctrl & LOONGSON_PWM_CTRL_REG_INVERT) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/2] pwm: loongson: Fix low pulse buffer register handling 2026-07-15 11:05 ` [PATCH v3 1/2] pwm: loongson: Fix low pulse buffer register handling Keguang Zhang via B4 Relay @ 2026-09-07 9:18 ` Uwe Kleine-König 0 siblings, 0 replies; 7+ messages in thread From: Uwe Kleine-König @ 2026-09-07 9:18 UTC (permalink / raw) To: keguang.zhang; +Cc: Binbin Zhou, linux-pwm, linux-kernel [-- Attachment #1: Type: text/plain, Size: 5111 bytes --] Hello Keguang, On Wed, Jul 15, 2026 at 07:05:23PM +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. > > Fixes: 2b62c89448dd ("pwm: Add Loongson PWM controller support") > Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com> > --- > drivers/pwm/pwm-loongson.c | 38 ++++++++++++++++++++++++-------------- > 1 file changed, 24 insertions(+), 14 deletions(-) > > diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c > index f2fb35b7af2b..e703217a6d5e 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,13 @@ > #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_LOW GENMASK(31, 0) > +#define LOONGSON_PWM_MAX_PERIOD GENMASK(31, 0) Can you please make this a minimal fix and do the rework in a separate patch? This way it a backport to stable is easier to motivate. > + > /* 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 +122,21 @@ 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, duty, 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))) > + period = LOONGSON_PWM_MAX_PERIOD; > > - pwm_loongson_writel(ddata, duty, LOONGSON_PWM_REG_DUTY); > + /* duty = duty_ns * ddata->clk_rate / NSEC_PER_SEC */ > + duty = mul_u64_u64_div_u64_roundup(duty_ns, ddata->clk_rate, NSEC_PER_SEC); > + low = period - duty; This might overflow. I think in that case the right thing happens (at least I failed to find an example that results in bogous settings), but that might be worth to be handled (either by a comment explaining it or explicitly limiting duty to be <= period first). > + if ((!FIELD_FIT(LOONGSON_PWM_MAX_LOW, low))) > + low = LOONGSON_PWM_MAX_LOW; > + > + pwm_loongson_writel(ddata, low, LOONGSON_PWM_REG_LOW); > pwm_loongson_writel(ddata, period, LOONGSON_PWM_REG_PERIOD); > > return 0; > @@ -166,15 +171,20 @@ static int pwm_loongson_apply(struct pwm_chip *chip, struct pwm_device *pwm, > static int pwm_loongson_get_state(struct pwm_chip *chip, struct pwm_device *pwm, > struct pwm_state *state) > { > - u32 duty, period, ctrl; > + u32 low, period, ctrl; > struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); > > - duty = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_DUTY); > + low = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_LOW); > period = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_PERIOD); > ctrl = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > > - /* duty & period have a max of 2^32, so we can't overflow */ > - state->duty_cycle = DIV64_U64_ROUND_UP((u64)duty * NSEC_PER_SEC, ddata->clk_rate); > + /* low & period have a max of 2^32, so we can't overflow */ 2^32-1 is the maximal value, right? (This was already wrong before.) > + if (low > period) > + state->duty_cycle = 0; > + else > + state->duty_cycle = > + DIV64_U64_ROUND_UP((u64)(period - low) * NSEC_PER_SEC, ddata->clk_rate); > + > state->period = DIV64_U64_ROUND_UP((u64)period * NSEC_PER_SEC, ddata->clk_rate); > state->polarity = (ctrl & LOONGSON_PWM_CTRL_REG_INVERT) ? PWM_POLARITY_INVERSED : > PWM_POLARITY_NORMAL; You could do s/>/>=/ as a micro optimisation, but I don't care much. Otherwise the adaption to pwm_loongson_get_state() looks fine. Best regards Uwe [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset 2026-07-15 11:05 [PATCH v3 0/2] pwm: loongson: Fix PWM configuration handling Keguang Zhang via B4 Relay 2026-07-15 11:05 ` [PATCH v3 1/2] pwm: loongson: Fix low pulse buffer register handling Keguang Zhang via B4 Relay @ 2026-07-15 11:05 ` Keguang Zhang via B4 Relay 2026-09-07 9:33 ` Uwe Kleine-König 1 sibling, 1 reply; 7+ messages in thread From: Keguang Zhang via B4 Relay @ 2026-07-15 11:05 UTC (permalink / raw) To: Binbin Zhou, Uwe Kleine-König; +Cc: linux-pwm, linux-kernel, Keguang Zhang From: Keguang Zhang <keguang.zhang@gmail.com> The Loongson PWM controller latches the LOW and PERIOD registers only at the start of each PWM period. After disabling and re-enabling the PWM, the controller resumes from the previous counter value and completes the current period before re-latching the updated LOW and PERIOD values. Reset the PWM counter when disabling the PWM and release it when enabling the PWM so that the updated LOW and PERIOD values are latched before the PWM starts running again. Fixes: 2b62c89448dd ("pwm: Add Loongson PWM controller support") Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com> --- drivers/pwm/pwm-loongson.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c index e703217a6d5e..c317d62fe813 100644 --- a/drivers/pwm/pwm-loongson.c +++ b/drivers/pwm/pwm-loongson.c @@ -103,6 +103,7 @@ static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm) struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + val |= LOONGSON_PWM_CTRL_REG_RST; val &= ~LOONGSON_PWM_CTRL_REG_EN; pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); } @@ -113,6 +114,7 @@ static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + val &= ~LOONGSON_PWM_CTRL_REG_RST; val |= LOONGSON_PWM_CTRL_REG_EN; pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset 2026-07-15 11:05 ` [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset Keguang Zhang via B4 Relay @ 2026-09-07 9:33 ` Uwe Kleine-König 2026-09-10 11:58 ` Keguang Zhang 0 siblings, 1 reply; 7+ messages in thread From: Uwe Kleine-König @ 2026-09-07 9:33 UTC (permalink / raw) To: keguang.zhang; +Cc: Binbin Zhou, linux-pwm, linux-kernel [-- Attachment #1: Type: text/plain, Size: 2616 bytes --] On Wed, Jul 15, 2026 at 07:05:24PM +0800, Keguang Zhang via B4 Relay wrote: > From: Keguang Zhang <keguang.zhang@gmail.com> > > The Loongson PWM controller latches the LOW and PERIOD registers only at > the start of each PWM period. After disabling and re-enabling the PWM, > the controller resumes from the previous counter value and completes the > current period before re-latching the updated LOW and PERIOD values. > > Reset the PWM counter when disabling the PWM and release it when > enabling the PWM so that the updated LOW and PERIOD values are latched > before the PWM starts running again. > > Fixes: 2b62c89448dd ("pwm: Add Loongson PWM controller support") > Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com> > --- > drivers/pwm/pwm-loongson.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c > index e703217a6d5e..c317d62fe813 100644 > --- a/drivers/pwm/pwm-loongson.c > +++ b/drivers/pwm/pwm-loongson.c > @@ -103,6 +103,7 @@ static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm) > struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); > > val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > + val |= LOONGSON_PWM_CTRL_REG_RST; > val &= ~LOONGSON_PWM_CTRL_REG_EN; > pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); > } > @@ -113,6 +114,7 @@ static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm) > struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); > > val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > + val &= ~LOONGSON_PWM_CTRL_REG_RST; > val |= LOONGSON_PWM_CTRL_REG_EN; > pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); I applied this patch to https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next , but I wonder if the fix is incomplete. If at driver bind time LOONGSON_PWM_CTRL_REG_RST isn't set and there are still wrong values in the shadowed LOW and PERIOD registers the first period will be wrong. This would need: val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + + /* + * Ensure that the values of LOW and PERIOD are sampled into + * the shadow register when the hardware starts running. + */ + if (!(val & LOONGSON_PWM_CTRL_REG_RST)) + pwm_loongson_writel(ddata, val | LOONGSON_PWM_CTRL_REG_RST, LOONGSON_PWM_REG_CTRL); + val &= ~LOONGSON_PWM_CTRL_REG_RST; val |= LOONGSON_PWM_CTRL_REG_EN; pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); I think. Best regards Uwe [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset 2026-09-07 9:33 ` Uwe Kleine-König @ 2026-09-10 11:58 ` Keguang Zhang 2026-09-10 13:54 ` Uwe Kleine-König 0 siblings, 1 reply; 7+ messages in thread From: Keguang Zhang @ 2026-09-10 11:58 UTC (permalink / raw) To: Uwe Kleine-König; +Cc: Binbin Zhou, linux-pwm, linux-kernel On Mon, Sep 7, 2026 at 5:33 PM Uwe Kleine-König <ukleinek@kernel.org> wrote: > > On Wed, Jul 15, 2026 at 07:05:24PM +0800, Keguang Zhang via B4 Relay wrote: > > From: Keguang Zhang <keguang.zhang@gmail.com> > > > > The Loongson PWM controller latches the LOW and PERIOD registers only at > > the start of each PWM period. After disabling and re-enabling the PWM, > > the controller resumes from the previous counter value and completes the > > current period before re-latching the updated LOW and PERIOD values. > > > > Reset the PWM counter when disabling the PWM and release it when > > enabling the PWM so that the updated LOW and PERIOD values are latched > > before the PWM starts running again. > > > > Fixes: 2b62c89448dd ("pwm: Add Loongson PWM controller support") > > Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com> > > --- > > drivers/pwm/pwm-loongson.c | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c > > index e703217a6d5e..c317d62fe813 100644 > > --- a/drivers/pwm/pwm-loongson.c > > +++ b/drivers/pwm/pwm-loongson.c > > @@ -103,6 +103,7 @@ static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm) > > struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); > > > > val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > > + val |= LOONGSON_PWM_CTRL_REG_RST; > > val &= ~LOONGSON_PWM_CTRL_REG_EN; > > pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); > > } > > @@ -113,6 +114,7 @@ static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm) > > struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); > > > > val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > > + val &= ~LOONGSON_PWM_CTRL_REG_RST; > > val |= LOONGSON_PWM_CTRL_REG_EN; > > pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); > > I applied this patch to > > https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next > > , but I wonder if the fix is incomplete. If at driver bind time > LOONGSON_PWM_CTRL_REG_RST isn't set and there are still wrong values in > the shadowed LOW and PERIOD registers the first period will be wrong. > > This would need: > > val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > + > + /* > + * Ensure that the values of LOW and PERIOD are sampled into > + * the shadow register when the hardware starts running. > + */ > + if (!(val & LOONGSON_PWM_CTRL_REG_RST)) > + pwm_loongson_writel(ddata, val | LOONGSON_PWM_CTRL_REG_RST, LOONGSON_PWM_REG_CTRL); > + > val &= ~LOONGSON_PWM_CTRL_REG_RST; > val |= LOONGSON_PWM_CTRL_REG_EN; > pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); > > I think. You are right that this patch doesn't handle the initial hardware state when the driver binds. Would you prefer that I submit a follow-up patch to address this, or are you planning to fix it yourself? Thanks! > > Best regards > Uwe -- Best regards, Keguang Zhang ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset 2026-09-10 11:58 ` Keguang Zhang @ 2026-09-10 13:54 ` Uwe Kleine-König 0 siblings, 0 replies; 7+ messages in thread From: Uwe Kleine-König @ 2026-09-10 13:54 UTC (permalink / raw) To: Keguang Zhang; +Cc: Binbin Zhou, linux-pwm, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1335 bytes --] Hello, On Thu, Sep 10, 2026 at 07:58:12PM +0800, Keguang Zhang wrote: > On Mon, Sep 7, 2026 at 5:33 PM Uwe Kleine-König <ukleinek@kernel.org> wrote: > > [...] I wonder if the fix is incomplete. If at driver bind time > > LOONGSON_PWM_CTRL_REG_RST isn't set and there are still wrong values in > > the shadowed LOW and PERIOD registers the first period will be wrong. > > > > This would need: > > > > val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); > > + > > + /* > > + * Ensure that the values of LOW and PERIOD are sampled into > > + * the shadow register when the hardware starts running. > > + */ > > + if (!(val & LOONGSON_PWM_CTRL_REG_RST)) > > + pwm_loongson_writel(ddata, val | LOONGSON_PWM_CTRL_REG_RST, LOONGSON_PWM_REG_CTRL); > > + > > val &= ~LOONGSON_PWM_CTRL_REG_RST; > > val |= LOONGSON_PWM_CTRL_REG_EN; > > pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); > > > > I think. > > You are right that this patch doesn't handle the initial hardware > state when the driver binds. > Would you prefer that I submit a follow-up patch to address this, or > are you planning to fix it yourself? I don't have the hardware, so if you do that and test it, that's very appreciated. Best regards Uwe [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-10 13:54 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-07-15 11:05 [PATCH v3 0/2] pwm: loongson: Fix PWM configuration handling Keguang Zhang via B4 Relay 2026-07-15 11:05 ` [PATCH v3 1/2] pwm: loongson: Fix low pulse buffer register handling Keguang Zhang via B4 Relay 2026-09-07 9:18 ` Uwe Kleine-König 2026-07-15 11:05 ` [PATCH v3 2/2] pwm: loongson: Reload PWM configuration through counter reset Keguang Zhang via B4 Relay 2026-09-07 9:33 ` Uwe Kleine-König 2026-09-10 11:58 ` Keguang Zhang 2026-09-10 13:54 ` Uwe Kleine-König
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®