This patchset contains fixes for Broadcom's Kona PWM driver.
These changes fix glitch issues when changing settings on different channels.
Kconfig change made to allow the driver to work on any Broadcom SoC rather
than just mobile devices.
Arun Ramamurthy (4):
pwm: kona: Remove setting default smooth type and polarity for all
channels
pwm: kona: Fix incorrect enable after channel polarity change
pwm: kona: Fix enable, disable and config procedures
pwm: kona: Update dependency to ARCH_BCM
drivers/pwm/Kconfig | 2 +-
drivers/pwm/pwm-bcm-kona.c | 112 ++++++++++++++++++++++++++++++++-------------
2 files changed, 81 insertions(+), 33 deletions(-)
--
2.1.3
From: Arun Ramamurthy <[email protected]>
The probe routine unnecessarily sets the smooth type and polarity for
all channels. This causes the channel for the speaker to click at the same
time the backlight turns on. The smooth type and polarity should be set individually
for each channel as required and no defaults need to be set.
Signed-off-by: Arun Ramamurthy <[email protected]>
Reviewed-by: Ray Jui <[email protected]>
Signed-off-by: Scott Branden <[email protected]>
---
drivers/pwm/pwm-bcm-kona.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index 02bc048..29eef9e 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -266,12 +266,9 @@ static int kona_pwmc_probe(struct platform_device *pdev)
return ret;
}
- /* Set smooth mode, push/pull, and normal polarity for all channels */
- for (chan = 0; chan < kp->chip.npwm; chan++) {
- value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+ /* Set push/pull for all channels */
+ for (chan = 0; chan < kp->chip.npwm; chan++)
value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
- value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan));
- }
writel(value, kp->base + PWM_CONTROL_OFFSET);
--
2.1.3
From: Arun Ramamurthy <[email protected]>
Signed-off-by: Arun Ramamurthy <[email protected]>
Reviewed-by: Ray Jui <[email protected]>
Signed-off-by: Scott Branden <[email protected]>
---
drivers/pwm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index ef2dd2e..186080e 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -64,7 +64,7 @@ config PWM_ATMEL_TCB
config PWM_BCM_KONA
tristate "Kona PWM support"
- depends on ARCH_BCM_MOBILE
+ depends on ARCH_BCM
help
Generic PWM framework driver for Broadcom Kona PWM block.
--
2.1.3
From: Arun Ramamurthy <[email protected]>
- Added helper functions to set and clear smooth and trigger bits
- Added 400ns delays when clearing and setting trigger bit as requied
by spec
- Added helper function to write prescale and other settings
- Updated config procedure to match spec
- Added code to handle pwn config when channel is disabled
- Updated disable procedure to match spec
Signed-off-by: Arun Ramamurthy <[email protected]>
Reviewed-by: Ray Jui <[email protected]>
Signed-off-by: Scott Branden <[email protected]>
---
drivers/pwm/pwm-bcm-kona.c | 100 +++++++++++++++++++++++++++++++++++----------
1 file changed, 78 insertions(+), 22 deletions(-)
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index fa0b5bf..06fa983 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -65,6 +65,10 @@
#define DUTY_CYCLE_HIGH_MIN (0x00000000)
#define DUTY_CYCLE_HIGH_MAX (0x00ffffff)
+/* The delay required after clearing or setting
+ PWMOUT_ENABLE*/
+#define PWMOUT_ENABLE_HOLD_DELAY 400
+
struct kona_pwmc {
struct pwm_chip chip;
void __iomem *base;
@@ -76,28 +80,70 @@ static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip)
return container_of(_chip, struct kona_pwmc, chip);
}
-static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
+static inline void kona_pwmc_set_trigger(struct kona_pwmc *kp,
+ unsigned int chan)
{
unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
- /* Clear trigger bit but set smooth bit to maintain old output */
- value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+ /* set trigger bit to enable channel */
+ value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
+ writel(value, kp->base + PWM_CONTROL_OFFSET);
+ ndelay(PWMOUT_ENABLE_HOLD_DELAY);
+}
+static inline void kona_pwmc_clear_trigger(struct kona_pwmc *kp,
+ unsigned int chan)
+{
+ unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+ /* Clear trigger bit */
value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
writel(value, kp->base + PWM_CONTROL_OFFSET);
+ ndelay(PWMOUT_ENABLE_HOLD_DELAY);
+}
- /* Set trigger bit and clear smooth bit to apply new settings */
+static inline void kona_pwmc_clear_smooth(struct kona_pwmc *kp,
+ unsigned int chan)
+{
+ unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+ /* Clear smooth bit */
value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
- value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
writel(value, kp->base + PWM_CONTROL_OFFSET);
}
+static inline void kona_pwmc_set_smooth(struct kona_pwmc *kp, unsigned int chan)
+{
+ unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+ /* set smooth bit to maintain old output */
+ value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+ writel(value, kp->base + PWM_CONTROL_OFFSET);
+}
+
+static void kona_pwmc_write_settings(struct kona_pwmc *kp, unsigned int chan,
+ unsigned long prescale, unsigned long pc,
+ unsigned long dc)
+{
+ unsigned int value;
+
+ value = readl(kp->base + PRESCALE_OFFSET);
+ value &= ~PRESCALE_MASK(chan);
+ value |= prescale << PRESCALE_SHIFT(chan);
+ writel(value, kp->base + PRESCALE_OFFSET);
+
+ writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+
+ writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+
+}
+
static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
{
struct kona_pwmc *kp = to_kona_pwmc(chip);
u64 val, div, rate;
unsigned long prescale = PRESCALE_MIN, pc, dc;
- unsigned int value, chan = pwm->hwpwm;
+ unsigned int ret, chan = pwm->hwpwm;
/*
* Find period count, duty count and prescale to suit duty_ns and
@@ -133,19 +179,30 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
return -EINVAL;
}
- /* If the PWM channel is enabled, write the settings to the HW */
- if (test_bit(PWMF_ENABLED, &pwm->flags)) {
- value = readl(kp->base + PRESCALE_OFFSET);
- value &= ~PRESCALE_MASK(chan);
- value |= prescale << PRESCALE_SHIFT(chan);
- writel(value, kp->base + PRESCALE_OFFSET);
- writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+ /* If the PWM channel is not enabled, enable the clock */
+ if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+ ret = clk_prepare_enable(kp->clk);
+ if (ret < 0) {
+ dev_err(chip->dev, "failed to enable clock: %d\n", ret);
+ return ret;
+ }
+ }
- writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+ /* Set smooth bit to maintain old output */
+ kona_pwmc_set_smooth(kp, chan);
+ kona_pwmc_clear_trigger(kp, chan);
+
+ /* apply new settings */
+ kona_pwmc_write_settings(kp, chan, prescale, pc, dc);
+
+ /*If the PWM is enabled, enable the channel with the new settings
+ and if not disable the clock*/
+ if (test_bit(PWMF_ENABLED, &pwm->flags))
+ kona_pwmc_set_trigger(kp, chan);
+ else
+ clk_disable_unprepare(kp->clk);
- kona_pwmc_apply_settings(kp, chan);
- }
return 0;
}
@@ -188,7 +245,6 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
dev_err(chip->dev, "failed to enable clock: %d\n", ret);
return ret;
}
-
ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period);
if (ret < 0) {
clk_disable_unprepare(kp->clk);
@@ -203,12 +259,12 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
struct kona_pwmc *kp = to_kona_pwmc(chip);
unsigned int chan = pwm->hwpwm;
+ kona_pwmc_clear_smooth(kp, chan);
+ kona_pwmc_clear_trigger(kp, chan);
/* Simulate a disable by configuring for zero duty */
- writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
- kona_pwmc_apply_settings(kp, chan);
-
- /* Wait for waveform to settle before gating off the clock */
- ndelay(400);
+ kona_pwmc_write_settings(kp, chan, 0, 0, 0);
+ kona_pwmc_set_polarity(chip, pwm, PWM_POLARITY_NORMAL);
+ kona_pwmc_set_trigger(kp, chan);
clk_disable_unprepare(kp->clk);
}
--
2.1.3
From: Arun Ramamurthy <[email protected]>
The pwm core code requires a separate call for enabling the channel
and hence the driver does not need to set pwm_trigger after a
polarity change
Signed-off-by: Arun Ramamurthy <[email protected]>
Reviewed-by: Ray Jui <[email protected]>
Signed-off-by: Scott Branden <[email protected]>
---
drivers/pwm/pwm-bcm-kona.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index 29eef9e..fa0b5bf 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -173,11 +173,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
writel(value, kp->base + PWM_CONTROL_OFFSET);
- kona_pwmc_apply_settings(kp, chan);
-
- /* Wait for waveform to settle before gating off the clock */
- ndelay(400);
-
clk_disable_unprepare(kp->clk);
return 0;
--
2.1.3
On Fri, Nov 14, 2014 at 10:29:56AM -0800, Scott Branden wrote:
> This patchset contains fixes for Broadcom's Kona PWM driver.
>
> These changes fix glitch issues when changing settings on different channels.
> Kconfig change made to allow the driver to work on any Broadcom SoC rather
> than just mobile devices.
>
> Arun Ramamurthy (4):
> pwm: kona: Remove setting default smooth type and polarity for all
> channels
> pwm: kona: Fix incorrect enable after channel polarity change
> pwm: kona: Fix enable, disable and config procedures
> pwm: kona: Update dependency to ARCH_BCM
>
> drivers/pwm/Kconfig | 2 +-
> drivers/pwm/pwm-bcm-kona.c | 112 ++++++++++++++++++++++++++++++++-------------
> 2 files changed, 81 insertions(+), 33 deletions(-)
Can you please resend with Tim Kryger <[email protected]> in Cc. He
originally submitted the driver and I'd like him to at least have the
opportunity of looking at the patches.
Thierry
On Fri, Nov 14, 2014 at 10:30:00AM -0800, Scott Branden wrote:
> From: Arun Ramamurthy <[email protected]>
>
There's no patch description here. You should describe why you make this
change.
Thierry
On 14-11-17 04:52 AM, Thierry Reding wrote:
> On Fri, Nov 14, 2014 at 10:30:00AM -0800, Scott Branden wrote:
>> From: Arun Ramamurthy <[email protected]>
>>
>
> There's no patch description here. You should describe why you make this
> change.
Updated - sent v2 of patchset with Tim Kryger on cc list.
>
> Thierry
>