1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * R-Mobile TPU PWM driver |
4 | * |
5 | * Copyright (C) 2012 Renesas Solutions Corp. |
6 | */ |
7 | |
8 | #include <linux/clk.h> |
9 | #include <linux/err.h> |
10 | #include <linux/io.h> |
11 | #include <linux/init.h> |
12 | #include <linux/ioport.h> |
13 | #include <linux/module.h> |
14 | #include <linux/of.h> |
15 | #include <linux/platform_device.h> |
16 | #include <linux/pm_runtime.h> |
17 | #include <linux/pwm.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/spinlock.h> |
20 | |
21 | #define TPU_CHANNEL_MAX 4 |
22 | |
23 | #define TPU_TSTR 0x00 /* Timer start register (shared) */ |
24 | |
25 | #define TPU_TCRn 0x00 /* Timer control register */ |
26 | #define TPU_TCR_CCLR_NONE (0 << 5) |
27 | #define TPU_TCR_CCLR_TGRA (1 << 5) |
28 | #define TPU_TCR_CCLR_TGRB (2 << 5) |
29 | #define TPU_TCR_CCLR_TGRC (5 << 5) |
30 | #define TPU_TCR_CCLR_TGRD (6 << 5) |
31 | #define TPU_TCR_CKEG_RISING (0 << 3) |
32 | #define TPU_TCR_CKEG_FALLING (1 << 3) |
33 | #define TPU_TCR_CKEG_BOTH (2 << 3) |
34 | #define TPU_TMDRn 0x04 /* Timer mode register */ |
35 | #define TPU_TMDR_BFWT (1 << 6) |
36 | #define TPU_TMDR_BFB (1 << 5) |
37 | #define TPU_TMDR_BFA (1 << 4) |
38 | #define TPU_TMDR_MD_NORMAL (0 << 0) |
39 | #define TPU_TMDR_MD_PWM (2 << 0) |
40 | #define TPU_TIORn 0x08 /* Timer I/O control register */ |
41 | #define TPU_TIOR_IOA_0 (0 << 0) |
42 | #define TPU_TIOR_IOA_0_CLR (1 << 0) |
43 | #define TPU_TIOR_IOA_0_SET (2 << 0) |
44 | #define TPU_TIOR_IOA_0_TOGGLE (3 << 0) |
45 | #define TPU_TIOR_IOA_1 (4 << 0) |
46 | #define TPU_TIOR_IOA_1_CLR (5 << 0) |
47 | #define TPU_TIOR_IOA_1_SET (6 << 0) |
48 | #define TPU_TIOR_IOA_1_TOGGLE (7 << 0) |
49 | #define TPU_TIERn 0x0c /* Timer interrupt enable register */ |
50 | #define TPU_TSRn 0x10 /* Timer status register */ |
51 | #define TPU_TCNTn 0x14 /* Timer counter */ |
52 | #define TPU_TGRAn 0x18 /* Timer general register A */ |
53 | #define TPU_TGRBn 0x1c /* Timer general register B */ |
54 | #define TPU_TGRCn 0x20 /* Timer general register C */ |
55 | #define TPU_TGRDn 0x24 /* Timer general register D */ |
56 | |
57 | #define TPU_CHANNEL_OFFSET 0x10 |
58 | #define TPU_CHANNEL_SIZE 0x40 |
59 | |
60 | enum tpu_pin_state { |
61 | TPU_PIN_INACTIVE, /* Pin is driven inactive */ |
62 | TPU_PIN_PWM, /* Pin is driven by PWM */ |
63 | TPU_PIN_ACTIVE, /* Pin is driven active */ |
64 | }; |
65 | |
66 | struct tpu_device; |
67 | |
68 | struct tpu_pwm_device { |
69 | bool timer_on; /* Whether the timer is running */ |
70 | |
71 | struct tpu_device *tpu; |
72 | unsigned int channel; /* Channel number in the TPU */ |
73 | |
74 | enum pwm_polarity polarity; |
75 | unsigned int prescaler; |
76 | u16 period; |
77 | u16 duty; |
78 | }; |
79 | |
80 | struct tpu_device { |
81 | struct platform_device *pdev; |
82 | spinlock_t lock; |
83 | |
84 | void __iomem *base; |
85 | struct clk *clk; |
86 | struct tpu_pwm_device tpd[TPU_CHANNEL_MAX]; |
87 | }; |
88 | |
89 | static inline struct tpu_device *to_tpu_device(struct pwm_chip *chip) |
90 | { |
91 | return pwmchip_get_drvdata(chip); |
92 | } |
93 | |
94 | static void tpu_pwm_write(struct tpu_pwm_device *tpd, int reg_nr, u16 value) |
95 | { |
96 | void __iomem *base = tpd->tpu->base + TPU_CHANNEL_OFFSET |
97 | + tpd->channel * TPU_CHANNEL_SIZE; |
98 | |
99 | iowrite16(value, base + reg_nr); |
100 | } |
101 | |
102 | static void tpu_pwm_set_pin(struct tpu_pwm_device *tpd, |
103 | enum tpu_pin_state state) |
104 | { |
105 | static const char * const states[] = { "inactive" , "PWM" , "active" }; |
106 | |
107 | dev_dbg(&tpd->tpu->pdev->dev, "%u: configuring pin as %s\n" , |
108 | tpd->channel, states[state]); |
109 | |
110 | switch (state) { |
111 | case TPU_PIN_INACTIVE: |
112 | tpu_pwm_write(tpd, TPU_TIORn, |
113 | value: tpd->polarity == PWM_POLARITY_INVERSED ? |
114 | TPU_TIOR_IOA_1 : TPU_TIOR_IOA_0); |
115 | break; |
116 | case TPU_PIN_PWM: |
117 | tpu_pwm_write(tpd, TPU_TIORn, |
118 | value: tpd->polarity == PWM_POLARITY_INVERSED ? |
119 | TPU_TIOR_IOA_0_SET : TPU_TIOR_IOA_1_CLR); |
120 | break; |
121 | case TPU_PIN_ACTIVE: |
122 | tpu_pwm_write(tpd, TPU_TIORn, |
123 | value: tpd->polarity == PWM_POLARITY_INVERSED ? |
124 | TPU_TIOR_IOA_0 : TPU_TIOR_IOA_1); |
125 | break; |
126 | } |
127 | } |
128 | |
129 | static void tpu_pwm_start_stop(struct tpu_pwm_device *tpd, int start) |
130 | { |
131 | unsigned long flags; |
132 | u16 value; |
133 | |
134 | spin_lock_irqsave(&tpd->tpu->lock, flags); |
135 | value = ioread16(tpd->tpu->base + TPU_TSTR); |
136 | |
137 | if (start) |
138 | value |= 1 << tpd->channel; |
139 | else |
140 | value &= ~(1 << tpd->channel); |
141 | |
142 | iowrite16(value, tpd->tpu->base + TPU_TSTR); |
143 | spin_unlock_irqrestore(lock: &tpd->tpu->lock, flags); |
144 | } |
145 | |
146 | static int tpu_pwm_timer_start(struct tpu_pwm_device *tpd) |
147 | { |
148 | int ret; |
149 | |
150 | if (!tpd->timer_on) { |
151 | /* Wake up device and enable clock. */ |
152 | pm_runtime_get_sync(dev: &tpd->tpu->pdev->dev); |
153 | ret = clk_prepare_enable(clk: tpd->tpu->clk); |
154 | if (ret) { |
155 | dev_err(&tpd->tpu->pdev->dev, "cannot enable clock\n" ); |
156 | return ret; |
157 | } |
158 | tpd->timer_on = true; |
159 | } |
160 | |
161 | /* |
162 | * Make sure the channel is stopped, as we need to reconfigure it |
163 | * completely. First drive the pin to the inactive state to avoid |
164 | * glitches. |
165 | */ |
166 | tpu_pwm_set_pin(tpd, state: TPU_PIN_INACTIVE); |
167 | tpu_pwm_start_stop(tpd, start: false); |
168 | |
169 | /* |
170 | * - Clear TCNT on TGRB match |
171 | * - Count on rising edge |
172 | * - Set prescaler |
173 | * - Output 0 until TGRA, output 1 until TGRB (active low polarity) |
174 | * - Output 1 until TGRA, output 0 until TGRB (active high polarity |
175 | * - PWM mode |
176 | */ |
177 | tpu_pwm_write(tpd, TPU_TCRn, TPU_TCR_CCLR_TGRB | TPU_TCR_CKEG_RISING | |
178 | tpd->prescaler); |
179 | tpu_pwm_write(tpd, TPU_TMDRn, TPU_TMDR_MD_PWM); |
180 | tpu_pwm_set_pin(tpd, state: TPU_PIN_PWM); |
181 | tpu_pwm_write(tpd, TPU_TGRAn, value: tpd->duty); |
182 | tpu_pwm_write(tpd, TPU_TGRBn, value: tpd->period); |
183 | |
184 | dev_dbg(&tpd->tpu->pdev->dev, "%u: TGRA 0x%04x TGRB 0x%04x\n" , |
185 | tpd->channel, tpd->duty, tpd->period); |
186 | |
187 | /* Start the channel. */ |
188 | tpu_pwm_start_stop(tpd, start: true); |
189 | |
190 | return 0; |
191 | } |
192 | |
193 | static void tpu_pwm_timer_stop(struct tpu_pwm_device *tpd) |
194 | { |
195 | if (!tpd->timer_on) |
196 | return; |
197 | |
198 | /* Disable channel. */ |
199 | tpu_pwm_start_stop(tpd, start: false); |
200 | |
201 | /* Stop clock and mark device as idle. */ |
202 | clk_disable_unprepare(clk: tpd->tpu->clk); |
203 | pm_runtime_put(dev: &tpd->tpu->pdev->dev); |
204 | |
205 | tpd->timer_on = false; |
206 | } |
207 | |
208 | /* ----------------------------------------------------------------------------- |
209 | * PWM API |
210 | */ |
211 | |
212 | static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) |
213 | { |
214 | struct tpu_device *tpu = to_tpu_device(chip); |
215 | struct tpu_pwm_device *tpd; |
216 | |
217 | if (pwm->hwpwm >= TPU_CHANNEL_MAX) |
218 | return -EINVAL; |
219 | |
220 | tpd = &tpu->tpd[pwm->hwpwm]; |
221 | |
222 | tpd->tpu = tpu; |
223 | tpd->channel = pwm->hwpwm; |
224 | tpd->polarity = PWM_POLARITY_NORMAL; |
225 | tpd->prescaler = 0; |
226 | tpd->period = 0; |
227 | tpd->duty = 0; |
228 | |
229 | tpd->timer_on = false; |
230 | |
231 | return 0; |
232 | } |
233 | |
234 | static void tpu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
235 | { |
236 | struct tpu_device *tpu = to_tpu_device(chip); |
237 | struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm]; |
238 | |
239 | tpu_pwm_timer_stop(tpd); |
240 | } |
241 | |
242 | static int tpu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, |
243 | u64 duty_ns, u64 period_ns, bool enabled) |
244 | { |
245 | struct tpu_device *tpu = to_tpu_device(chip); |
246 | struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm]; |
247 | unsigned int prescaler; |
248 | bool duty_only = false; |
249 | u32 clk_rate; |
250 | u64 period; |
251 | u32 duty; |
252 | int ret; |
253 | |
254 | clk_rate = clk_get_rate(clk: tpu->clk); |
255 | if (unlikely(clk_rate > NSEC_PER_SEC)) { |
256 | /* |
257 | * This won't happen in the nearer future, so this is only a |
258 | * safeguard to prevent the following calculation from |
259 | * overflowing. With this clk_rate * period_ns / NSEC_PER_SEC is |
260 | * not greater than period_ns and so fits into an u64. |
261 | */ |
262 | return -EINVAL; |
263 | } |
264 | |
265 | period = mul_u64_u64_div_u64(a: clk_rate, mul: period_ns, NSEC_PER_SEC); |
266 | |
267 | /* |
268 | * Find the minimal prescaler in [0..3] such that |
269 | * |
270 | * period >> (2 * prescaler) < 0x10000 |
271 | * |
272 | * This could be calculated using something like: |
273 | * |
274 | * prescaler = max(ilog2(period) / 2, 7) - 7; |
275 | * |
276 | * but given there are only four allowed results and that ilog2 isn't |
277 | * cheap on all platforms using a switch statement is more effective. |
278 | */ |
279 | switch (period) { |
280 | case 1 ... 0xffff: |
281 | prescaler = 0; |
282 | break; |
283 | |
284 | case 0x10000 ... 0x3ffff: |
285 | prescaler = 1; |
286 | break; |
287 | |
288 | case 0x40000 ... 0xfffff: |
289 | prescaler = 2; |
290 | break; |
291 | |
292 | case 0x100000 ... 0x3fffff: |
293 | prescaler = 3; |
294 | break; |
295 | |
296 | default: |
297 | return -EINVAL; |
298 | } |
299 | |
300 | period >>= 2 * prescaler; |
301 | |
302 | if (duty_ns) |
303 | duty = mul_u64_u64_div_u64(a: clk_rate, mul: duty_ns, |
304 | div: (u64)NSEC_PER_SEC << (2 * prescaler)); |
305 | else |
306 | duty = 0; |
307 | |
308 | dev_dbg(&tpu->pdev->dev, |
309 | "rate %u, prescaler %u, period %u, duty %u\n" , |
310 | clk_rate, 1 << (2 * prescaler), (u32)period, duty); |
311 | |
312 | if (tpd->prescaler == prescaler && tpd->period == period) |
313 | duty_only = true; |
314 | |
315 | tpd->prescaler = prescaler; |
316 | tpd->period = period; |
317 | tpd->duty = duty; |
318 | |
319 | /* If the channel is disabled we're done. */ |
320 | if (!enabled) |
321 | return 0; |
322 | |
323 | if (duty_only && tpd->timer_on) { |
324 | /* |
325 | * If only the duty cycle changed and the timer is already |
326 | * running, there's no need to reconfigure it completely, Just |
327 | * modify the duty cycle. |
328 | */ |
329 | tpu_pwm_write(tpd, TPU_TGRAn, value: tpd->duty); |
330 | dev_dbg(&tpu->pdev->dev, "%u: TGRA 0x%04x\n" , tpd->channel, |
331 | tpd->duty); |
332 | } else { |
333 | /* Otherwise perform a full reconfiguration. */ |
334 | ret = tpu_pwm_timer_start(tpd); |
335 | if (ret < 0) |
336 | return ret; |
337 | } |
338 | |
339 | if (duty == 0 || duty == period) { |
340 | /* |
341 | * To avoid running the timer when not strictly required, handle |
342 | * 0% and 100% duty cycles as fixed levels and stop the timer. |
343 | */ |
344 | tpu_pwm_set_pin(tpd, state: duty ? TPU_PIN_ACTIVE : TPU_PIN_INACTIVE); |
345 | tpu_pwm_timer_stop(tpd); |
346 | } |
347 | |
348 | return 0; |
349 | } |
350 | |
351 | static int tpu_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, |
352 | enum pwm_polarity polarity) |
353 | { |
354 | struct tpu_device *tpu = to_tpu_device(chip); |
355 | struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm]; |
356 | |
357 | tpd->polarity = polarity; |
358 | |
359 | return 0; |
360 | } |
361 | |
362 | static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) |
363 | { |
364 | struct tpu_device *tpu = to_tpu_device(chip); |
365 | struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm]; |
366 | int ret; |
367 | |
368 | ret = tpu_pwm_timer_start(tpd); |
369 | if (ret < 0) |
370 | return ret; |
371 | |
372 | /* |
373 | * To avoid running the timer when not strictly required, handle 0% and |
374 | * 100% duty cycles as fixed levels and stop the timer. |
375 | */ |
376 | if (tpd->duty == 0 || tpd->duty == tpd->period) { |
377 | tpu_pwm_set_pin(tpd, state: tpd->duty ? |
378 | TPU_PIN_ACTIVE : TPU_PIN_INACTIVE); |
379 | tpu_pwm_timer_stop(tpd); |
380 | } |
381 | |
382 | return 0; |
383 | } |
384 | |
385 | static void tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) |
386 | { |
387 | struct tpu_device *tpu = to_tpu_device(chip); |
388 | struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm]; |
389 | |
390 | /* The timer must be running to modify the pin output configuration. */ |
391 | tpu_pwm_timer_start(tpd); |
392 | tpu_pwm_set_pin(tpd, state: TPU_PIN_INACTIVE); |
393 | tpu_pwm_timer_stop(tpd); |
394 | } |
395 | |
396 | static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, |
397 | const struct pwm_state *state) |
398 | { |
399 | int err; |
400 | bool enabled = pwm->state.enabled; |
401 | |
402 | if (state->polarity != pwm->state.polarity) { |
403 | if (enabled) { |
404 | tpu_pwm_disable(chip, pwm); |
405 | enabled = false; |
406 | } |
407 | |
408 | err = tpu_pwm_set_polarity(chip, pwm, polarity: state->polarity); |
409 | if (err) |
410 | return err; |
411 | } |
412 | |
413 | if (!state->enabled) { |
414 | if (enabled) |
415 | tpu_pwm_disable(chip, pwm); |
416 | |
417 | return 0; |
418 | } |
419 | |
420 | err = tpu_pwm_config(chip, pwm, |
421 | duty_ns: state->duty_cycle, period_ns: state->period, enabled); |
422 | if (err) |
423 | return err; |
424 | |
425 | if (!enabled) |
426 | err = tpu_pwm_enable(chip, pwm); |
427 | |
428 | return err; |
429 | } |
430 | |
431 | static const struct pwm_ops tpu_pwm_ops = { |
432 | .request = tpu_pwm_request, |
433 | .free = tpu_pwm_free, |
434 | .apply = tpu_pwm_apply, |
435 | }; |
436 | |
437 | /* ----------------------------------------------------------------------------- |
438 | * Probe and remove |
439 | */ |
440 | |
441 | static int tpu_probe(struct platform_device *pdev) |
442 | { |
443 | struct pwm_chip *chip; |
444 | struct tpu_device *tpu; |
445 | int ret; |
446 | |
447 | chip = devm_pwmchip_alloc(parent: &pdev->dev, TPU_CHANNEL_MAX, sizeof_priv: sizeof(*tpu)); |
448 | if (IS_ERR(ptr: chip)) |
449 | return PTR_ERR(ptr: chip); |
450 | tpu = to_tpu_device(chip); |
451 | |
452 | spin_lock_init(&tpu->lock); |
453 | tpu->pdev = pdev; |
454 | |
455 | /* Map memory, get clock and pin control. */ |
456 | tpu->base = devm_platform_ioremap_resource(pdev, index: 0); |
457 | if (IS_ERR(ptr: tpu->base)) |
458 | return PTR_ERR(ptr: tpu->base); |
459 | |
460 | tpu->clk = devm_clk_get(dev: &pdev->dev, NULL); |
461 | if (IS_ERR(ptr: tpu->clk)) |
462 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: tpu->clk), fmt: "Failed to get clock\n" ); |
463 | |
464 | /* Initialize and register the device. */ |
465 | platform_set_drvdata(pdev, data: tpu); |
466 | |
467 | chip->ops = &tpu_pwm_ops; |
468 | |
469 | ret = devm_pm_runtime_enable(dev: &pdev->dev); |
470 | if (ret < 0) |
471 | return dev_err_probe(dev: &pdev->dev, err: ret, fmt: "Failed to enable runtime PM\n" ); |
472 | |
473 | ret = devm_pwmchip_add(&pdev->dev, chip); |
474 | if (ret < 0) |
475 | return dev_err_probe(dev: &pdev->dev, err: ret, fmt: "Failed to register PWM chip\n" ); |
476 | |
477 | return 0; |
478 | } |
479 | |
480 | #ifdef CONFIG_OF |
481 | static const struct of_device_id tpu_of_table[] = { |
482 | { .compatible = "renesas,tpu-r8a73a4" , }, |
483 | { .compatible = "renesas,tpu-r8a7740" , }, |
484 | { .compatible = "renesas,tpu-r8a7790" , }, |
485 | { .compatible = "renesas,tpu" , }, |
486 | { }, |
487 | }; |
488 | |
489 | MODULE_DEVICE_TABLE(of, tpu_of_table); |
490 | #endif |
491 | |
492 | static struct platform_driver tpu_driver = { |
493 | .probe = tpu_probe, |
494 | .driver = { |
495 | .name = "renesas-tpu-pwm" , |
496 | .of_match_table = of_match_ptr(tpu_of_table), |
497 | } |
498 | }; |
499 | |
500 | module_platform_driver(tpu_driver); |
501 | |
502 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>" ); |
503 | MODULE_DESCRIPTION("Renesas TPU PWM Driver" ); |
504 | MODULE_LICENSE("GPL v2" ); |
505 | MODULE_ALIAS("platform:renesas-tpu-pwm" ); |
506 | |