mvebu: add Linux 4.0 support
[openwrt.git] / target / linux / mvebu / patches-4.0 / 202-gpio_mvebu_add_limited_pwm_support.patch
1 Armada 370/XP devices can 'blink' gpio lines with a configurable on
2 and off period. This can be modelled as a PWM.
3
4 However, there are only two sets of PWM configuration registers for
5 all the gpio lines. This driver simply allows a single gpio line per
6 gpio chip of 32 lines to be used as a PWM. Attempts to use more return
7 EBUSY.
8
9 Due to the interleaving of registers it is not simple to separate the
10 PWM driver from the gpio driver. Thus the gpio driver has been
11 extended with a PWM driver.
12
13 Signed-off-by: Andrew Lunn <andrew@lunn.ch>
14 ---
15  drivers/gpio/Kconfig          |   5 ++
16  drivers/gpio/Makefile         |   1 +
17  drivers/gpio/gpio-mvebu-pwm.c | 202 ++++++++++++++++++++++++++++++++++++++++++
18  drivers/gpio/gpio-mvebu.c     |  37 +++-----
19  drivers/gpio/gpio-mvebu.h     |  79 +++++++++++++++++
20  5 files changed, 299 insertions(+), 25 deletions(-)
21  create mode 100644 drivers/gpio/gpio-mvebu-pwm.c
22  create mode 100644 drivers/gpio/gpio-mvebu.h
23
24 --- a/drivers/gpio/Kconfig
25 +++ b/drivers/gpio/Kconfig
26 @@ -246,6 +246,11 @@ config GPIO_MVEBU
27         select GPIO_GENERIC
28         select GENERIC_IRQ_CHIP
29  
30 +config GPIO_MVEBU_PWM
31 +       def_bool y
32 +       depends on GPIO_MVEBU
33 +       depends on PWM
34 +
35  config GPIO_MXC
36         def_bool y
37         depends on ARCH_MXC
38 --- a/drivers/gpio/Makefile
39 +++ b/drivers/gpio/Makefile
40 @@ -61,6 +61,7 @@ obj-$(CONFIG_GPIO_MSIC)               += gpio-msic.o
41  obj-$(CONFIG_GPIO_MSM_V1)      += gpio-msm-v1.o
42  obj-$(CONFIG_GPIO_MSM_V2)      += gpio-msm-v2.o
43  obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
44 +obj-$(CONFIG_GPIO_MVEBU_PWM)   += gpio-mvebu-pwm.o
45  obj-$(CONFIG_GPIO_MXC)         += gpio-mxc.o
46  obj-$(CONFIG_GPIO_MXS)         += gpio-mxs.o
47  obj-$(CONFIG_GPIO_OCTEON)      += gpio-octeon.o
48 --- /dev/null
49 +++ b/drivers/gpio/gpio-mvebu-pwm.c
50 @@ -0,0 +1,202 @@
51 +#include <linux/err.h>
52 +#include <linux/module.h>
53 +#include <linux/gpio.h>
54 +#include <linux/pwm.h>
55 +#include <linux/clk.h>
56 +#include <linux/platform_device.h>
57 +#include "gpio-mvebu.h"
58 +#include "gpiolib.h"
59 +
60 +static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip)
61 +{
62 +       return mvchip->membase + GPIO_BLINK_CNT_SELECT;
63 +}
64 +
65 +static inline struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip)
66 +{
67 +       return container_of(chip, struct mvebu_pwm, chip);
68 +}
69 +
70 +static inline struct mvebu_gpio_chip *to_mvchip(struct mvebu_pwm *pwm)
71 +{
72 +       return container_of(pwm, struct mvebu_gpio_chip, pwm);
73 +}
74 +
75 +static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwmd)
76 +{
77 +       struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
78 +       struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
79 +       struct gpio_desc *desc = gpio_to_desc(pwmd->pwm);
80 +       unsigned long flags;
81 +       int ret = 0;
82 +
83 +       spin_lock_irqsave(&pwm->lock, flags);
84 +       if (pwm->used) {
85 +               ret = -EBUSY;
86 +       } else {
87 +               if (!desc) {
88 +                       ret = -ENODEV;
89 +                       goto out;
90 +               }
91 +               ret = gpiod_request(desc, "mvebu-pwm");
92 +               if (ret)
93 +                       goto out;
94 +
95 +               ret = gpiod_direction_output(desc, 0);
96 +               if (ret) {
97 +                       gpiod_free(desc);
98 +                       goto out;
99 +               }
100 +
101 +               pwm->pin = pwmd->pwm - mvchip->chip.base;
102 +               pwm->used = true;
103 +       }
104 +
105 +out:
106 +       spin_unlock_irqrestore(&pwm->lock, flags);
107 +       return ret;
108 +}
109 +
110 +static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwmd)
111 +{
112 +       struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
113 +       struct gpio_desc *desc = gpio_to_desc(pwmd->pwm);
114 +       unsigned long flags;
115 +
116 +       spin_lock_irqsave(&pwm->lock, flags);
117 +       gpiod_free(desc);
118 +       pwm->used = false;
119 +       spin_unlock_irqrestore(&pwm->lock, flags);
120 +}
121 +
122 +static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd,
123 +                           int duty_ns, int period_ns)
124 +{
125 +       struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
126 +       struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
127 +       unsigned int on, off;
128 +       unsigned long long val;
129 +       u32 u;
130 +
131 +       val = (unsigned long long) pwm->clk_rate * duty_ns;
132 +       do_div(val, NSEC_PER_SEC);
133 +       if (val > UINT_MAX)
134 +               return -EINVAL;
135 +       if (val)
136 +               on = val;
137 +       else
138 +               on = 1;
139 +
140 +       val = (unsigned long long) pwm->clk_rate * (period_ns - duty_ns);
141 +       do_div(val, NSEC_PER_SEC);
142 +       if (val > UINT_MAX)
143 +               return -EINVAL;
144 +       if (val)
145 +               off = val;
146 +       else
147 +               off = 1;
148 +
149 +       u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip));
150 +       u &= ~(1 << pwm->pin);
151 +       u |= (pwm->id << pwm->pin);
152 +       writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip));
153 +
154 +       writel_relaxed(on, pwm->membase + BLINK_ON_DURATION);
155 +       writel_relaxed(off, pwm->membase + BLINK_OFF_DURATION);
156 +
157 +       return 0;
158 +}
159 +
160 +static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwmd)
161 +{
162 +       struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
163 +       struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
164 +
165 +       mvebu_gpio_blink(&mvchip->chip, pwm->pin, 1);
166 +
167 +       return 0;
168 +}
169 +
170 +static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwmd)
171 +{
172 +       struct mvebu_pwm *pwm = to_mvebu_pwm(chip);
173 +       struct mvebu_gpio_chip *mvchip = to_mvchip(pwm);
174 +
175 +       mvebu_gpio_blink(&mvchip->chip, pwm->pin, 0);
176 +}
177 +
178 +static const struct pwm_ops mvebu_pwm_ops = {
179 +       .request = mvebu_pwm_request,
180 +       .free = mvebu_pwm_free,
181 +       .config = mvebu_pwm_config,
182 +       .enable = mvebu_pwm_enable,
183 +       .disable = mvebu_pwm_disable,
184 +       .owner = THIS_MODULE,
185 +};
186 +
187 +void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)
188 +{
189 +       struct mvebu_pwm *pwm = &mvchip->pwm;
190 +
191 +       pwm->blink_select = readl_relaxed(mvebu_gpioreg_blink_select(mvchip));
192 +       pwm->blink_on_duration =
193 +               readl_relaxed(pwm->membase + BLINK_ON_DURATION);
194 +       pwm->blink_off_duration =
195 +               readl_relaxed(pwm->membase + BLINK_OFF_DURATION);
196 +}
197 +
198 +void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
199 +{
200 +       struct mvebu_pwm *pwm = &mvchip->pwm;
201 +
202 +       writel_relaxed(pwm->blink_select, mvebu_gpioreg_blink_select(mvchip));
203 +       writel_relaxed(pwm->blink_on_duration,
204 +                      pwm->membase + BLINK_ON_DURATION);
205 +       writel_relaxed(pwm->blink_off_duration,
206 +                      pwm->membase + BLINK_OFF_DURATION);
207 +}
208 +
209 +/*
210 + * Armada 370/XP has simple PWM support for gpio lines. Other SoCs
211 + * don't have this hardware. So if we don't have the necessary
212 + * resource, it is not an error.
213 + */
214 +int mvebu_pwm_probe(struct platform_device *pdev,
215 +                   struct mvebu_gpio_chip *mvchip,
216 +                   int id)
217 +{
218 +       struct device *dev = &pdev->dev;
219 +       struct mvebu_pwm *pwm = &mvchip->pwm;
220 +       struct resource *res;
221 +
222 +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm");
223 +       if (!res)
224 +               return 0;
225 +
226 +       mvchip->pwm.membase = devm_ioremap_resource(&pdev->dev, res);
227 +       if (IS_ERR(mvchip->pwm.membase))
228 +               return PTR_ERR(mvchip->percpu_membase);
229 +
230 +       if (id < 0 || id > 1)
231 +               return -EINVAL;
232 +       pwm->id = id;
233 +
234 +       if (IS_ERR(mvchip->clk))
235 +               return PTR_ERR(mvchip->clk);
236 +
237 +       pwm->clk_rate = clk_get_rate(mvchip->clk);
238 +       if (!pwm->clk_rate) {
239 +               dev_err(dev, "failed to get clock rate\n");
240 +               return -EINVAL;
241 +       }
242 +
243 +       pwm->chip.dev = dev;
244 +       pwm->chip.ops = &mvebu_pwm_ops;
245 +       pwm->chip.base = mvchip->chip.base;
246 +       pwm->chip.npwm = mvchip->chip.ngpio;
247 +       pwm->chip.can_sleep = false;
248 +
249 +       spin_lock_init(&pwm->lock);
250 +
251 +       return pwmchip_add(&pwm->chip);
252 +}
253 --- a/drivers/gpio/gpio-mvebu.c
254 +++ b/drivers/gpio/gpio-mvebu.c
255 @@ -42,10 +42,11 @@
256  #include <linux/io.h>
257  #include <linux/of_irq.h>
258  #include <linux/of_device.h>
259 +#include <linux/pwm.h>
260  #include <linux/clk.h>
261  #include <linux/pinctrl/consumer.h>
262  #include <linux/irqchip/chained_irq.h>
263 -
264 +#include "gpio-mvebu.h"
265  /*
266   * GPIO unit register offsets.
267   */
268 @@ -75,24 +76,6 @@
269  
270  #define MVEBU_MAX_GPIO_PER_BANK                32
271  
272 -struct mvebu_gpio_chip {
273 -       struct gpio_chip   chip;
274 -       spinlock_t         lock;
275 -       void __iomem      *membase;
276 -       void __iomem      *percpu_membase;
277 -       int                irqbase;
278 -       struct irq_domain *domain;
279 -       int                soc_variant;
280 -
281 -       /* Used to preserve GPIO registers across suspend/resume */
282 -       u32                out_reg;
283 -       u32                io_conf_reg;
284 -       u32                blink_en_reg;
285 -       u32                in_pol_reg;
286 -       u32                edge_mask_regs[4];
287 -       u32                level_mask_regs[4];
288 -};
289 -
290  /*
291   * Functions returning addresses of individual registers for a given
292   * GPIO controller.
293 @@ -228,7 +211,7 @@ static int mvebu_gpio_get(struct gpio_ch
294         return (u >> pin) & 1;
295  }
296  
297 -static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
298 +void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
299  {
300         struct mvebu_gpio_chip *mvchip =
301                 container_of(chip, struct mvebu_gpio_chip, chip);
302 @@ -609,6 +592,8 @@ static int mvebu_gpio_suspend(struct pla
303                 BUG();
304         }
305  
306 +       mvebu_pwm_suspend(mvchip);
307 +
308         return 0;
309  }
310  
311 @@ -652,6 +637,8 @@ static int mvebu_gpio_resume(struct plat
312                 BUG();
313         }
314  
315 +       mvebu_pwm_resume(mvchip);
316 +
317         return 0;
318  }
319  
320 @@ -663,7 +650,6 @@ static int mvebu_gpio_probe(struct platf
321         struct resource *res;
322         struct irq_chip_generic *gc;
323         struct irq_chip_type *ct;
324 -       struct clk *clk;
325         unsigned int ngpios;
326         int soc_variant;
327         int i, cpu, id;
328 @@ -693,10 +679,10 @@ static int mvebu_gpio_probe(struct platf
329                 return id;
330         }
331  
332 -       clk = devm_clk_get(&pdev->dev, NULL);
333 +       mvchip->clk = devm_clk_get(&pdev->dev, NULL);
334         /* Not all SoCs require a clock.*/
335 -       if (!IS_ERR(clk))
336 -               clk_prepare_enable(clk);
337 +       if (!IS_ERR(mvchip->clk))
338 +               clk_prepare_enable(mvchip->clk);
339  
340         mvchip->soc_variant = soc_variant;
341         mvchip->chip.label = dev_name(&pdev->dev);
342 @@ -830,7 +816,8 @@ static int mvebu_gpio_probe(struct platf
343                 goto err_generic_chip;
344         }
345  
346 -       return 0;
347 +       /* Armada 370/XP has simple PWM support for gpio lines */
348 +       return mvebu_pwm_probe(pdev, mvchip, id);
349  
350  err_generic_chip:
351         irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
352 --- /dev/null
353 +++ b/drivers/gpio/gpio-mvebu.h
354 @@ -0,0 +1,79 @@
355 +/*
356 + * Interface between MVEBU GPIO driver and PWM driver for GPIO pins
357 + *
358 + * Copyright (C) 2015, Andrew Lunn <andrew@lunn.ch>
359 + *
360 + * This program is free software; you can redistribute it and/or modify
361 + * it under the terms of the GNU General Public License version 2 as
362 + * published by the Free Software Foundation.
363 + */
364 +
365 +#ifndef MVEBU_GPIO_PWM_H
366 +#define MVEBU_GPIO_PWM_H
367 +
368 +#define BLINK_ON_DURATION      0x0
369 +#define BLINK_OFF_DURATION     0x4
370 +#define GPIO_BLINK_CNT_SELECT  0x0020
371 +
372 +struct mvebu_pwm {
373 +       void __iomem    *membase;
374 +       unsigned long    clk_rate;
375 +       bool             used;
376 +       unsigned         pin;
377 +       struct pwm_chip  chip;
378 +       int              id;
379 +       spinlock_t       lock;
380 +
381 +       /* Used to preserve GPIO/PWM registers across suspend /
382 +        * resume */
383 +       u32              blink_select;
384 +       u32              blink_on_duration;
385 +       u32              blink_off_duration;
386 +};
387 +
388 +struct mvebu_gpio_chip {
389 +       struct gpio_chip   chip;
390 +       spinlock_t         lock;
391 +       void __iomem      *membase;
392 +       void __iomem      *percpu_membase;
393 +       int                irqbase;
394 +       struct irq_domain *domain;
395 +       int                soc_variant;
396 +       struct clk        *clk;
397 +#ifdef CONFIG_PWM
398 +       struct mvebu_pwm pwm;
399 +#endif
400 +       /* Used to preserve GPIO registers across suspend/resume */
401 +       u32                out_reg;
402 +       u32                io_conf_reg;
403 +       u32                blink_en_reg;
404 +       u32                in_pol_reg;
405 +       u32                edge_mask_regs[4];
406 +       u32                level_mask_regs[4];
407 +};
408 +
409 +void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value);
410 +
411 +#ifdef CONFIG_PWM
412 +int mvebu_pwm_probe(struct platform_device *pdev,
413 +                   struct mvebu_gpio_chip *mvchip,
414 +                   int id);
415 +void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip);
416 +void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip);
417 +#else
418 +int mvebu_pwm_probe(struct platform_device *pdev,
419 +                   struct mvebu_gpio_chip *mvchip,
420 +                   int id)
421 +{
422 +       return 0;
423 +}
424 +
425 +void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)
426 +{
427 +}
428 +
429 +void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip)
430 +{
431 +}
432 +#endif
433 +#endif