1
2
3
4
5
6
7
8
9
10
11
12#include <linux/bitfield.h>
13#include <linux/bitops.h>
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/platform_device.h>
23#include <linux/pwm.h>
24#include <linux/slab.h>
25
26#define MX3_PWMCR 0x00
27#define MX3_PWMSR 0x04
28#define MX3_PWMSAR 0x0C
29#define MX3_PWMPR 0x10
30
31#define MX3_PWMCR_FWM GENMASK(27, 26)
32#define MX3_PWMCR_STOPEN BIT(25)
33#define MX3_PWMCR_DOZEN BIT(24)
34#define MX3_PWMCR_WAITEN BIT(23)
35#define MX3_PWMCR_DBGEN BIT(22)
36#define MX3_PWMCR_BCTR BIT(21)
37#define MX3_PWMCR_HCTR BIT(20)
38
39#define MX3_PWMCR_POUTC GENMASK(19, 18)
40#define MX3_PWMCR_POUTC_NORMAL 0
41#define MX3_PWMCR_POUTC_INVERTED 1
42#define MX3_PWMCR_POUTC_OFF 2
43
44#define MX3_PWMCR_CLKSRC GENMASK(17, 16)
45#define MX3_PWMCR_CLKSRC_OFF 0
46#define MX3_PWMCR_CLKSRC_IPG 1
47#define MX3_PWMCR_CLKSRC_IPG_HIGH 2
48#define MX3_PWMCR_CLKSRC_IPG_32K 3
49
50#define MX3_PWMCR_PRESCALER GENMASK(15, 4)
51
52#define MX3_PWMCR_SWR BIT(3)
53
54#define MX3_PWMCR_REPEAT GENMASK(2, 1)
55#define MX3_PWMCR_REPEAT_1X 0
56#define MX3_PWMCR_REPEAT_2X 1
57#define MX3_PWMCR_REPEAT_4X 2
58#define MX3_PWMCR_REPEAT_8X 3
59
60#define MX3_PWMCR_EN BIT(0)
61
62#define MX3_PWMSR_FWE BIT(6)
63#define MX3_PWMSR_CMP BIT(5)
64#define MX3_PWMSR_ROV BIT(4)
65#define MX3_PWMSR_FE BIT(3)
66
67#define MX3_PWMSR_FIFOAV GENMASK(2, 0)
68#define MX3_PWMSR_FIFOAV_EMPTY 0
69#define MX3_PWMSR_FIFOAV_1WORD 1
70#define MX3_PWMSR_FIFOAV_2WORDS 2
71#define MX3_PWMSR_FIFOAV_3WORDS 3
72#define MX3_PWMSR_FIFOAV_4WORDS 4
73
74#define MX3_PWMCR_PRESCALER_SET(x) FIELD_PREP(MX3_PWMCR_PRESCALER, (x) - 1)
75#define MX3_PWMCR_PRESCALER_GET(x) (FIELD_GET(MX3_PWMCR_PRESCALER, \
76 (x)) + 1)
77
78#define MX3_PWM_SWR_LOOP 5
79
80
81#define MX3_PWMPR_MAX 0xfffe
82
83struct pwm_imx27_chip {
84 struct clk *clk_ipg;
85 struct clk *clk_per;
86 void __iomem *mmio_base;
87 struct pwm_chip chip;
88
89
90
91
92
93
94 unsigned int duty_cycle;
95};
96
97#define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip)
98
99static int pwm_imx27_clk_prepare_enable(struct pwm_chip *chip)
100{
101 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
102 int ret;
103
104 ret = clk_prepare_enable(imx->clk_ipg);
105 if (ret)
106 return ret;
107
108 ret = clk_prepare_enable(imx->clk_per);
109 if (ret) {
110 clk_disable_unprepare(imx->clk_ipg);
111 return ret;
112 }
113
114 return 0;
115}
116
117static void pwm_imx27_clk_disable_unprepare(struct pwm_chip *chip)
118{
119 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
120
121 clk_disable_unprepare(imx->clk_per);
122 clk_disable_unprepare(imx->clk_ipg);
123}
124
125static void pwm_imx27_get_state(struct pwm_chip *chip,
126 struct pwm_device *pwm, struct pwm_state *state)
127{
128 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
129 u32 period, prescaler, pwm_clk, val;
130 u64 tmp;
131 int ret;
132
133 ret = pwm_imx27_clk_prepare_enable(chip);
134 if (ret < 0)
135 return;
136
137 val = readl(imx->mmio_base + MX3_PWMCR);
138
139 if (val & MX3_PWMCR_EN)
140 state->enabled = true;
141 else
142 state->enabled = false;
143
144 switch (FIELD_GET(MX3_PWMCR_POUTC, val)) {
145 case MX3_PWMCR_POUTC_NORMAL:
146 state->polarity = PWM_POLARITY_NORMAL;
147 break;
148 case MX3_PWMCR_POUTC_INVERTED:
149 state->polarity = PWM_POLARITY_INVERSED;
150 break;
151 default:
152 dev_warn(chip->dev, "can't set polarity, output disconnected");
153 }
154
155 prescaler = MX3_PWMCR_PRESCALER_GET(val);
156 pwm_clk = clk_get_rate(imx->clk_per);
157 pwm_clk = DIV_ROUND_CLOSEST_ULL(pwm_clk, prescaler);
158 val = readl(imx->mmio_base + MX3_PWMPR);
159 period = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
160
161
162 tmp = NSEC_PER_SEC * (u64)(period + 2);
163 state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
164
165
166
167
168
169 if (state->enabled)
170 val = readl(imx->mmio_base + MX3_PWMSAR);
171 else
172 val = imx->duty_cycle;
173
174 tmp = NSEC_PER_SEC * (u64)(val);
175 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
176
177 if (!state->enabled)
178 pwm_imx27_clk_disable_unprepare(chip);
179}
180
181static void pwm_imx27_sw_reset(struct pwm_chip *chip)
182{
183 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
184 struct device *dev = chip->dev;
185 int wait_count = 0;
186 u32 cr;
187
188 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR);
189 do {
190 usleep_range(200, 1000);
191 cr = readl(imx->mmio_base + MX3_PWMCR);
192 } while ((cr & MX3_PWMCR_SWR) &&
193 (wait_count++ < MX3_PWM_SWR_LOOP));
194
195 if (cr & MX3_PWMCR_SWR)
196 dev_warn(dev, "software reset timeout\n");
197}
198
199static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
200 struct pwm_device *pwm)
201{
202 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
203 struct device *dev = chip->dev;
204 unsigned int period_ms;
205 int fifoav;
206 u32 sr;
207
208 sr = readl(imx->mmio_base + MX3_PWMSR);
209 fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
210 if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
211 period_ms = DIV_ROUND_UP(pwm_get_period(pwm),
212 NSEC_PER_MSEC);
213 msleep(period_ms);
214
215 sr = readl(imx->mmio_base + MX3_PWMSR);
216 if (fifoav == FIELD_GET(MX3_PWMSR_FIFOAV, sr))
217 dev_warn(dev, "there is no free FIFO slot\n");
218 }
219}
220
221static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
222 const struct pwm_state *state)
223{
224 unsigned long period_cycles, duty_cycles, prescale;
225 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
226 struct pwm_state cstate;
227 unsigned long long c;
228 int ret;
229 u32 cr;
230
231 pwm_get_state(pwm, &cstate);
232
233 c = clk_get_rate(imx->clk_per);
234 c *= state->period;
235
236 do_div(c, 1000000000);
237 period_cycles = c;
238
239 prescale = period_cycles / 0x10000 + 1;
240
241 period_cycles /= prescale;
242 c = (unsigned long long)period_cycles * state->duty_cycle;
243 do_div(c, state->period);
244 duty_cycles = c;
245
246
247
248
249
250 if (period_cycles > 2)
251 period_cycles -= 2;
252 else
253 period_cycles = 0;
254
255
256
257
258
259 if (cstate.enabled) {
260 pwm_imx27_wait_fifo_slot(chip, pwm);
261 } else {
262 ret = pwm_imx27_clk_prepare_enable(chip);
263 if (ret)
264 return ret;
265
266 pwm_imx27_sw_reset(chip);
267 }
268
269 writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
270 writel(period_cycles, imx->mmio_base + MX3_PWMPR);
271
272
273
274
275
276 imx->duty_cycle = duty_cycles;
277
278 cr = MX3_PWMCR_PRESCALER_SET(prescale) |
279 MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN |
280 FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) |
281 MX3_PWMCR_DBGEN;
282
283 if (state->polarity == PWM_POLARITY_INVERSED)
284 cr |= FIELD_PREP(MX3_PWMCR_POUTC,
285 MX3_PWMCR_POUTC_INVERTED);
286
287 if (state->enabled)
288 cr |= MX3_PWMCR_EN;
289
290 writel(cr, imx->mmio_base + MX3_PWMCR);
291
292 if (!state->enabled && cstate.enabled)
293 pwm_imx27_clk_disable_unprepare(chip);
294
295 return 0;
296}
297
298static const struct pwm_ops pwm_imx27_ops = {
299 .apply = pwm_imx27_apply,
300 .get_state = pwm_imx27_get_state,
301 .owner = THIS_MODULE,
302};
303
304static const struct of_device_id pwm_imx27_dt_ids[] = {
305 { .compatible = "fsl,imx27-pwm", },
306 { }
307};
308MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids);
309
310static int pwm_imx27_probe(struct platform_device *pdev)
311{
312 struct pwm_imx27_chip *imx;
313
314 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
315 if (imx == NULL)
316 return -ENOMEM;
317
318 platform_set_drvdata(pdev, imx);
319
320 imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
321 if (IS_ERR(imx->clk_ipg)) {
322 int ret = PTR_ERR(imx->clk_ipg);
323
324 if (ret != -EPROBE_DEFER)
325 dev_err(&pdev->dev,
326 "getting ipg clock failed with %d\n",
327 ret);
328 return ret;
329 }
330
331 imx->clk_per = devm_clk_get(&pdev->dev, "per");
332 if (IS_ERR(imx->clk_per)) {
333 int ret = PTR_ERR(imx->clk_per);
334
335 if (ret != -EPROBE_DEFER)
336 dev_err(&pdev->dev,
337 "failed to get peripheral clock: %d\n",
338 ret);
339
340 return ret;
341 }
342
343 imx->chip.ops = &pwm_imx27_ops;
344 imx->chip.dev = &pdev->dev;
345 imx->chip.base = -1;
346 imx->chip.npwm = 1;
347
348 imx->chip.of_xlate = of_pwm_xlate_with_flags;
349 imx->chip.of_pwm_n_cells = 3;
350
351 imx->mmio_base = devm_platform_ioremap_resource(pdev, 0);
352 if (IS_ERR(imx->mmio_base))
353 return PTR_ERR(imx->mmio_base);
354
355 return pwmchip_add(&imx->chip);
356}
357
358static int pwm_imx27_remove(struct platform_device *pdev)
359{
360 struct pwm_imx27_chip *imx;
361
362 imx = platform_get_drvdata(pdev);
363
364 pwm_imx27_clk_disable_unprepare(&imx->chip);
365
366 return pwmchip_remove(&imx->chip);
367}
368
369static struct platform_driver imx_pwm_driver = {
370 .driver = {
371 .name = "pwm-imx27",
372 .of_match_table = pwm_imx27_dt_ids,
373 },
374 .probe = pwm_imx27_probe,
375 .remove = pwm_imx27_remove,
376};
377module_platform_driver(imx_pwm_driver);
378
379MODULE_LICENSE("GPL v2");
380MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
381