Re: [PATCH 2/3] drivers: pwm: pwm-bcm-kona: Add pwm-kona-v2 support

2019-01-11 Thread Uwe Kleine-König
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

2019-01-11 Thread Andrew Lunn
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

2019-01-10 Thread Sheetal Tigadoli
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. */
-