Skip to contentSkip to conversation

pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

PATCH New Sylvain Lemieux 3 participants 9 messages Jun 3, 2016 – Jun 22, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

Prior to commit 08ee77b5a5de27ad63c92262ebcb4efe0da93b58, the PWM_PIN_LEVEL bit was always clear when the PWM was disable and a 0 logic level was apply to the output.

According to the LPC32x0 User Manual [1], the default value for bit 30 (PWM_PIN_LEVEL) is 0.

This change initialize the pin level to 0 (default value) and update the register value accordingly during the disable process.

[1] http://www.nxp.com/documents/user_manual/UM10326.pdf

---
 drivers/pwm/pwm-lpc32xx.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/pwm/pwm-lpc32xx.c +11 -1
index 4d470c1..dbf93a1 100644
@@ -22,9 +22,11 @@ struct lpc32xx_pwm_chip {
 	struct pwm_chip chip;
 	struct clk *clk;
 	void __iomem *base;
+	unsigned int pin_state;
 };
 
 #define PWM_ENABLE	BIT(31)
+#define PWM_PIN_LEVEL	BIT(30)
 
 #define to_lpc32xx_pwm_chip(_chip) \
 	container_of(_chip, struct lpc32xx_pwm_chip, chip)
@@ -85,7 +87,14 @@ static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	u32 val;
 
 	val = readl(lpc32xx->base + (pwm->hwpwm << 2));
-	val &= ~PWM_ENABLE;
+	val &= ~(PWM_ENABLE | PWM_PIN_LEVEL);
+
+	/*
+	 * When the PWM is disable, we have to ensure the output is configured
+	 * correctly:
+	 */
+	if(lpc32xx->pin_state)
+		val |= PWM_PIN_LEVEL;
 	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
 
 	clk_disable_unprepare(lpc32xx->clk);
@@ -121,6 +130,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
 	lpc32xx->chip.ops = &lpc32xx_pwm_ops;
 	lpc32xx->chip.npwm = 1;
 	lpc32xx->chip.base = -1;
+	lpc32xx->pin_state = 0;
 
 	ret = pwmchip_add(&lpc32xx->chip);
 	if (ret < 0) {
Signature · 1 line
1.8.3.1
#1 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Hi Sylvain,

Quoted 12 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

Prior to commit 08ee77b5a5de27ad63c92262ebcb4efe0da93b58, the PWM_PIN_LEVEL bit was always clear when the PWM was disable and a 0 logic level was apply to the output.

According to the LPC32x0 User Manual [1], the default value for bit 30 (PWM_PIN_LEVEL) is 0.

Quoted 6 lines

This change initialize the pin level to 0 (default value) and update the register value accordingly during the disable process.

[1] http://www.nxp.com/documents/user_manual/UM10326.pdf

It looks like a pin control setting, but because it depends on PWM enabled/disabled status, I suppose it is good enough to manage it from the PWM driver.

I think here a new optional DTS property should be introduced, which if present indicates that PWM_OUT pin value is high when PWM is disabled. And if the property is not found then PWMx_PIN_LEVEL is set to 0 on driver probe.

By convention the property name should be prefixed by "nxp,", what name is good? May be "nxp,pwm-disabled-level-high" ? Or add a property "nxp,pwm-disabled-level" with valid values 0/1?

Also note someone may want to switch the default behaviour in runtime, but this feature may be added later on.

Quoted 38 lines
---
 drivers/pwm/pwm-lpc32xx.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/pwm/pwm-lpc32xx.c +10 -1
index 4d470c1..dbf93a1 100644
@@ -22,9 +22,11 @@ struct lpc32xx_pwm_chip {
 	struct pwm_chip chip;
 	struct clk *clk;
 	void __iomem *base;
+	unsigned int pin_state;
 };
 
 #define PWM_ENABLE	BIT(31)
+#define PWM_PIN_LEVEL	BIT(30)
 
 #define to_lpc32xx_pwm_chip(_chip) \
 	container_of(_chip, struct lpc32xx_pwm_chip, chip)
@@ -85,7 +87,14 @@ static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	u32 val;
 
 	val = readl(lpc32xx->base + (pwm->hwpwm << 2));
-	val &= ~PWM_ENABLE;
+	val &= ~(PWM_ENABLE | PWM_PIN_LEVEL);
+
+	/*
+	 * When the PWM is disable, we have to ensure the output is configured
+	 * correctly:
+	 */
+	if(lpc32xx->pin_state)
+		val |= PWM_PIN_LEVEL;
 	writel(val, lpc32xx->base + (pwm->hwpwm << 2));
 
 	clk_disable_unprepare(lpc32xx->clk);

drivers/pwm/pwm-lpc32xx.c static int lpc32xx_pwm_probe(struct platform_device *pdev) · line 136

Quoted 7 lines
drivers/pwm/pwm-lpc32xx.c +1 -0
@@ -121,6 +130,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
 	lpc32xx->chip.ops = &lpc32xx_pwm_ops;
 	lpc32xx->chip.npwm = 1;
 	lpc32xx->chip.base = -1;
+	lpc32xx->pin_state = 0;
 
 	ret = pwmchip_add(&lpc32xx->chip);
 	if (ret < 0) {

--
With best wishes,
Vladimir

#2 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Hi Vladimir,

Quoted 22 lines · Vladimir Zapolskiy

Hi Sylvain,

Quoted 12 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

Prior to commit 08ee77b5a5de27ad63c92262ebcb4efe0da93b58, the PWM_PIN_LEVEL bit was always clear when the PWM was disable and a 0 logic level was apply to the output.

According to the LPC32x0 User Manual [1], the default value for bit 30 (PWM_PIN_LEVEL) is 0.

Quoted 6 lines

This change initialize the pin level to 0 (default value) and update the register value accordingly during the disable process.

[1] http://www.nxp.com/documents/user_manual/UM10326.pdf

Quoted 9 lines

It looks like a pin control setting, but because it depends on PWM enabled/disabled status, I suppose it is good enough to manage it from the PWM driver.

I think here a new optional DTS property should be introduced, which if present indicates that PWM_OUT pin value is high when PWM is disabled. And if the property is not found then PWMx_PIN_LEVEL is set to 0 on driver probe.

I will add this option and submit a new revision of the patch.

Quoted 4 lines

By convention the property name should be prefixed by "nxp,", what name is good? May be "nxp,pwm-disabled-level-high" ? Or add a property "nxp,pwm-disabled-level" with valid values 0/1?

I prefer to use "nxp,pwm-disabled-level-high".

Quoted 3 lines

Also note someone may want to switch the default behaviour in runtime, but this feature may be added later on.

I agree with you, this can be done later.

Sylvain

#3 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Hi Sylvain,

Quoted 34 lines · Sylvain Lemieux

Hi Vladimir,

Quoted 22 lines · Vladimir Zapolskiy

Hi Sylvain,

Quoted 12 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

Prior to commit 08ee77b5a5de27ad63c92262ebcb4efe0da93b58, the PWM_PIN_LEVEL bit was always clear when the PWM was disable and a 0 logic level was apply to the output.

According to the LPC32x0 User Manual [1], the default value for bit 30 (PWM_PIN_LEVEL) is 0.

Quoted 6 lines

This change initialize the pin level to 0 (default value) and update the register value accordingly during the disable process.

[1] http://www.nxp.com/documents/user_manual/UM10326.pdf

Quoted 9 lines

It looks like a pin control setting, but because it depends on PWM enabled/disabled status, I suppose it is good enough to manage it from the PWM driver.

I think here a new optional DTS property should be introduced, which if present indicates that PWM_OUT pin value is high when PWM is disabled. And if the property is not found then PWMx_PIN_LEVEL is set to 0 on driver probe.

Quoted 8 lines

I will add this option and submit a new revision of the patch.

Quoted 4 lines

By convention the property name should be prefixed by "nxp,", what name is good? May be "nxp,pwm-disabled-level-high" ? Or add a property "nxp,pwm-disabled-level" with valid values 0/1?

I prefer to use "nxp,pwm-disabled-level-high".

nice, for v2 please add documentation devicetree bindings bits and add devicetree mailing list to Cc, hopefully Rob will find time to review the name.

Have you tried to set PWMx_PIN_LEVEL only once on probe()? I think there is no need to set/unset it every time when PWM is enabled or disabled. If it works, then the newly introduced local state storage can be removed.

Quoted 4 lines
Quoted 3 lines

Also note someone may want to switch the default behaviour in runtime, but this feature may be added later on.

I agree with you, this can be done later.

--
With best wishes,
Vladimir

#4 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

In reply to Sylvain Lemieux
Quoted 4 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

I presume there's a reason why the bootloader set this bit to 1. Why do you assume it's the right thing to clear it?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160622/6ba5f7b9/attachment.sig>

#5 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Hi Thierry,

Quoted 9 lines · Thierry Reding
Quoted 4 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

I presume there's a reason why the bootloader set this bit to 1. Why do you assume it's the right thing to clear it?

There is an alternative mode for the PWM output pin; using the PWM_PIN_LEVEL bit to control the PWM output (logical 0 or 1 on output) when the PWM is disable.

In this case, the bootloader is using the PWM_PIN_LEVEL bit to control the PWM output (always 1) to enable the LCD; the application is using the PWM to control the intensity of the LCD output. When disabling the PWM, the line level should be setup to 0.

A version 2 of this patch will be send with support to select the alternate PWM disable level high from the device tree.

For details, you can refer to:
http://thread.gmane.org/gmane.linux.pwm/3882/focus=508758

Sylvain

Quoted 1 line

Thierry

#6 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Quoted 16 lines · Sylvain Lemieux

Hi Thierry,

Quoted 9 lines · Thierry Reding
Quoted 4 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

I presume there's a reason why the bootloader set this bit to 1. Why do you assume it's the right thing to clear it?

There is an alternative mode for the PWM output pin; using the PWM_PIN_LEVEL bit to control the PWM output (logical 0 or 1 on output) when the PWM is disable.

Quoted 5 lines

In this case, the bootloader is using the PWM_PIN_LEVEL bit to control the PWM output (always 1) to enable the LCD; the application is using the PWM to control the intensity of the LCD output. When disabling the PWM, the line level should be setup to 0.

But doesn't that mean that if the pin is used in PWM mode there's never a use-case for having it go high when disabled? Given that this is a PWM driver I don't see how we'd ever be in the case where the alternate setting makes sense.

Quoted 5 lines

A version 2 of this patch will be send with support to select the alternate PWM disable level high from the device tree.

For details, you can refer to:
http://thread.gmane.org/gmane.linux.pwm/3882/focus=508758

Given the above I don't think we should add this new device tree property until we encounter a setup where it's needed.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160622/de943625/attachment.sig>

#7 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Hi Thierry,

Quoted 23 lines · Thierry Reding
Quoted 16 lines · Sylvain Lemieux

Hi Thierry,

Quoted 9 lines · Thierry Reding
Quoted 4 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

I presume there's a reason why the bootloader set this bit to 1. Why do you assume it's the right thing to clear it?

There is an alternative mode for the PWM output pin; using the PWM_PIN_LEVEL bit to control the PWM output (logical 0 or 1 on output) when the PWM is disable.

Quoted 5 lines

In this case, the bootloader is using the PWM_PIN_LEVEL bit to control the PWM output (always 1) to enable the LCD; the application is using the PWM to control the intensity of the LCD output. When disabling the PWM, the line level should be setup to 0.

Quoted 5 lines

But doesn't that mean that if the pin is used in PWM mode there's never a use-case for having it go high when disabled? Given that this is a PWM driver I don't see how we'd ever be in the case where the alternate setting makes sense.

to some extend when PWM is disabled, both options of pin output high and low level values are valid if we consider variable PWM polarity setting in general, however this particular controller does not have this control and thus there is no need to extend it to 2-cell type.

Another alternative to avoid a new property may be to extend period_ns to its apparently valid boundaries - 0 and duty_ns, both options are not supported properly in the driver at the moment. But then the question what to do with it on boot is still open, just leaving it untouched is nondeterministic in my opinion.

Quoted 9 lines
Quoted 5 lines

A version 2 of this patch will be send with support to select the alternate PWM disable level high from the device tree.

For details, you can refer to:
http://thread.gmane.org/gmane.linux.pwm/3882/focus=508758

Given the above I don't think we should add this new device tree property until we encounter a setup where it's needed.

--
With best wishes,
Vladimir

#8 lore raw

PATCH 1/1 pwm: lpc32xx: Set PWM_PIN_LEVEL bit in lpc32xx_pwm_disable

Hi Thierry,

Quoted 37 lines · Vladimir Zapolskiy

Hi Thierry,

Quoted 23 lines · Thierry Reding
Quoted 16 lines · Sylvain Lemieux

Hi Thierry,

Quoted 9 lines · Thierry Reding
Quoted 4 lines · Sylvain Lemieux

From: Sylvain Lemieux <[email protected]>

If the PWM_PIN_LEVEL bit is setup to 1 in the bootloader, when the kernel disable the PWM, the PWM output is always set as a logic 1.

I presume there's a reason why the bootloader set this bit to 1. Why do you assume it's the right thing to clear it?

There is an alternative mode for the PWM output pin; using the PWM_PIN_LEVEL bit to control the PWM output (logical 0 or 1 on output) when the PWM is disable.

Quoted 5 lines

In this case, the bootloader is using the PWM_PIN_LEVEL bit to control the PWM output (always 1) to enable the LCD; the application is using the PWM to control the intensity of the LCD output. When disabling the PWM, the line level should be setup to 0.

Quoted 5 lines

But doesn't that mean that if the pin is used in PWM mode there's never a use-case for having it go high when disabled? Given that this is a PWM driver I don't see how we'd ever be in the case where the alternate setting makes sense.

to some extend when PWM is disabled, both options of pin output high and low level values are valid if we consider variable PWM polarity setting in general, however this particular controller does not have this control and thus there is no need to extend it to 2-cell type.

Quoted 15 lines

Another alternative to avoid a new property may be to extend period_ns to its apparently valid boundaries - 0 and duty_ns, both options are not supported properly in the driver at the moment. But then the question what to do with it on boot is still open, just leaving it untouched is nondeterministic in my opinion.

Quoted 9 lines
Quoted 5 lines

A version 2 of this patch will be send with support to select the alternate PWM disable level high from the device tree.

For details, you can refer to:
http://thread.gmane.org/gmane.linux.pwm/3882/focus=508758

Given the above I don't think we should add this new device tree property until we encounter a setup where it's needed.

I am currently having this problem as our bootloader is using the pin output control when the PWM is disabled to setup the PWM output (0 or 1) and the application is using the PWM to control the output. In this case the application need to be sure the value of the PWM_PIN_LEVEL bit is configured properly.

Prior to commit 08ee77b5a5de27ad63c92262ebcb4efe0da93b58, the PWM_PIN_LEVEL bit was always clear when the PWM was disable and a 0 logic level was apply to the output.

I am ready to submit a version 2 with this new device tree property; should I go ahead with the submit?

Regards,
Sylvain

Quoted 4 lines

--
With best wishes,
Vladimir