aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-imx.c')
-rw-r--r--drivers/pwm/pwm-imx.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 5449d9150d40..f8b5f109c1ab 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/delay.h>
17#include <linux/io.h> 18#include <linux/io.h>
18#include <linux/pwm.h> 19#include <linux/pwm.h>
19#include <linux/of.h> 20#include <linux/of.h>
@@ -21,24 +22,30 @@
21 22
22/* i.MX1 and i.MX21 share the same PWM function block: */ 23/* i.MX1 and i.MX21 share the same PWM function block: */
23 24
24#define MX1_PWMC 0x00 /* PWM Control Register */ 25#define MX1_PWMC 0x00 /* PWM Control Register */
25#define MX1_PWMS 0x04 /* PWM Sample Register */ 26#define MX1_PWMS 0x04 /* PWM Sample Register */
26#define MX1_PWMP 0x08 /* PWM Period Register */ 27#define MX1_PWMP 0x08 /* PWM Period Register */
27 28
28#define MX1_PWMC_EN (1 << 4) 29#define MX1_PWMC_EN (1 << 4)
29 30
30/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ 31/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
31 32
32#define MX3_PWMCR 0x00 /* PWM Control Register */ 33#define MX3_PWMCR 0x00 /* PWM Control Register */
33#define MX3_PWMSAR 0x0C /* PWM Sample Register */ 34#define MX3_PWMSR 0x04 /* PWM Status Register */
34#define MX3_PWMPR 0x10 /* PWM Period Register */ 35#define MX3_PWMSAR 0x0C /* PWM Sample Register */
35#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) 36#define MX3_PWMPR 0x10 /* PWM Period Register */
36#define MX3_PWMCR_DOZEEN (1 << 24) 37#define MX3_PWMCR_PRESCALER(x) ((((x) - 1) & 0xFFF) << 4)
37#define MX3_PWMCR_WAITEN (1 << 23) 38#define MX3_PWMCR_DOZEEN (1 << 24)
39#define MX3_PWMCR_WAITEN (1 << 23)
38#define MX3_PWMCR_DBGEN (1 << 22) 40#define MX3_PWMCR_DBGEN (1 << 22)
39#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) 41#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
40#define MX3_PWMCR_CLKSRC_IPG (1 << 16) 42#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
41#define MX3_PWMCR_EN (1 << 0) 43#define MX3_PWMCR_SWR (1 << 3)
44#define MX3_PWMCR_EN (1 << 0)
45#define MX3_PWMSR_FIFOAV_4WORDS 0x4
46#define MX3_PWMSR_FIFOAV_MASK 0x7
47
48#define MX3_PWM_SWR_LOOP 5
42 49
43struct imx_chip { 50struct imx_chip {
44 struct clk *clk_per; 51 struct clk *clk_per;
@@ -103,9 +110,43 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
103 struct pwm_device *pwm, int duty_ns, int period_ns) 110 struct pwm_device *pwm, int duty_ns, int period_ns)
104{ 111{
105 struct imx_chip *imx = to_imx_chip(chip); 112 struct imx_chip *imx = to_imx_chip(chip);
113 struct device *dev = chip->dev;
106 unsigned long long c; 114 unsigned long long c;
107 unsigned long period_cycles, duty_cycles, prescale; 115 unsigned long period_cycles, duty_cycles, prescale;
108 u32 cr; 116 unsigned int period_ms;
117 bool enable = test_bit(PWMF_ENABLED, &pwm->flags);
118 int wait_count = 0, fifoav;
119 u32 cr, sr;
120
121 /*
122 * i.MX PWMv2 has a 4-word sample FIFO.
123 * In order to avoid FIFO overflow issue, we do software reset
124 * to clear all sample FIFO if the controller is disabled or
125 * wait for a full PWM cycle to get a relinquished FIFO slot
126 * when the controller is enabled and the FIFO is fully loaded.
127 */
128 if (enable) {
129 sr = readl(imx->mmio_base + MX3_PWMSR);
130 fifoav = sr & MX3_PWMSR_FIFOAV_MASK;
131 if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
132 period_ms = DIV_ROUND_UP(pwm->period, NSEC_PER_MSEC);
133 msleep(period_ms);
134
135 sr = readl(imx->mmio_base + MX3_PWMSR);
136 if (fifoav == (sr & MX3_PWMSR_FIFOAV_MASK))
137 dev_warn(dev, "there is no free FIFO slot\n");
138 }
139 } else {
140 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR);
141 do {
142 usleep_range(200, 1000);
143 cr = readl(imx->mmio_base + MX3_PWMCR);
144 } while ((cr & MX3_PWMCR_SWR) &&
145 (wait_count++ < MX3_PWM_SWR_LOOP));
146
147 if (cr & MX3_PWMCR_SWR)
148 dev_warn(dev, "software reset timeout\n");
149 }
109 150
110 c = clk_get_rate(imx->clk_per); 151 c = clk_get_rate(imx->clk_per);
111 c = c * period_ns; 152 c = c * period_ns;
@@ -135,7 +176,7 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
135 MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | 176 MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
136 MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH; 177 MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH;
137 178
138 if (test_bit(PWMF_ENABLED, &pwm->flags)) 179 if (enable)
139 cr |= MX3_PWMCR_EN; 180 cr |= MX3_PWMCR_EN;
140 181
141 writel(cr, imx->mmio_base + MX3_PWMCR); 182 writel(cr, imx->mmio_base + MX3_PWMCR);