1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * EHRPWM PWM driver
4 *
5 * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
6 */
7
8#include <linux/module.h>
9#include <linux/platform_device.h>
10#include <linux/pwm.h>
11#include <linux/io.h>
12#include <linux/err.h>
13#include <linux/clk.h>
14#include <linux/pm_runtime.h>
15#include <linux/of.h>
16
17/* EHRPWM registers and bits definitions */
18
19/* Time base module registers */
20#define TBCTL 0x00
21#define TBPRD 0x0A
22
23#define TBCTL_PRDLD_MASK BIT(3)
24#define TBCTL_PRDLD_SHDW 0
25#define TBCTL_PRDLD_IMDT BIT(3)
26#define TBCTL_CLKDIV_MASK (BIT(12) | BIT(11) | BIT(10) | BIT(9) | \
27 BIT(8) | BIT(7))
28#define TBCTL_CTRMODE_MASK (BIT(1) | BIT(0))
29#define TBCTL_CTRMODE_UP 0
30#define TBCTL_CTRMODE_DOWN BIT(0)
31#define TBCTL_CTRMODE_UPDOWN BIT(1)
32#define TBCTL_CTRMODE_FREEZE (BIT(1) | BIT(0))
33
34#define TBCTL_HSPCLKDIV_SHIFT 7
35#define TBCTL_CLKDIV_SHIFT 10
36
37#define CLKDIV_MAX 7
38#define HSPCLKDIV_MAX 7
39#define PERIOD_MAX 0x10000
40
41/* compare module registers */
42#define CMPA 0x12
43#define CMPB 0x14
44
45/* Action qualifier module registers */
46#define AQCTLA 0x16
47#define AQCTLB 0x18
48#define AQSFRC 0x1A
49#define AQCSFRC 0x1C
50
51#define AQCTL_CBU_MASK (BIT(9) | BIT(8))
52#define AQCTL_CBU_FRCLOW BIT(8)
53#define AQCTL_CBU_FRCHIGH BIT(9)
54#define AQCTL_CBU_FRCTOGGLE (BIT(9) | BIT(8))
55#define AQCTL_CAU_MASK (BIT(5) | BIT(4))
56#define AQCTL_CAU_FRCLOW BIT(4)
57#define AQCTL_CAU_FRCHIGH BIT(5)
58#define AQCTL_CAU_FRCTOGGLE (BIT(5) | BIT(4))
59#define AQCTL_PRD_MASK (BIT(3) | BIT(2))
60#define AQCTL_PRD_FRCLOW BIT(2)
61#define AQCTL_PRD_FRCHIGH BIT(3)
62#define AQCTL_PRD_FRCTOGGLE (BIT(3) | BIT(2))
63#define AQCTL_ZRO_MASK (BIT(1) | BIT(0))
64#define AQCTL_ZRO_FRCLOW BIT(0)
65#define AQCTL_ZRO_FRCHIGH BIT(1)
66#define AQCTL_ZRO_FRCTOGGLE (BIT(1) | BIT(0))
67
68#define AQCTL_CHANA_POLNORMAL (AQCTL_CAU_FRCLOW | AQCTL_ZRO_FRCHIGH)
69#define AQCTL_CHANA_POLINVERSED (AQCTL_CAU_FRCHIGH | AQCTL_ZRO_FRCLOW)
70#define AQCTL_CHANB_POLNORMAL (AQCTL_CBU_FRCLOW | AQCTL_ZRO_FRCHIGH)
71#define AQCTL_CHANB_POLINVERSED (AQCTL_CBU_FRCHIGH | AQCTL_ZRO_FRCLOW)
72
73#define AQSFRC_RLDCSF_MASK (BIT(7) | BIT(6))
74#define AQSFRC_RLDCSF_ZRO 0
75#define AQSFRC_RLDCSF_PRD BIT(6)
76#define AQSFRC_RLDCSF_ZROPRD BIT(7)
77#define AQSFRC_RLDCSF_IMDT (BIT(7) | BIT(6))
78
79#define AQCSFRC_CSFB_MASK (BIT(3) | BIT(2))
80#define AQCSFRC_CSFB_FRCDIS 0
81#define AQCSFRC_CSFB_FRCLOW BIT(2)
82#define AQCSFRC_CSFB_FRCHIGH BIT(3)
83#define AQCSFRC_CSFB_DISSWFRC (BIT(3) | BIT(2))
84#define AQCSFRC_CSFA_MASK (BIT(1) | BIT(0))
85#define AQCSFRC_CSFA_FRCDIS 0
86#define AQCSFRC_CSFA_FRCLOW BIT(0)
87#define AQCSFRC_CSFA_FRCHIGH BIT(1)
88#define AQCSFRC_CSFA_DISSWFRC (BIT(1) | BIT(0))
89
90#define NUM_PWM_CHANNEL 2 /* EHRPWM channels */
91
92struct ehrpwm_context {
93 u16 tbctl;
94 u16 tbprd;
95 u16 cmpa;
96 u16 cmpb;
97 u16 aqctla;
98 u16 aqctlb;
99 u16 aqsfrc;
100 u16 aqcsfrc;
101};
102
103struct ehrpwm_pwm_chip {
104 unsigned long clk_rate;
105 void __iomem *mmio_base;
106 unsigned long period_cycles[NUM_PWM_CHANNEL];
107 struct clk *tbclk;
108 struct ehrpwm_context ctx;
109};
110
111static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
112{
113 return pwmchip_get_drvdata(chip);
114}
115
116static inline u16 ehrpwm_read(void __iomem *base, unsigned int offset)
117{
118 return readw(addr: base + offset);
119}
120
121static inline void ehrpwm_write(void __iomem *base, unsigned int offset,
122 u16 value)
123{
124 writew(val: value, addr: base + offset);
125}
126
127static void ehrpwm_modify(void __iomem *base, unsigned int offset, u16 mask,
128 u16 value)
129{
130 unsigned short val;
131
132 val = readw(addr: base + offset);
133 val &= ~mask;
134 val |= value & mask;
135 writew(val, addr: base + offset);
136}
137
138/**
139 * set_prescale_div - Set up the prescaler divider function
140 * @rqst_prescaler: prescaler value min
141 * @prescale_div: prescaler value set
142 * @tb_clk_div: Time Base Control prescaler bits
143 */
144static int set_prescale_div(unsigned long rqst_prescaler, u16 *prescale_div,
145 u16 *tb_clk_div)
146{
147 unsigned int clkdiv, hspclkdiv;
148
149 for (clkdiv = 0; clkdiv <= CLKDIV_MAX; clkdiv++) {
150 for (hspclkdiv = 0; hspclkdiv <= HSPCLKDIV_MAX; hspclkdiv++) {
151 /*
152 * calculations for prescaler value :
153 * prescale_div = HSPCLKDIVIDER * CLKDIVIDER.
154 * HSPCLKDIVIDER = 2 ** hspclkdiv
155 * CLKDIVIDER = (1), if clkdiv == 0 *OR*
156 * (2 * clkdiv), if clkdiv != 0
157 *
158 * Configure prescale_div value such that period
159 * register value is less than 65535.
160 */
161
162 *prescale_div = (1 << clkdiv) *
163 (hspclkdiv ? (hspclkdiv * 2) : 1);
164 if (*prescale_div >= rqst_prescaler) {
165 *tb_clk_div = (clkdiv << TBCTL_CLKDIV_SHIFT) |
166 (hspclkdiv << TBCTL_HSPCLKDIV_SHIFT);
167 return 0;
168 }
169 }
170 }
171
172 return 1;
173}
174
175/*
176 * period_ns = 10^9 * (ps_divval * period_cycles) / PWM_CLK_RATE
177 * duty_ns = 10^9 * (ps_divval * duty_cycles) / PWM_CLK_RATE
178 */
179static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
180 u64 duty_ns, u64 period_ns, enum pwm_polarity polarity)
181{
182 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
183 u32 period_cycles, duty_cycles;
184 u16 ps_divval, tb_divval;
185 unsigned int i, cmp_reg;
186 unsigned long long c;
187 u16 aqctl_val, aqctl_mask;
188 unsigned int aqctl_reg;
189
190 if (period_ns > NSEC_PER_SEC)
191 return -ERANGE;
192
193 c = pc->clk_rate;
194 c = c * period_ns;
195 do_div(c, NSEC_PER_SEC);
196 period_cycles = (unsigned long)c;
197
198 c = pc->clk_rate;
199 c = c * duty_ns;
200 do_div(c, NSEC_PER_SEC);
201 duty_cycles = (unsigned long)c;
202
203 /*
204 * Period values should be same for multiple PWM channels as IP uses
205 * same period register for multiple channels.
206 */
207 for (i = 0; i < NUM_PWM_CHANNEL; i++) {
208 if (pc->period_cycles[i] &&
209 (pc->period_cycles[i] != period_cycles)) {
210 /*
211 * Allow channel to reconfigure period if no other
212 * channels being configured.
213 */
214 if (i == pwm->hwpwm)
215 continue;
216
217 dev_err(pwmchip_parent(chip),
218 "period value conflicts with channel %u\n",
219 i);
220 return -EINVAL;
221 }
222 }
223
224 pc->period_cycles[pwm->hwpwm] = period_cycles;
225
226 /* Configure clock prescaler to support Low frequency PWM wave */
227 if (set_prescale_div(DIV_ROUND_UP(period_cycles, PERIOD_MAX), prescale_div: &ps_divval,
228 tb_clk_div: &tb_divval)) {
229 dev_err(pwmchip_parent(chip), "Unsupported values\n");
230 return -EINVAL;
231 }
232
233 /* Update period & duty cycle with presacler division */
234 period_cycles = period_cycles / ps_divval;
235 duty_cycles = duty_cycles / ps_divval;
236
237 if (period_cycles < 1)
238 period_cycles = 1;
239
240 pm_runtime_get_sync(dev: pwmchip_parent(chip));
241
242 /* Update clock prescaler values */
243 ehrpwm_modify(base: pc->mmio_base, TBCTL, TBCTL_CLKDIV_MASK, value: tb_divval);
244
245 if (pwm->hwpwm == 1) {
246 /* Channel 1 configured with compare B register */
247 cmp_reg = CMPB;
248
249 aqctl_reg = AQCTLB;
250 aqctl_mask = AQCTL_CBU_MASK;
251
252 if (polarity == PWM_POLARITY_INVERSED)
253 aqctl_val = AQCTL_CHANB_POLINVERSED;
254 else
255 aqctl_val = AQCTL_CHANB_POLNORMAL;
256
257 /* if duty_cycle is big, don't toggle on CBU */
258 if (duty_cycles > period_cycles)
259 aqctl_val &= ~AQCTL_CBU_MASK;
260
261 } else {
262 /* Channel 0 configured with compare A register */
263 cmp_reg = CMPA;
264
265 aqctl_reg = AQCTLA;
266 aqctl_mask = AQCTL_CAU_MASK;
267
268 if (polarity == PWM_POLARITY_INVERSED)
269 aqctl_val = AQCTL_CHANA_POLINVERSED;
270 else
271 aqctl_val = AQCTL_CHANA_POLNORMAL;
272
273 /* if duty_cycle is big, don't toggle on CAU */
274 if (duty_cycles > period_cycles)
275 aqctl_val &= ~AQCTL_CAU_MASK;
276 }
277
278 aqctl_mask |= AQCTL_PRD_MASK | AQCTL_ZRO_MASK;
279 ehrpwm_modify(base: pc->mmio_base, offset: aqctl_reg, mask: aqctl_mask, value: aqctl_val);
280
281 /* Configure shadow loading on Period register */
282 ehrpwm_modify(base: pc->mmio_base, TBCTL, TBCTL_PRDLD_MASK, TBCTL_PRDLD_SHDW);
283
284 ehrpwm_write(base: pc->mmio_base, TBPRD, value: period_cycles - 1);
285
286 /* Configure ehrpwm counter for up-count mode */
287 ehrpwm_modify(base: pc->mmio_base, TBCTL, TBCTL_CTRMODE_MASK,
288 TBCTL_CTRMODE_UP);
289
290 if (!(duty_cycles > period_cycles))
291 ehrpwm_write(base: pc->mmio_base, offset: cmp_reg, value: duty_cycles);
292
293 pm_runtime_put_sync(dev: pwmchip_parent(chip));
294
295 return 0;
296}
297
298static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
299{
300 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
301 u16 aqcsfrc_val, aqcsfrc_mask;
302 int ret;
303
304 /* Leave clock enabled on enabling PWM */
305 pm_runtime_get_sync(dev: pwmchip_parent(chip));
306
307 /* Disabling Action Qualifier on PWM output */
308 if (pwm->hwpwm) {
309 aqcsfrc_val = AQCSFRC_CSFB_FRCDIS;
310 aqcsfrc_mask = AQCSFRC_CSFB_MASK;
311 } else {
312 aqcsfrc_val = AQCSFRC_CSFA_FRCDIS;
313 aqcsfrc_mask = AQCSFRC_CSFA_MASK;
314 }
315
316 /* Changes to shadow mode */
317 ehrpwm_modify(base: pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK,
318 AQSFRC_RLDCSF_ZRO);
319
320 ehrpwm_modify(base: pc->mmio_base, AQCSFRC, mask: aqcsfrc_mask, value: aqcsfrc_val);
321
322 /* Enable TBCLK */
323 ret = clk_enable(clk: pc->tbclk);
324 if (ret) {
325 dev_err(pwmchip_parent(chip), "Failed to enable TBCLK for %s: %d\n",
326 dev_name(pwmchip_parent(chip)), ret);
327 return ret;
328 }
329
330 return 0;
331}
332
333static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
334{
335 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
336 u16 aqcsfrc_val, aqcsfrc_mask;
337
338 /* Action Qualifier puts PWM output low forcefully */
339 if (pwm->hwpwm) {
340 aqcsfrc_val = AQCSFRC_CSFB_FRCLOW;
341 aqcsfrc_mask = AQCSFRC_CSFB_MASK;
342 } else {
343 aqcsfrc_val = AQCSFRC_CSFA_FRCLOW;
344 aqcsfrc_mask = AQCSFRC_CSFA_MASK;
345 }
346
347 /* Update shadow register first before modifying active register */
348 ehrpwm_modify(base: pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK,
349 AQSFRC_RLDCSF_ZRO);
350 ehrpwm_modify(base: pc->mmio_base, AQCSFRC, mask: aqcsfrc_mask, value: aqcsfrc_val);
351 /*
352 * Changes to immediate action on Action Qualifier. This puts
353 * Action Qualifier control on PWM output from next TBCLK
354 */
355 ehrpwm_modify(base: pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK,
356 AQSFRC_RLDCSF_IMDT);
357
358 ehrpwm_modify(base: pc->mmio_base, AQCSFRC, mask: aqcsfrc_mask, value: aqcsfrc_val);
359
360 /* Disabling TBCLK on PWM disable */
361 clk_disable(clk: pc->tbclk);
362
363 /* Disable clock on PWM disable */
364 pm_runtime_put_sync(dev: pwmchip_parent(chip));
365}
366
367static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
368{
369 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
370
371 /* Don't let a pwm without consumer block requests to the other channel */
372 pc->period_cycles[pwm->hwpwm] = 0;
373}
374
375static int ehrpwm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
376 const struct pwm_state *state)
377{
378 int err;
379 bool enabled = pwm->state.enabled;
380
381 if (state->polarity != pwm->state.polarity) {
382 if (enabled) {
383 ehrpwm_pwm_disable(chip, pwm);
384 enabled = false;
385 }
386 }
387
388 if (!state->enabled) {
389 if (enabled)
390 ehrpwm_pwm_disable(chip, pwm);
391 return 0;
392 }
393
394 err = ehrpwm_pwm_config(chip, pwm, duty_ns: state->duty_cycle, period_ns: state->period, polarity: state->polarity);
395 if (err)
396 return err;
397
398 if (!enabled)
399 err = ehrpwm_pwm_enable(chip, pwm);
400
401 return err;
402}
403
404static const struct pwm_ops ehrpwm_pwm_ops = {
405 .free = ehrpwm_pwm_free,
406 .apply = ehrpwm_pwm_apply,
407};
408
409static const struct of_device_id ehrpwm_of_match[] = {
410 { .compatible = "ti,am3352-ehrpwm" },
411 { .compatible = "ti,am33xx-ehrpwm" },
412 {},
413};
414MODULE_DEVICE_TABLE(of, ehrpwm_of_match);
415
416static int ehrpwm_pwm_probe(struct platform_device *pdev)
417{
418 struct device_node *np = pdev->dev.of_node;
419 struct ehrpwm_pwm_chip *pc;
420 struct pwm_chip *chip;
421 struct clk *clk;
422 int ret;
423
424 chip = devm_pwmchip_alloc(parent: &pdev->dev, NUM_PWM_CHANNEL, sizeof_priv: sizeof(*pc));
425 if (IS_ERR(ptr: chip))
426 return PTR_ERR(ptr: chip);
427 pc = to_ehrpwm_pwm_chip(chip);
428
429 clk = devm_clk_get(dev: &pdev->dev, id: "fck");
430 if (IS_ERR(ptr: clk)) {
431 if (of_device_is_compatible(device: np, "ti,am33xx-ecap")) {
432 dev_warn(&pdev->dev, "Binding is obsolete.\n");
433 clk = devm_clk_get(dev: pdev->dev.parent, id: "fck");
434 }
435 }
436
437 if (IS_ERR(ptr: clk))
438 return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: clk), fmt: "Failed to get fck\n");
439
440 pc->clk_rate = clk_get_rate(clk);
441 if (!pc->clk_rate) {
442 dev_err(&pdev->dev, "failed to get clock rate\n");
443 return -EINVAL;
444 }
445
446 chip->ops = &ehrpwm_pwm_ops;
447
448 pc->mmio_base = devm_platform_ioremap_resource(pdev, index: 0);
449 if (IS_ERR(ptr: pc->mmio_base))
450 return PTR_ERR(ptr: pc->mmio_base);
451
452 /* Acquire tbclk for Time Base EHRPWM submodule */
453 pc->tbclk = devm_clk_get(dev: &pdev->dev, id: "tbclk");
454 if (IS_ERR(ptr: pc->tbclk))
455 return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: pc->tbclk), fmt: "Failed to get tbclk\n");
456
457 ret = clk_prepare(clk: pc->tbclk);
458 if (ret < 0) {
459 dev_err(&pdev->dev, "clk_prepare() failed: %d\n", ret);
460 return ret;
461 }
462
463 ret = pwmchip_add(chip);
464 if (ret < 0) {
465 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
466 goto err_clk_unprepare;
467 }
468
469 platform_set_drvdata(pdev, data: chip);
470 pm_runtime_enable(dev: &pdev->dev);
471
472 return 0;
473
474err_clk_unprepare:
475 clk_unprepare(clk: pc->tbclk);
476
477 return ret;
478}
479
480static void ehrpwm_pwm_remove(struct platform_device *pdev)
481{
482 struct pwm_chip *chip = platform_get_drvdata(pdev);
483 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
484
485 pwmchip_remove(chip);
486
487 clk_unprepare(clk: pc->tbclk);
488
489 pm_runtime_disable(dev: &pdev->dev);
490}
491
492static void ehrpwm_pwm_save_context(struct pwm_chip *chip)
493{
494 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
495
496 pm_runtime_get_sync(dev: pwmchip_parent(chip));
497
498 pc->ctx.tbctl = ehrpwm_read(base: pc->mmio_base, TBCTL);
499 pc->ctx.tbprd = ehrpwm_read(base: pc->mmio_base, TBPRD);
500 pc->ctx.cmpa = ehrpwm_read(base: pc->mmio_base, CMPA);
501 pc->ctx.cmpb = ehrpwm_read(base: pc->mmio_base, CMPB);
502 pc->ctx.aqctla = ehrpwm_read(base: pc->mmio_base, AQCTLA);
503 pc->ctx.aqctlb = ehrpwm_read(base: pc->mmio_base, AQCTLB);
504 pc->ctx.aqsfrc = ehrpwm_read(base: pc->mmio_base, AQSFRC);
505 pc->ctx.aqcsfrc = ehrpwm_read(base: pc->mmio_base, AQCSFRC);
506
507 pm_runtime_put_sync(dev: pwmchip_parent(chip));
508}
509
510static void ehrpwm_pwm_restore_context(struct pwm_chip *chip)
511{
512 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
513
514 ehrpwm_write(base: pc->mmio_base, TBPRD, value: pc->ctx.tbprd);
515 ehrpwm_write(base: pc->mmio_base, CMPA, value: pc->ctx.cmpa);
516 ehrpwm_write(base: pc->mmio_base, CMPB, value: pc->ctx.cmpb);
517 ehrpwm_write(base: pc->mmio_base, AQCTLA, value: pc->ctx.aqctla);
518 ehrpwm_write(base: pc->mmio_base, AQCTLB, value: pc->ctx.aqctlb);
519 ehrpwm_write(base: pc->mmio_base, AQSFRC, value: pc->ctx.aqsfrc);
520 ehrpwm_write(base: pc->mmio_base, AQCSFRC, value: pc->ctx.aqcsfrc);
521 ehrpwm_write(base: pc->mmio_base, TBCTL, value: pc->ctx.tbctl);
522}
523
524static int ehrpwm_pwm_suspend(struct device *dev)
525{
526 struct pwm_chip *chip = dev_get_drvdata(dev);
527 unsigned int i;
528
529 ehrpwm_pwm_save_context(chip);
530
531 for (i = 0; i < chip->npwm; i++) {
532 struct pwm_device *pwm = &chip->pwms[i];
533
534 if (!pwm_is_enabled(pwm))
535 continue;
536
537 /* Disable explicitly if PWM is running */
538 pm_runtime_put_sync(dev);
539 }
540
541 return 0;
542}
543
544static int ehrpwm_pwm_resume(struct device *dev)
545{
546 struct pwm_chip *chip = dev_get_drvdata(dev);
547 unsigned int i;
548
549 for (i = 0; i < chip->npwm; i++) {
550 struct pwm_device *pwm = &chip->pwms[i];
551
552 if (!pwm_is_enabled(pwm))
553 continue;
554
555 /* Enable explicitly if PWM was running */
556 pm_runtime_get_sync(dev);
557 }
558
559 ehrpwm_pwm_restore_context(chip);
560
561 return 0;
562}
563
564static DEFINE_SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend,
565 ehrpwm_pwm_resume);
566
567static struct platform_driver ehrpwm_pwm_driver = {
568 .driver = {
569 .name = "ehrpwm",
570 .of_match_table = ehrpwm_of_match,
571 .pm = pm_ptr(&ehrpwm_pwm_pm_ops),
572 },
573 .probe = ehrpwm_pwm_probe,
574 .remove = ehrpwm_pwm_remove,
575};
576module_platform_driver(ehrpwm_pwm_driver);
577
578MODULE_DESCRIPTION("EHRPWM PWM driver");
579MODULE_AUTHOR("Texas Instruments");
580MODULE_LICENSE("GPL");
581

source code of linux/drivers/pwm/pwm-tiehrpwm.c