aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-imx.c
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@gmail.com>2017-02-10 09:15:56 -0500
committerThierry Reding <thierry.reding@gmail.com>2017-02-10 09:15:56 -0500
commit38b0a526ec33314ee1d9926e3a347078f63eac8e (patch)
tree7deea94e326a36567ccdf9a35188657305d1b5cc /drivers/pwm/pwm-imx.c
parent776906ff0350de74441a2e2387a2a69f55f0f71c (diff)
parent326ed314fefebb259563926c8c6110a009562e07 (diff)
Merge branch 'for-4.11/drivers' into for-next
Diffstat (limited to 'drivers/pwm/pwm-imx.c')
-rw-r--r--drivers/pwm/pwm-imx.c271
1 files changed, 129 insertions, 142 deletions
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 1223187ad354..2ba5c3a398ff 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -38,6 +38,7 @@
38#define MX3_PWMCR_DOZEEN (1 << 24) 38#define MX3_PWMCR_DOZEEN (1 << 24)
39#define MX3_PWMCR_WAITEN (1 << 23) 39#define MX3_PWMCR_WAITEN (1 << 23)
40#define MX3_PWMCR_DBGEN (1 << 22) 40#define MX3_PWMCR_DBGEN (1 << 22)
41#define MX3_PWMCR_POUTC (1 << 18)
41#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) 42#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
42#define MX3_PWMCR_CLKSRC_IPG (1 << 16) 43#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
43#define MX3_PWMCR_SWR (1 << 3) 44#define MX3_PWMCR_SWR (1 << 3)
@@ -49,15 +50,10 @@
49 50
50struct imx_chip { 51struct imx_chip {
51 struct clk *clk_per; 52 struct clk *clk_per;
52 struct clk *clk_ipg;
53 53
54 void __iomem *mmio_base; 54 void __iomem *mmio_base;
55 55
56 struct pwm_chip chip; 56 struct pwm_chip chip;
57
58 int (*config)(struct pwm_chip *chip,
59 struct pwm_device *pwm, int duty_ns, int period_ns);
60 void (*set_enable)(struct pwm_chip *chip, bool enable);
61}; 57};
62 58
63#define to_imx_chip(chip) container_of(chip, struct imx_chip, chip) 59#define to_imx_chip(chip) container_of(chip, struct imx_chip, chip)
@@ -91,176 +87,170 @@ static int imx_pwm_config_v1(struct pwm_chip *chip,
91 return 0; 87 return 0;
92} 88}
93 89
94static void imx_pwm_set_enable_v1(struct pwm_chip *chip, bool enable) 90static int imx_pwm_enable_v1(struct pwm_chip *chip, struct pwm_device *pwm)
95{ 91{
96 struct imx_chip *imx = to_imx_chip(chip); 92 struct imx_chip *imx = to_imx_chip(chip);
97 u32 val; 93 u32 val;
94 int ret;
98 95
99 val = readl(imx->mmio_base + MX1_PWMC); 96 ret = clk_prepare_enable(imx->clk_per);
100 97 if (ret < 0)
101 if (enable) 98 return ret;
102 val |= MX1_PWMC_EN;
103 else
104 val &= ~MX1_PWMC_EN;
105 99
100 val = readl(imx->mmio_base + MX1_PWMC);
101 val |= MX1_PWMC_EN;
106 writel(val, imx->mmio_base + MX1_PWMC); 102 writel(val, imx->mmio_base + MX1_PWMC);
107}
108
109static int imx_pwm_config_v2(struct pwm_chip *chip,
110 struct pwm_device *pwm, int duty_ns, int period_ns)
111{
112 struct imx_chip *imx = to_imx_chip(chip);
113 struct device *dev = chip->dev;
114 unsigned long long c;
115 unsigned long period_cycles, duty_cycles, prescale;
116 unsigned int period_ms;
117 bool enable = pwm_is_enabled(pwm);
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_get_period(pwm),
133 NSEC_PER_MSEC);
134 msleep(period_ms);
135
136 sr = readl(imx->mmio_base + MX3_PWMSR);
137 if (fifoav == (sr & MX3_PWMSR_FIFOAV_MASK))
138 dev_warn(dev, "there is no free FIFO slot\n");
139 }
140 } else {
141 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR);
142 do {
143 usleep_range(200, 1000);
144 cr = readl(imx->mmio_base + MX3_PWMCR);
145 } while ((cr & MX3_PWMCR_SWR) &&
146 (wait_count++ < MX3_PWM_SWR_LOOP));
147
148 if (cr & MX3_PWMCR_SWR)
149 dev_warn(dev, "software reset timeout\n");
150 }
151
152 c = clk_get_rate(imx->clk_per);
153 c = c * period_ns;
154 do_div(c, 1000000000);
155 period_cycles = c;
156
157 prescale = period_cycles / 0x10000 + 1;
158
159 period_cycles /= prescale;
160 c = (unsigned long long)period_cycles * duty_ns;
161 do_div(c, period_ns);
162 duty_cycles = c;
163
164 /*
165 * according to imx pwm RM, the real period value should be
166 * PERIOD value in PWMPR plus 2.
167 */
168 if (period_cycles > 2)
169 period_cycles -= 2;
170 else
171 period_cycles = 0;
172
173 writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
174 writel(period_cycles, imx->mmio_base + MX3_PWMPR);
175
176 cr = MX3_PWMCR_PRESCALER(prescale) |
177 MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
178 MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH;
179
180 if (enable)
181 cr |= MX3_PWMCR_EN;
182
183 writel(cr, imx->mmio_base + MX3_PWMCR);
184 103
185 return 0; 104 return 0;
186} 105}
187 106
188static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable) 107static void imx_pwm_disable_v1(struct pwm_chip *chip, struct pwm_device *pwm)
189{ 108{
190 struct imx_chip *imx = to_imx_chip(chip); 109 struct imx_chip *imx = to_imx_chip(chip);
191 u32 val; 110 u32 val;
192 111
193 val = readl(imx->mmio_base + MX3_PWMCR); 112 val = readl(imx->mmio_base + MX1_PWMC);
194 113 val &= ~MX1_PWMC_EN;
195 if (enable) 114 writel(val, imx->mmio_base + MX1_PWMC);
196 val |= MX3_PWMCR_EN;
197 else
198 val &= ~MX3_PWMCR_EN;
199 115
200 writel(val, imx->mmio_base + MX3_PWMCR); 116 clk_disable_unprepare(imx->clk_per);
201} 117}
202 118
203static int imx_pwm_config(struct pwm_chip *chip, 119static void imx_pwm_sw_reset(struct pwm_chip *chip)
204 struct pwm_device *pwm, int duty_ns, int period_ns)
205{ 120{
206 struct imx_chip *imx = to_imx_chip(chip); 121 struct imx_chip *imx = to_imx_chip(chip);
207 int ret; 122 struct device *dev = chip->dev;
208 123 int wait_count = 0;
209 ret = clk_prepare_enable(imx->clk_ipg); 124 u32 cr;
210 if (ret) 125
211 return ret; 126 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR);
127 do {
128 usleep_range(200, 1000);
129 cr = readl(imx->mmio_base + MX3_PWMCR);
130 } while ((cr & MX3_PWMCR_SWR) &&
131 (wait_count++ < MX3_PWM_SWR_LOOP));
132
133 if (cr & MX3_PWMCR_SWR)
134 dev_warn(dev, "software reset timeout\n");
135}
212 136
213 ret = imx->config(chip, pwm, duty_ns, period_ns); 137static void imx_pwm_wait_fifo_slot(struct pwm_chip *chip,
138 struct pwm_device *pwm)
139{
140 struct imx_chip *imx = to_imx_chip(chip);
141 struct device *dev = chip->dev;
142 unsigned int period_ms;
143 int fifoav;
144 u32 sr;
214 145
215 clk_disable_unprepare(imx->clk_ipg); 146 sr = readl(imx->mmio_base + MX3_PWMSR);
147 fifoav = sr & MX3_PWMSR_FIFOAV_MASK;
148 if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
149 period_ms = DIV_ROUND_UP(pwm_get_period(pwm),
150 NSEC_PER_MSEC);
151 msleep(period_ms);
216 152
217 return ret; 153 sr = readl(imx->mmio_base + MX3_PWMSR);
154 if (fifoav == (sr & MX3_PWMSR_FIFOAV_MASK))
155 dev_warn(dev, "there is no free FIFO slot\n");
156 }
218} 157}
219 158
220static int imx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 159static int imx_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
160 struct pwm_state *state)
221{ 161{
162 unsigned long period_cycles, duty_cycles, prescale;
222 struct imx_chip *imx = to_imx_chip(chip); 163 struct imx_chip *imx = to_imx_chip(chip);
164 struct pwm_state cstate;
165 unsigned long long c;
223 int ret; 166 int ret;
167 u32 cr;
168
169 pwm_get_state(pwm, &cstate);
170
171 if (state->enabled) {
172 c = clk_get_rate(imx->clk_per);
173 c *= state->period;
174
175 do_div(c, 1000000000);
176 period_cycles = c;
177
178 prescale = period_cycles / 0x10000 + 1;
179
180 period_cycles /= prescale;
181 c = (unsigned long long)period_cycles * state->duty_cycle;
182 do_div(c, state->period);
183 duty_cycles = c;
184
185 /*
186 * according to imx pwm RM, the real period value should be
187 * PERIOD value in PWMPR plus 2.
188 */
189 if (period_cycles > 2)
190 period_cycles -= 2;
191 else
192 period_cycles = 0;
193
194 /*
195 * Wait for a free FIFO slot if the PWM is already enabled, and
196 * flush the FIFO if the PWM was disabled and is about to be
197 * enabled.
198 */
199 if (cstate.enabled) {
200 imx_pwm_wait_fifo_slot(chip, pwm);
201 } else {
202 ret = clk_prepare_enable(imx->clk_per);
203 if (ret)
204 return ret;
205
206 imx_pwm_sw_reset(chip);
207 }
224 208
225 ret = clk_prepare_enable(imx->clk_per); 209 writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
226 if (ret) 210 writel(period_cycles, imx->mmio_base + MX3_PWMPR);
227 return ret;
228 211
229 imx->set_enable(chip, true); 212 cr = MX3_PWMCR_PRESCALER(prescale) |
213 MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
214 MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH |
215 MX3_PWMCR_EN;
230 216
231 return 0; 217 if (state->polarity == PWM_POLARITY_INVERSED)
232} 218 cr |= MX3_PWMCR_POUTC;
233 219
234static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 220 writel(cr, imx->mmio_base + MX3_PWMCR);
235{ 221 } else if (cstate.enabled) {
236 struct imx_chip *imx = to_imx_chip(chip); 222 writel(0, imx->mmio_base + MX3_PWMCR);
237 223
238 imx->set_enable(chip, false); 224 clk_disable_unprepare(imx->clk_per);
225 }
239 226
240 clk_disable_unprepare(imx->clk_per); 227 return 0;
241} 228}
242 229
243static struct pwm_ops imx_pwm_ops = { 230static const struct pwm_ops imx_pwm_ops_v1 = {
244 .enable = imx_pwm_enable, 231 .enable = imx_pwm_enable_v1,
245 .disable = imx_pwm_disable, 232 .disable = imx_pwm_disable_v1,
246 .config = imx_pwm_config, 233 .config = imx_pwm_config_v1,
234 .owner = THIS_MODULE,
235};
236
237static const struct pwm_ops imx_pwm_ops_v2 = {
238 .apply = imx_pwm_apply_v2,
247 .owner = THIS_MODULE, 239 .owner = THIS_MODULE,
248}; 240};
249 241
250struct imx_pwm_data { 242struct imx_pwm_data {
251 int (*config)(struct pwm_chip *chip, 243 bool polarity_supported;
252 struct pwm_device *pwm, int duty_ns, int period_ns); 244 const struct pwm_ops *ops;
253 void (*set_enable)(struct pwm_chip *chip, bool enable);
254}; 245};
255 246
256static struct imx_pwm_data imx_pwm_data_v1 = { 247static struct imx_pwm_data imx_pwm_data_v1 = {
257 .config = imx_pwm_config_v1, 248 .ops = &imx_pwm_ops_v1,
258 .set_enable = imx_pwm_set_enable_v1,
259}; 249};
260 250
261static struct imx_pwm_data imx_pwm_data_v2 = { 251static struct imx_pwm_data imx_pwm_data_v2 = {
262 .config = imx_pwm_config_v2, 252 .polarity_supported = true,
263 .set_enable = imx_pwm_set_enable_v2, 253 .ops = &imx_pwm_ops_v2,
264}; 254};
265 255
266static const struct of_device_id imx_pwm_dt_ids[] = { 256static const struct of_device_id imx_pwm_dt_ids[] = {
@@ -282,6 +272,8 @@ static int imx_pwm_probe(struct platform_device *pdev)
282 if (!of_id) 272 if (!of_id)
283 return -ENODEV; 273 return -ENODEV;
284 274
275 data = of_id->data;
276
285 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); 277 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
286 if (imx == NULL) 278 if (imx == NULL)
287 return -ENOMEM; 279 return -ENOMEM;
@@ -293,27 +285,22 @@ static int imx_pwm_probe(struct platform_device *pdev)
293 return PTR_ERR(imx->clk_per); 285 return PTR_ERR(imx->clk_per);
294 } 286 }
295 287
296 imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 288 imx->chip.ops = data->ops;
297 if (IS_ERR(imx->clk_ipg)) {
298 dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
299 PTR_ERR(imx->clk_ipg));
300 return PTR_ERR(imx->clk_ipg);
301 }
302
303 imx->chip.ops = &imx_pwm_ops;
304 imx->chip.dev = &pdev->dev; 289 imx->chip.dev = &pdev->dev;
305 imx->chip.base = -1; 290 imx->chip.base = -1;
306 imx->chip.npwm = 1; 291 imx->chip.npwm = 1;
307 292
293 if (data->polarity_supported) {
294 dev_dbg(&pdev->dev, "PWM supports output inversion\n");
295 imx->chip.of_xlate = of_pwm_xlate_with_flags;
296 imx->chip.of_pwm_n_cells = 3;
297 }
298
308 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 299 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
309 imx->mmio_base = devm_ioremap_resource(&pdev->dev, r); 300 imx->mmio_base = devm_ioremap_resource(&pdev->dev, r);
310 if (IS_ERR(imx->mmio_base)) 301 if (IS_ERR(imx->mmio_base))
311 return PTR_ERR(imx->mmio_base); 302 return PTR_ERR(imx->mmio_base);
312 303
313 data = of_id->data;
314 imx->config = data->config;
315 imx->set_enable = data->set_enable;
316
317 ret = pwmchip_add(&imx->chip); 304 ret = pwmchip_add(&imx->chip);
318 if (ret < 0) 305 if (ret < 0)
319 return ret; 306 return ret;