From: Scott Branden <sbranden@broadcom.com>
To: Scott Branden <sbranden@broadcom.com>,
Thierry Reding <thierry.reding@gmail.com>
Cc: Ray Jui <rjui@broadcom.com>,
Arun Ramamurthy <arunrama@broadcom.com>,
Tim Kryger <tim.kryger@gmail.com>,
bcm-kernel-feedback-list@broadcom.com, linux-pwm@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 3/4] pwm: kona: Fix enable, disable and config procedures
Date: Tue, 25 Nov 2014 11:40:40 -0800 [thread overview]
Message-ID: <1416944441-12066-4-git-send-email-sbranden@broadcom.com> (raw)
In-Reply-To: <1416944441-12066-1-git-send-email-sbranden@broadcom.com>
From: Arun Ramamurthy <arunrama@broadcom.com>
- 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 <arunrama@broadcom.com>
Reviewed-by: Ray Jui <rjui@broadcom.com>
Signed-off-by: Scott Branden <sbranden@broadcom.com>
---
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
next prev parent reply other threads:[~2014-11-25 19:40 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Scott Branden <sbranden@broadcom.com>
2014-11-14 18:29 ` [PATCH 0/4] pwm: kona: Drivers fixes Scott Branden
2014-11-14 18:29 ` [PATCH 1/4] pwm: kona: Remove setting default smooth type and polarity for all channels Scott Branden
2014-11-14 18:29 ` [PATCH 2/4] pwm: kona: Fix incorrect enable after channel polarity change Scott Branden
2014-11-14 18:29 ` [PATCH 3/4] pwm: kona: Fix enable, disable and config procedures Scott Branden
2014-11-14 18:30 ` [PATCH 4/4] pwm: kona: Update dependency to ARCH_BCM Scott Branden
2014-11-17 12:52 ` Thierry Reding
2014-11-17 17:33 ` Scott Branden
2014-11-17 12:41 ` [PATCH 0/4] pwm: kona: Drivers fixes Thierry Reding
2014-11-25 19:40 ` [PATCH v2 " Scott Branden
2014-11-25 19:40 ` [PATCH v2 1/4] pwm: kona: Remove setting default smooth type and polarity for all channels Scott Branden
2014-11-26 5:51 ` Tim Kryger
2014-11-28 23:47 ` Arun Ramamurthy
2014-11-29 1:08 ` Tim Kryger
2014-11-29 1:19 ` Arun Ramamurthy
2014-11-29 3:19 ` Tim Kryger
2014-12-01 19:37 ` Arun Ramamurthy
2014-12-04 20:22 ` Jonathan Richardson
2014-12-06 23:13 ` Tim Kryger
2014-12-10 19:57 ` Jonathan Richardson
2014-11-25 19:40 ` [PATCH v2 2/4] pwm: kona: Fix incorrect enable after channel polarity change Scott Branden
2014-11-26 6:22 ` Tim Kryger
2014-11-28 23:48 ` Arun Ramamurthy
2014-11-29 2:02 ` Tim Kryger
2014-12-04 20:33 ` Jonathan Richardson
2014-11-25 19:40 ` Scott Branden [this message]
2014-11-26 7:29 ` [PATCH v2 3/4] pwm: kona: Fix enable, disable and config procedures Tim Kryger
2014-11-27 23:30 ` Scott Branden
2014-11-28 23:49 ` Arun Ramamurthy
2014-11-29 2:30 ` Tim Kryger
2014-12-01 19:37 ` Arun Ramamurthy
2014-12-02 4:29 ` Tim Kryger
2014-12-04 20:26 ` Jonathan Richardson
2014-11-25 19:40 ` [PATCH v2 4/4] pwm: kona: Update dependency to ARCH_BCM Scott Branden
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=1416944441-12066-4-git-send-email-sbranden@broadcom.com \
--to=sbranden@broadcom.com \
--cc=arunrama@broadcom.com \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=rjui@broadcom.com \
--cc=thierry.reding@gmail.com \
--cc=tim.kryger@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).