Re: [PATCH 2/3] drivers: pwm: pwm-bcm-kona: Add pwm-kona-v2 support
Hello, On Fri, Jan 11, 2019 at 10:51:15AM +0530, Sheetal Tigadoli wrote: > From: Praveen Kumar B > > Add support for new version of pwm-kona. > Add support to make PWM changes configured and stable. > > Signed-off-by: Praveen Kumar B > Reviewed-by: Ray Jui > Reviewed-by: Scott Branden > Signed-off-by: Sheetal Tigadoli > --- > drivers/pwm/pwm-bcm-kona.c | 128 > ++--- > 1 file changed, 98 insertions(+), 30 deletions(-) > > diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c > index 09a95ae..2b44ad8 100644 > --- a/drivers/pwm/pwm-bcm-kona.c > +++ b/drivers/pwm/pwm-bcm-kona.c > @@ -45,30 +45,39 @@ > *high or low depending on its state at that exact instant. > */ > > -#define PWM_CONTROL_OFFSET (0x) > +#define PWM_CONTROL_OFFSET 0x > #define PWM_CONTROL_SMOOTH_SHIFT(chan) (24 + (chan)) > #define PWM_CONTROL_TYPE_SHIFT(chan) (16 + (chan)) > #define PWM_CONTROL_POLARITY_SHIFT(chan) (8 + (chan)) > #define PWM_CONTROL_TRIGGER_SHIFT(chan) (chan) > > -#define PRESCALE_OFFSET (0x0004) > +#define PRESCALE_OFFSET 0x0004 > #define PRESCALE_SHIFT(chan) ((chan) << 2) > #define PRESCALE_MASK(chan) (0x7 << PRESCALE_SHIFT(chan)) > -#define PRESCALE_MIN (0x) > -#define PRESCALE_MAX (0x0007) > +#define PRESCALE_MIN 0x > +#define PRESCALE_MAX 0x0007 > > #define PERIOD_COUNT_OFFSET(chan)(0x0008 + ((chan) << 3)) > -#define PERIOD_COUNT_MIN (0x0002) > -#define PERIOD_COUNT_MAX (0x00ff) > +#define PERIOD_COUNT_MIN 0x0002 > +#define PERIOD_COUNT_MAX 0x00ff > > #define DUTY_CYCLE_HIGH_OFFSET(chan) (0x000c + ((chan) << 3)) > -#define DUTY_CYCLE_HIGH_MIN (0x) > -#define DUTY_CYCLE_HIGH_MAX (0x00ff) > +#define DUTY_CYCLE_HIGH_MIN 0x > +#define DUTY_CYCLE_HIGH_MAX 0x00ff All these are unrelated changes. > +#define PWM_MONITOR_OFFSET 0xb0 > +#define PWM_MONITOR_TIMEOUT_US 5 > + > +enum kona_pwmc_ver { > + KONA_PWM_V1 = 1, > + KONA_PWM_V2 > +}; > > struct kona_pwmc { > struct pwm_chip chip; > void __iomem *base; > struct clk *clk; > + enum kona_pwmc_ver version; > }; > > static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip) > @@ -76,11 +85,40 @@ static inline struct kona_pwmc *to_kona_pwmc(struct > pwm_chip *_chip) > return container_of(_chip, struct kona_pwmc, chip); > } > > +static int kona_pwmc_wait_stable(struct pwm_chip *chip, unsigned int chan, > + unsigned int kona_ver) > +{ > + struct kona_pwmc *kp = to_kona_pwmc(chip); > + unsigned int value; > + unsigned int count = PWM_MONITOR_TIMEOUT_US * 1000; > + > + switch (kona_ver) { > + case KONA_PWM_V1: > + /* > + * There must be a min 400ns delay between clearing trigger and > + * settingit. Failing to do this may result in no PWM signal. Space missing. > + */ > + ndelay(400); > + return 0; > + case KONA_PWM_V2: > + do { > + value = readl(kp->base + PWM_MONITOR_OFFSET); > + if (!(value & (BIT(chan > + return 0; > + ndelay(1); > + } while (count--); > + > + return -ETIMEDOUT; > + default: > + return -ENODEV; > + } I wonder if v1 and v2 are different enough to justify a separate driver for v2. > +} > + > /* > * Clear trigger bit but set smooth bit to maintain old output. > */ > -static void kona_pwmc_prepare_for_settings(struct kona_pwmc *kp, > - unsigned int chan) > +static int kona_pwmc_prepare_for_settings(struct kona_pwmc *kp, > + unsigned int chan) > { > unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET); > > @@ -88,14 +126,10 @@ static void kona_pwmc_prepare_for_settings(struct > kona_pwmc *kp, > value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan)); > writel(value, kp->base + PWM_CONTROL_OFFSET); > > - /* > - * There must be a min 400ns delay between clearing trigger and setting > - * it. Failing to do this may result in no PWM signal. > - */ > - ndelay(400); > + return kona_pwmc_wait_stable(&kp->chip, chan, kp->version); > } > > -static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) > +static int kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) > { >
Re: [PATCH 2/3] drivers: pwm: pwm-bcm-kona: Add pwm-kona-v2 support
On Fri, Jan 11, 2019 at 10:51:15AM +0530, Sheetal Tigadoli wrote: > From: Praveen Kumar B > > Add support for new version of pwm-kona. > Add support to make PWM changes configured and stable. > > Signed-off-by: Praveen Kumar B > Reviewed-by: Ray Jui > Reviewed-by: Scott Branden > Signed-off-by: Sheetal Tigadoli > --- > drivers/pwm/pwm-bcm-kona.c | 128 > ++--- > 1 file changed, 98 insertions(+), 30 deletions(-) > > diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c > index 09a95ae..2b44ad8 100644 > --- a/drivers/pwm/pwm-bcm-kona.c > +++ b/drivers/pwm/pwm-bcm-kona.c > @@ -45,30 +45,39 @@ > *high or low depending on its state at that exact instant. > */ > > -#define PWM_CONTROL_OFFSET (0x) > +#define PWM_CONTROL_OFFSET 0x > #define PWM_CONTROL_SMOOTH_SHIFT(chan) (24 + (chan)) > #define PWM_CONTROL_TYPE_SHIFT(chan) (16 + (chan)) > #define PWM_CONTROL_POLARITY_SHIFT(chan) (8 + (chan)) > #define PWM_CONTROL_TRIGGER_SHIFT(chan) (chan) > > -#define PRESCALE_OFFSET (0x0004) > +#define PRESCALE_OFFSET 0x0004 > #define PRESCALE_SHIFT(chan) ((chan) << 2) > #define PRESCALE_MASK(chan) (0x7 << PRESCALE_SHIFT(chan)) > -#define PRESCALE_MIN (0x) > -#define PRESCALE_MAX (0x0007) > +#define PRESCALE_MIN 0x > +#define PRESCALE_MAX 0x0007 Hi Praveen These changes are unrelated to adding support for a new PWM. So ideally they should be in a separate patch. > +static int kona_pwmc_wait_stable(struct pwm_chip *chip, unsigned int chan, > + unsigned int kona_ver) > +{ > + struct kona_pwmc *kp = to_kona_pwmc(chip); > + unsigned int value; > + unsigned int count = PWM_MONITOR_TIMEOUT_US * 1000; > + > + switch (kona_ver) { > + case KONA_PWM_V1: > + /* > + * There must be a min 400ns delay between clearing trigger and > + * settingit. Failing to do this may result in no PWM signal. > + */ > + ndelay(400); > + return 0; > + case KONA_PWM_V2: > + do { > + value = readl(kp->base + PWM_MONITOR_OFFSET); > + if (!(value & (BIT(chan > + return 0; > + ndelay(1); > + } while (count--); You can probably use readl_poll_timeout() here. Andrew
[PATCH 2/3] drivers: pwm: pwm-bcm-kona: Add pwm-kona-v2 support
From: Praveen Kumar B Add support for new version of pwm-kona. Add support to make PWM changes configured and stable. Signed-off-by: Praveen Kumar B Reviewed-by: Ray Jui Reviewed-by: Scott Branden Signed-off-by: Sheetal Tigadoli --- drivers/pwm/pwm-bcm-kona.c | 128 ++--- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c index 09a95ae..2b44ad8 100644 --- a/drivers/pwm/pwm-bcm-kona.c +++ b/drivers/pwm/pwm-bcm-kona.c @@ -45,30 +45,39 @@ *high or low depending on its state at that exact instant. */ -#define PWM_CONTROL_OFFSET (0x) +#define PWM_CONTROL_OFFSET 0x #define PWM_CONTROL_SMOOTH_SHIFT(chan) (24 + (chan)) #define PWM_CONTROL_TYPE_SHIFT(chan) (16 + (chan)) #define PWM_CONTROL_POLARITY_SHIFT(chan) (8 + (chan)) #define PWM_CONTROL_TRIGGER_SHIFT(chan)(chan) -#define PRESCALE_OFFSET(0x0004) +#define PRESCALE_OFFSET0x0004 #define PRESCALE_SHIFT(chan) ((chan) << 2) #define PRESCALE_MASK(chan)(0x7 << PRESCALE_SHIFT(chan)) -#define PRESCALE_MIN (0x) -#define PRESCALE_MAX (0x0007) +#define PRESCALE_MIN 0x +#define PRESCALE_MAX 0x0007 #define PERIOD_COUNT_OFFSET(chan) (0x0008 + ((chan) << 3)) -#define PERIOD_COUNT_MIN (0x0002) -#define PERIOD_COUNT_MAX (0x00ff) +#define PERIOD_COUNT_MIN 0x0002 +#define PERIOD_COUNT_MAX 0x00ff #define DUTY_CYCLE_HIGH_OFFSET(chan) (0x000c + ((chan) << 3)) -#define DUTY_CYCLE_HIGH_MIN(0x) -#define DUTY_CYCLE_HIGH_MAX(0x00ff) +#define DUTY_CYCLE_HIGH_MIN0x +#define DUTY_CYCLE_HIGH_MAX0x00ff + +#define PWM_MONITOR_OFFSET 0xb0 +#define PWM_MONITOR_TIMEOUT_US 5 + +enum kona_pwmc_ver { + KONA_PWM_V1 = 1, + KONA_PWM_V2 +}; struct kona_pwmc { struct pwm_chip chip; void __iomem *base; struct clk *clk; + enum kona_pwmc_ver version; }; static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip) @@ -76,11 +85,40 @@ static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip) return container_of(_chip, struct kona_pwmc, chip); } +static int kona_pwmc_wait_stable(struct pwm_chip *chip, unsigned int chan, +unsigned int kona_ver) +{ + struct kona_pwmc *kp = to_kona_pwmc(chip); + unsigned int value; + unsigned int count = PWM_MONITOR_TIMEOUT_US * 1000; + + switch (kona_ver) { + case KONA_PWM_V1: + /* +* There must be a min 400ns delay between clearing trigger and +* settingit. Failing to do this may result in no PWM signal. +*/ + ndelay(400); + return 0; + case KONA_PWM_V2: + do { + value = readl(kp->base + PWM_MONITOR_OFFSET); + if (!(value & (BIT(chan + return 0; + ndelay(1); + } while (count--); + + return -ETIMEDOUT; + default: + return -ENODEV; + } +} + /* * Clear trigger bit but set smooth bit to maintain old output. */ -static void kona_pwmc_prepare_for_settings(struct kona_pwmc *kp, - unsigned int chan) +static int kona_pwmc_prepare_for_settings(struct kona_pwmc *kp, + unsigned int chan) { unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET); @@ -88,14 +126,10 @@ static void kona_pwmc_prepare_for_settings(struct kona_pwmc *kp, value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan)); writel(value, kp->base + PWM_CONTROL_OFFSET); - /* -* There must be a min 400ns delay between clearing trigger and setting -* it. Failing to do this may result in no PWM signal. -*/ - ndelay(400); + return kona_pwmc_wait_stable(&kp->chip, chan, kp->version); } -static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) +static int kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) { unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET); @@ -104,8 +138,7 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan); writel(value, kp->base + PWM_CONTROL_OFFSET); - /* Trigger bit must be held high for at least 400 ns. */ -