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