1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Renesas RZ/G2L MTU3a Counter driver |
4 | * |
5 | * Copyright (C) 2022 Renesas Electronics Corporation |
6 | */ |
7 | |
8 | #include <linux/clk.h> |
9 | #include <linux/counter.h> |
10 | #include <linux/mfd/rz-mtu3.h> |
11 | #include <linux/module.h> |
12 | #include <linux/platform_device.h> |
13 | #include <linux/pm_runtime.h> |
14 | #include <linux/types.h> |
15 | |
16 | /* |
17 | * Register descriptions |
18 | * TSR: Timer Status Register |
19 | * TMDR1: Timer Mode Register 1 |
20 | * TMDR3: Timer Mode Register 3 |
21 | * TIOR: Timer I/O Control Register |
22 | * TCR: Timer Control Register |
23 | * TCNT: Timer Counter |
24 | * TGRA: Timer general register A |
25 | * TCNTLW: Timer Longword Counter |
26 | * TGRALW: Timer longword general register A |
27 | */ |
28 | |
29 | #define RZ_MTU3_TSR_TCFD BIT(7) /* Count Direction Flag */ |
30 | |
31 | #define RZ_MTU3_TMDR1_PH_CNT_MODE_1 (4) /* Phase counting mode 1 */ |
32 | #define RZ_MTU3_TMDR1_PH_CNT_MODE_2 (5) /* Phase counting mode 2 */ |
33 | #define RZ_MTU3_TMDR1_PH_CNT_MODE_3 (6) /* Phase counting mode 3 */ |
34 | #define RZ_MTU3_TMDR1_PH_CNT_MODE_4 (7) /* Phase counting mode 4 */ |
35 | #define RZ_MTU3_TMDR1_PH_CNT_MODE_5 (9) /* Phase counting mode 5 */ |
36 | #define RZ_MTU3_TMDR1_PH_CNT_MODE_MASK (0xf) |
37 | |
38 | /* |
39 | * LWA: MTU1/MTU2 Combination Longword Access Control |
40 | * 0: 16-bit, 1: 32-bit |
41 | */ |
42 | #define RZ_MTU3_TMDR3_LWA (0) |
43 | |
44 | /* |
45 | * PHCKSEL: External Input Phase Clock Select |
46 | * 0: MTCLKA and MTCLKB, 1: MTCLKC and MTCLKD |
47 | */ |
48 | #define RZ_MTU3_TMDR3_PHCKSEL (1) |
49 | |
50 | #define RZ_MTU3_16_BIT_MTU1_CH (0) |
51 | #define RZ_MTU3_16_BIT_MTU2_CH (1) |
52 | #define RZ_MTU3_32_BIT_CH (2) |
53 | |
54 | #define RZ_MTU3_TIOR_NO_OUTPUT (0) /* Output prohibited */ |
55 | #define RZ_MTU3_TIOR_IC_BOTH (10) /* Input capture at both edges */ |
56 | |
57 | #define SIGNAL_A_ID (0) |
58 | #define SIGNAL_B_ID (1) |
59 | #define SIGNAL_C_ID (2) |
60 | #define SIGNAL_D_ID (3) |
61 | |
62 | #define RZ_MTU3_MAX_HW_CNTR_CHANNELS (2) |
63 | #define RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS (3) |
64 | |
65 | /** |
66 | * struct rz_mtu3_cnt - MTU3 counter private data |
67 | * |
68 | * @clk: MTU3 module clock |
69 | * @lock: Lock to prevent concurrent access for ceiling and count |
70 | * @ch: HW channels for the counters |
71 | * @count_is_enabled: Enabled state of Counter value channel |
72 | * @mtu_16bit_max: Cache for 16-bit counters |
73 | * @mtu_32bit_max: Cache for 32-bit counters |
74 | */ |
75 | struct rz_mtu3_cnt { |
76 | struct clk *clk; |
77 | struct mutex lock; |
78 | struct rz_mtu3_channel *ch; |
79 | bool count_is_enabled[RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS]; |
80 | union { |
81 | u16 mtu_16bit_max[RZ_MTU3_MAX_HW_CNTR_CHANNELS]; |
82 | u32 mtu_32bit_max; |
83 | }; |
84 | }; |
85 | |
86 | static const enum counter_function rz_mtu3_count_functions[] = { |
87 | COUNTER_FUNCTION_QUADRATURE_X4, |
88 | COUNTER_FUNCTION_PULSE_DIRECTION, |
89 | COUNTER_FUNCTION_QUADRATURE_X2_B, |
90 | }; |
91 | |
92 | static inline size_t rz_mtu3_get_hw_ch(const size_t id) |
93 | { |
94 | return (id == RZ_MTU3_32_BIT_CH) ? 0 : id; |
95 | } |
96 | |
97 | static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *counter, int id) |
98 | { |
99 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
100 | const size_t ch_id = rz_mtu3_get_hw_ch(id); |
101 | |
102 | return &priv->ch[ch_id]; |
103 | } |
104 | |
105 | static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id) |
106 | { |
107 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
108 | unsigned long tmdr; |
109 | |
110 | pm_runtime_get_sync(dev: priv->ch->dev); |
111 | tmdr = rz_mtu3_shared_reg_read(ch: priv->ch, RZ_MTU3_TMDR3); |
112 | pm_runtime_put(dev: priv->ch->dev); |
113 | |
114 | if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr)) |
115 | return false; |
116 | |
117 | if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr)) |
118 | return false; |
119 | |
120 | return true; |
121 | } |
122 | |
123 | static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter, |
124 | struct rz_mtu3_channel *const ch, |
125 | struct rz_mtu3_cnt *const priv, |
126 | int id) |
127 | { |
128 | mutex_lock(&priv->lock); |
129 | |
130 | if (ch->is_busy && !priv->count_is_enabled[id]) { |
131 | mutex_unlock(lock: &priv->lock); |
132 | return -EINVAL; |
133 | } |
134 | |
135 | if (rz_mtu3_is_counter_invalid(counter, id)) { |
136 | mutex_unlock(lock: &priv->lock); |
137 | return -EBUSY; |
138 | } |
139 | |
140 | return 0; |
141 | } |
142 | |
143 | static int rz_mtu3_lock_if_count_is_enabled(struct rz_mtu3_channel *const ch, |
144 | struct rz_mtu3_cnt *const priv, |
145 | int id) |
146 | { |
147 | mutex_lock(&priv->lock); |
148 | |
149 | if (ch->is_busy && !priv->count_is_enabled[id]) { |
150 | mutex_unlock(lock: &priv->lock); |
151 | return -EINVAL; |
152 | } |
153 | |
154 | return 0; |
155 | } |
156 | |
157 | static int rz_mtu3_count_read(struct counter_device *counter, |
158 | struct counter_count *count, u64 *val) |
159 | { |
160 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
161 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
162 | int ret; |
163 | |
164 | ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, id: count->id); |
165 | if (ret) |
166 | return ret; |
167 | |
168 | pm_runtime_get_sync(dev: ch->dev); |
169 | if (count->id == RZ_MTU3_32_BIT_CH) |
170 | *val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW); |
171 | else |
172 | *val = rz_mtu3_16bit_ch_read(ch, RZ_MTU3_TCNT); |
173 | pm_runtime_put(dev: ch->dev); |
174 | mutex_unlock(lock: &priv->lock); |
175 | |
176 | return 0; |
177 | } |
178 | |
179 | static int rz_mtu3_count_write(struct counter_device *counter, |
180 | struct counter_count *count, const u64 val) |
181 | { |
182 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
183 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
184 | int ret; |
185 | |
186 | ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, id: count->id); |
187 | if (ret) |
188 | return ret; |
189 | |
190 | pm_runtime_get_sync(dev: ch->dev); |
191 | if (count->id == RZ_MTU3_32_BIT_CH) |
192 | rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val); |
193 | else |
194 | rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TCNT, val); |
195 | pm_runtime_put(dev: ch->dev); |
196 | mutex_unlock(lock: &priv->lock); |
197 | |
198 | return 0; |
199 | } |
200 | |
201 | static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch, |
202 | struct rz_mtu3_cnt *const priv, |
203 | enum counter_function *function) |
204 | { |
205 | u8 timer_mode; |
206 | |
207 | pm_runtime_get_sync(dev: ch->dev); |
208 | timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1); |
209 | pm_runtime_put(dev: ch->dev); |
210 | |
211 | switch (timer_mode & RZ_MTU3_TMDR1_PH_CNT_MODE_MASK) { |
212 | case RZ_MTU3_TMDR1_PH_CNT_MODE_1: |
213 | *function = COUNTER_FUNCTION_QUADRATURE_X4; |
214 | return 0; |
215 | case RZ_MTU3_TMDR1_PH_CNT_MODE_2: |
216 | *function = COUNTER_FUNCTION_PULSE_DIRECTION; |
217 | return 0; |
218 | case RZ_MTU3_TMDR1_PH_CNT_MODE_4: |
219 | *function = COUNTER_FUNCTION_QUADRATURE_X2_B; |
220 | return 0; |
221 | default: |
222 | /* |
223 | * TODO: |
224 | * - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_3 |
225 | * - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_5 |
226 | */ |
227 | return -EINVAL; |
228 | } |
229 | } |
230 | |
231 | static int rz_mtu3_count_function_read(struct counter_device *counter, |
232 | struct counter_count *count, |
233 | enum counter_function *function) |
234 | { |
235 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
236 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
237 | int ret; |
238 | |
239 | ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, id: count->id); |
240 | if (ret) |
241 | return ret; |
242 | |
243 | ret = rz_mtu3_count_function_read_helper(ch, priv, function); |
244 | mutex_unlock(lock: &priv->lock); |
245 | |
246 | return ret; |
247 | } |
248 | |
249 | static int rz_mtu3_count_function_write(struct counter_device *counter, |
250 | struct counter_count *count, |
251 | enum counter_function function) |
252 | { |
253 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
254 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
255 | u8 timer_mode; |
256 | int ret; |
257 | |
258 | ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, id: count->id); |
259 | if (ret) |
260 | return ret; |
261 | |
262 | switch (function) { |
263 | case COUNTER_FUNCTION_QUADRATURE_X4: |
264 | timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_1; |
265 | break; |
266 | case COUNTER_FUNCTION_PULSE_DIRECTION: |
267 | timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_2; |
268 | break; |
269 | case COUNTER_FUNCTION_QUADRATURE_X2_B: |
270 | timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_4; |
271 | break; |
272 | default: |
273 | /* |
274 | * TODO: |
275 | * - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_3 |
276 | * - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_5 |
277 | */ |
278 | mutex_unlock(lock: &priv->lock); |
279 | return -EINVAL; |
280 | } |
281 | |
282 | pm_runtime_get_sync(dev: ch->dev); |
283 | rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, val: timer_mode); |
284 | pm_runtime_put(dev: ch->dev); |
285 | mutex_unlock(lock: &priv->lock); |
286 | |
287 | return 0; |
288 | } |
289 | |
290 | static int rz_mtu3_count_direction_read(struct counter_device *counter, |
291 | struct counter_count *count, |
292 | enum counter_count_direction *direction) |
293 | { |
294 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
295 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
296 | int ret; |
297 | u8 tsr; |
298 | |
299 | ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, id: count->id); |
300 | if (ret) |
301 | return ret; |
302 | |
303 | pm_runtime_get_sync(dev: ch->dev); |
304 | tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR); |
305 | pm_runtime_put(dev: ch->dev); |
306 | |
307 | *direction = (tsr & RZ_MTU3_TSR_TCFD) ? |
308 | COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD; |
309 | mutex_unlock(lock: &priv->lock); |
310 | |
311 | return 0; |
312 | } |
313 | |
314 | static int rz_mtu3_count_ceiling_read(struct counter_device *counter, |
315 | struct counter_count *count, |
316 | u64 *ceiling) |
317 | { |
318 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
319 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
320 | const size_t ch_id = rz_mtu3_get_hw_ch(id: count->id); |
321 | int ret; |
322 | |
323 | ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, id: count->id); |
324 | if (ret) |
325 | return ret; |
326 | |
327 | switch (count->id) { |
328 | case RZ_MTU3_16_BIT_MTU1_CH: |
329 | case RZ_MTU3_16_BIT_MTU2_CH: |
330 | *ceiling = priv->mtu_16bit_max[ch_id]; |
331 | break; |
332 | case RZ_MTU3_32_BIT_CH: |
333 | *ceiling = priv->mtu_32bit_max; |
334 | break; |
335 | default: |
336 | /* should never reach this path */ |
337 | mutex_unlock(lock: &priv->lock); |
338 | return -EINVAL; |
339 | } |
340 | |
341 | mutex_unlock(lock: &priv->lock); |
342 | return 0; |
343 | } |
344 | |
345 | static int rz_mtu3_count_ceiling_write(struct counter_device *counter, |
346 | struct counter_count *count, |
347 | u64 ceiling) |
348 | { |
349 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
350 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
351 | const size_t ch_id = rz_mtu3_get_hw_ch(id: count->id); |
352 | int ret; |
353 | |
354 | ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, id: count->id); |
355 | if (ret) |
356 | return ret; |
357 | |
358 | switch (count->id) { |
359 | case RZ_MTU3_16_BIT_MTU1_CH: |
360 | case RZ_MTU3_16_BIT_MTU2_CH: |
361 | if (ceiling > U16_MAX) { |
362 | mutex_unlock(lock: &priv->lock); |
363 | return -ERANGE; |
364 | } |
365 | priv->mtu_16bit_max[ch_id] = ceiling; |
366 | break; |
367 | case RZ_MTU3_32_BIT_CH: |
368 | if (ceiling > U32_MAX) { |
369 | mutex_unlock(lock: &priv->lock); |
370 | return -ERANGE; |
371 | } |
372 | priv->mtu_32bit_max = ceiling; |
373 | break; |
374 | default: |
375 | /* should never reach this path */ |
376 | mutex_unlock(lock: &priv->lock); |
377 | return -EINVAL; |
378 | } |
379 | |
380 | pm_runtime_get_sync(dev: ch->dev); |
381 | if (count->id == RZ_MTU3_32_BIT_CH) |
382 | rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, val: ceiling); |
383 | else |
384 | rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TGRA, val: ceiling); |
385 | |
386 | rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA); |
387 | pm_runtime_put(dev: ch->dev); |
388 | mutex_unlock(lock: &priv->lock); |
389 | |
390 | return 0; |
391 | } |
392 | |
393 | static void rz_mtu3_32bit_cnt_setting(struct counter_device *counter) |
394 | { |
395 | struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, id: 0); |
396 | struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, id: 1); |
397 | |
398 | /* Phase counting mode 1 is used as default in initialization. */ |
399 | rz_mtu3_8bit_ch_write(ch: ch1, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_PH_CNT_MODE_1); |
400 | |
401 | rz_mtu3_8bit_ch_write(ch: ch1, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA); |
402 | rz_mtu3_8bit_ch_write(ch: ch1, RZ_MTU3_TIOR, RZ_MTU3_TIOR_IC_BOTH); |
403 | |
404 | rz_mtu3_enable(ch: ch1); |
405 | rz_mtu3_enable(ch: ch2); |
406 | } |
407 | |
408 | static void rz_mtu3_16bit_cnt_setting(struct counter_device *counter, int id) |
409 | { |
410 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id); |
411 | |
412 | /* Phase counting mode 1 is used as default in initialization. */ |
413 | rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_PH_CNT_MODE_1); |
414 | |
415 | rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA); |
416 | rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TIOR, RZ_MTU3_TIOR_NO_OUTPUT); |
417 | rz_mtu3_enable(ch); |
418 | } |
419 | |
420 | static int rz_mtu3_initialize_counter(struct counter_device *counter, int id) |
421 | { |
422 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id); |
423 | struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, id: 0); |
424 | struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, id: 1); |
425 | |
426 | switch (id) { |
427 | case RZ_MTU3_16_BIT_MTU1_CH: |
428 | case RZ_MTU3_16_BIT_MTU2_CH: |
429 | if (!rz_mtu3_request_channel(ch)) |
430 | return -EBUSY; |
431 | |
432 | rz_mtu3_16bit_cnt_setting(counter, id); |
433 | return 0; |
434 | case RZ_MTU3_32_BIT_CH: |
435 | /* |
436 | * 32-bit phase counting need MTU1 and MTU2 to create 32-bit |
437 | * cascade counter. |
438 | */ |
439 | if (!rz_mtu3_request_channel(ch: ch1)) |
440 | return -EBUSY; |
441 | |
442 | if (!rz_mtu3_request_channel(ch: ch2)) { |
443 | rz_mtu3_release_channel(ch: ch1); |
444 | return -EBUSY; |
445 | } |
446 | |
447 | rz_mtu3_32bit_cnt_setting(counter); |
448 | return 0; |
449 | default: |
450 | /* should never reach this path */ |
451 | return -EINVAL; |
452 | } |
453 | } |
454 | |
455 | static void rz_mtu3_terminate_counter(struct counter_device *counter, int id) |
456 | { |
457 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id); |
458 | struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, id: 0); |
459 | struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, id: 1); |
460 | |
461 | if (id == RZ_MTU3_32_BIT_CH) { |
462 | rz_mtu3_release_channel(ch: ch2); |
463 | rz_mtu3_release_channel(ch: ch1); |
464 | rz_mtu3_disable(ch: ch2); |
465 | rz_mtu3_disable(ch: ch1); |
466 | } else { |
467 | rz_mtu3_release_channel(ch); |
468 | rz_mtu3_disable(ch); |
469 | } |
470 | } |
471 | |
472 | static int rz_mtu3_count_enable_read(struct counter_device *counter, |
473 | struct counter_count *count, u8 *enable) |
474 | { |
475 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
476 | struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, id: 0); |
477 | struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, id: 1); |
478 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
479 | int ret; |
480 | |
481 | ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, id: count->id); |
482 | if (ret) |
483 | return ret; |
484 | |
485 | if (count->id == RZ_MTU3_32_BIT_CH) |
486 | *enable = rz_mtu3_is_enabled(ch: ch1) && rz_mtu3_is_enabled(ch: ch2); |
487 | else |
488 | *enable = rz_mtu3_is_enabled(ch); |
489 | |
490 | mutex_unlock(lock: &priv->lock); |
491 | |
492 | return 0; |
493 | } |
494 | |
495 | static int rz_mtu3_count_enable_write(struct counter_device *counter, |
496 | struct counter_count *count, u8 enable) |
497 | { |
498 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
499 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
500 | int ret = 0; |
501 | |
502 | if (enable) { |
503 | mutex_lock(&priv->lock); |
504 | pm_runtime_get_sync(dev: ch->dev); |
505 | ret = rz_mtu3_initialize_counter(counter, id: count->id); |
506 | if (ret == 0) |
507 | priv->count_is_enabled[count->id] = true; |
508 | mutex_unlock(lock: &priv->lock); |
509 | } else { |
510 | mutex_lock(&priv->lock); |
511 | rz_mtu3_terminate_counter(counter, id: count->id); |
512 | priv->count_is_enabled[count->id] = false; |
513 | pm_runtime_put(dev: ch->dev); |
514 | mutex_unlock(lock: &priv->lock); |
515 | } |
516 | |
517 | return ret; |
518 | } |
519 | |
520 | static int rz_mtu3_lock_if_ch0_is_enabled(struct rz_mtu3_cnt *const priv) |
521 | { |
522 | mutex_lock(&priv->lock); |
523 | if (priv->ch->is_busy && !(priv->count_is_enabled[RZ_MTU3_16_BIT_MTU1_CH] || |
524 | priv->count_is_enabled[RZ_MTU3_32_BIT_CH])) { |
525 | mutex_unlock(lock: &priv->lock); |
526 | return -EINVAL; |
527 | } |
528 | |
529 | return 0; |
530 | } |
531 | |
532 | static int rz_mtu3_cascade_counts_enable_get(struct counter_device *counter, |
533 | u8 *cascade_enable) |
534 | { |
535 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
536 | unsigned long tmdr; |
537 | int ret; |
538 | |
539 | ret = rz_mtu3_lock_if_ch0_is_enabled(priv); |
540 | if (ret) |
541 | return ret; |
542 | |
543 | pm_runtime_get_sync(dev: priv->ch->dev); |
544 | tmdr = rz_mtu3_shared_reg_read(ch: priv->ch, RZ_MTU3_TMDR3); |
545 | pm_runtime_put(dev: priv->ch->dev); |
546 | *cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr); |
547 | mutex_unlock(lock: &priv->lock); |
548 | |
549 | return 0; |
550 | } |
551 | |
552 | static int rz_mtu3_cascade_counts_enable_set(struct counter_device *counter, |
553 | u8 cascade_enable) |
554 | { |
555 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
556 | int ret; |
557 | |
558 | ret = rz_mtu3_lock_if_ch0_is_enabled(priv); |
559 | if (ret) |
560 | return ret; |
561 | |
562 | pm_runtime_get_sync(dev: priv->ch->dev); |
563 | rz_mtu3_shared_reg_update_bit(ch: priv->ch, RZ_MTU3_TMDR3, |
564 | RZ_MTU3_TMDR3_LWA, val: cascade_enable); |
565 | pm_runtime_put(dev: priv->ch->dev); |
566 | mutex_unlock(lock: &priv->lock); |
567 | |
568 | return 0; |
569 | } |
570 | |
571 | static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *counter, |
572 | u32 *ext_input_phase_clock_select) |
573 | { |
574 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
575 | unsigned long tmdr; |
576 | int ret; |
577 | |
578 | ret = rz_mtu3_lock_if_ch0_is_enabled(priv); |
579 | if (ret) |
580 | return ret; |
581 | |
582 | pm_runtime_get_sync(dev: priv->ch->dev); |
583 | tmdr = rz_mtu3_shared_reg_read(ch: priv->ch, RZ_MTU3_TMDR3); |
584 | pm_runtime_put(dev: priv->ch->dev); |
585 | *ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr); |
586 | mutex_unlock(lock: &priv->lock); |
587 | |
588 | return 0; |
589 | } |
590 | |
591 | static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *counter, |
592 | u32 ext_input_phase_clock_select) |
593 | { |
594 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
595 | int ret; |
596 | |
597 | ret = rz_mtu3_lock_if_ch0_is_enabled(priv); |
598 | if (ret) |
599 | return ret; |
600 | |
601 | pm_runtime_get_sync(dev: priv->ch->dev); |
602 | rz_mtu3_shared_reg_update_bit(ch: priv->ch, RZ_MTU3_TMDR3, |
603 | RZ_MTU3_TMDR3_PHCKSEL, |
604 | val: ext_input_phase_clock_select); |
605 | pm_runtime_put(dev: priv->ch->dev); |
606 | mutex_unlock(lock: &priv->lock); |
607 | |
608 | return 0; |
609 | } |
610 | |
611 | static struct counter_comp rz_mtu3_count_ext[] = { |
612 | COUNTER_COMP_DIRECTION(rz_mtu3_count_direction_read), |
613 | COUNTER_COMP_ENABLE(rz_mtu3_count_enable_read, |
614 | rz_mtu3_count_enable_write), |
615 | COUNTER_COMP_CEILING(rz_mtu3_count_ceiling_read, |
616 | rz_mtu3_count_ceiling_write), |
617 | }; |
618 | |
619 | static const enum counter_synapse_action rz_mtu3_synapse_actions[] = { |
620 | COUNTER_SYNAPSE_ACTION_BOTH_EDGES, |
621 | COUNTER_SYNAPSE_ACTION_RISING_EDGE, |
622 | COUNTER_SYNAPSE_ACTION_NONE, |
623 | }; |
624 | |
625 | static int rz_mtu3_action_read(struct counter_device *counter, |
626 | struct counter_count *count, |
627 | struct counter_synapse *synapse, |
628 | enum counter_synapse_action *action) |
629 | { |
630 | const bool is_signal_ab = (synapse->signal->id == SIGNAL_A_ID) || |
631 | (synapse->signal->id == SIGNAL_B_ID); |
632 | struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id: count->id); |
633 | struct rz_mtu3_cnt *const priv = counter_priv(counter); |
634 | enum counter_function function; |
635 | bool mtclkc_mtclkd; |
636 | unsigned long tmdr; |
637 | int ret; |
638 | |
639 | ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, id: count->id); |
640 | if (ret) |
641 | return ret; |
642 | |
643 | ret = rz_mtu3_count_function_read_helper(ch, priv, function: &function); |
644 | if (ret) { |
645 | mutex_unlock(lock: &priv->lock); |
646 | return ret; |
647 | } |
648 | |
649 | /* Default action mode */ |
650 | *action = COUNTER_SYNAPSE_ACTION_NONE; |
651 | |
652 | if (count->id != RZ_MTU3_16_BIT_MTU1_CH) { |
653 | tmdr = rz_mtu3_shared_reg_read(ch: priv->ch, RZ_MTU3_TMDR3); |
654 | mtclkc_mtclkd = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr); |
655 | if ((mtclkc_mtclkd && is_signal_ab) || |
656 | (!mtclkc_mtclkd && !is_signal_ab)) { |
657 | mutex_unlock(lock: &priv->lock); |
658 | return 0; |
659 | } |
660 | } |
661 | |
662 | switch (function) { |
663 | case COUNTER_FUNCTION_PULSE_DIRECTION: |
664 | /* |
665 | * Rising edges on signal A (signal C) updates the respective |
666 | * count. The input level of signal B (signal D) determines |
667 | * direction. |
668 | */ |
669 | if (synapse->signal->id == SIGNAL_A_ID || |
670 | synapse->signal->id == SIGNAL_C_ID) |
671 | *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; |
672 | break; |
673 | case COUNTER_FUNCTION_QUADRATURE_X2_B: |
674 | /* |
675 | * Any state transition on quadrature pair signal B (signal D) |
676 | * updates the respective count. |
677 | */ |
678 | if (synapse->signal->id == SIGNAL_B_ID || |
679 | synapse->signal->id == SIGNAL_D_ID) |
680 | *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; |
681 | break; |
682 | case COUNTER_FUNCTION_QUADRATURE_X4: |
683 | /* counts up/down on both edges of A (C) and B (D) signal */ |
684 | *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; |
685 | break; |
686 | default: |
687 | /* should never reach this path */ |
688 | mutex_unlock(lock: &priv->lock); |
689 | return -EINVAL; |
690 | } |
691 | |
692 | mutex_unlock(lock: &priv->lock); |
693 | |
694 | return 0; |
695 | } |
696 | |
697 | static const struct counter_ops rz_mtu3_cnt_ops = { |
698 | .count_read = rz_mtu3_count_read, |
699 | .count_write = rz_mtu3_count_write, |
700 | .function_read = rz_mtu3_count_function_read, |
701 | .function_write = rz_mtu3_count_function_write, |
702 | .action_read = rz_mtu3_action_read, |
703 | }; |
704 | |
705 | #define RZ_MTU3_PHASE_SIGNAL(_id, _name) { \ |
706 | .id = (_id), \ |
707 | .name = (_name), \ |
708 | } |
709 | |
710 | static struct counter_signal rz_mtu3_signals[] = { |
711 | RZ_MTU3_PHASE_SIGNAL(SIGNAL_A_ID, "MTU1 MTCLKA" ), |
712 | RZ_MTU3_PHASE_SIGNAL(SIGNAL_B_ID, "MTU1 MTCLKB" ), |
713 | RZ_MTU3_PHASE_SIGNAL(SIGNAL_C_ID, "MTU2 MTCLKC" ), |
714 | RZ_MTU3_PHASE_SIGNAL(SIGNAL_D_ID, "MTU2 MTCLKD" ), |
715 | }; |
716 | |
717 | static struct counter_synapse rz_mtu3_mtu1_count_synapses[] = { |
718 | { |
719 | .actions_list = rz_mtu3_synapse_actions, |
720 | .num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions), |
721 | .signal = rz_mtu3_signals, |
722 | }, |
723 | { |
724 | .actions_list = rz_mtu3_synapse_actions, |
725 | .num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions), |
726 | .signal = rz_mtu3_signals + 1, |
727 | } |
728 | }; |
729 | |
730 | static struct counter_synapse rz_mtu3_mtu2_count_synapses[] = { |
731 | { |
732 | .actions_list = rz_mtu3_synapse_actions, |
733 | .num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions), |
734 | .signal = rz_mtu3_signals, |
735 | }, |
736 | { |
737 | .actions_list = rz_mtu3_synapse_actions, |
738 | .num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions), |
739 | .signal = rz_mtu3_signals + 1, |
740 | }, |
741 | { |
742 | .actions_list = rz_mtu3_synapse_actions, |
743 | .num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions), |
744 | .signal = rz_mtu3_signals + 2, |
745 | }, |
746 | { |
747 | .actions_list = rz_mtu3_synapse_actions, |
748 | .num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions), |
749 | .signal = rz_mtu3_signals + 3, |
750 | } |
751 | }; |
752 | |
753 | static struct counter_count rz_mtu3_counts[] = { |
754 | { |
755 | .id = RZ_MTU3_16_BIT_MTU1_CH, |
756 | .name = "Channel 1 Count" , |
757 | .functions_list = rz_mtu3_count_functions, |
758 | .num_functions = ARRAY_SIZE(rz_mtu3_count_functions), |
759 | .synapses = rz_mtu3_mtu1_count_synapses, |
760 | .num_synapses = ARRAY_SIZE(rz_mtu3_mtu1_count_synapses), |
761 | .ext = rz_mtu3_count_ext, |
762 | .num_ext = ARRAY_SIZE(rz_mtu3_count_ext), |
763 | }, |
764 | { |
765 | .id = RZ_MTU3_16_BIT_MTU2_CH, |
766 | .name = "Channel 2 Count" , |
767 | .functions_list = rz_mtu3_count_functions, |
768 | .num_functions = ARRAY_SIZE(rz_mtu3_count_functions), |
769 | .synapses = rz_mtu3_mtu2_count_synapses, |
770 | .num_synapses = ARRAY_SIZE(rz_mtu3_mtu2_count_synapses), |
771 | .ext = rz_mtu3_count_ext, |
772 | .num_ext = ARRAY_SIZE(rz_mtu3_count_ext), |
773 | }, |
774 | { |
775 | .id = RZ_MTU3_32_BIT_CH, |
776 | .name = "Channel 1 and 2 (cascaded) Count" , |
777 | .functions_list = rz_mtu3_count_functions, |
778 | .num_functions = ARRAY_SIZE(rz_mtu3_count_functions), |
779 | .synapses = rz_mtu3_mtu2_count_synapses, |
780 | .num_synapses = ARRAY_SIZE(rz_mtu3_mtu2_count_synapses), |
781 | .ext = rz_mtu3_count_ext, |
782 | .num_ext = ARRAY_SIZE(rz_mtu3_count_ext), |
783 | } |
784 | }; |
785 | |
786 | static const char *const rz_mtu3_ext_input_phase_clock_select[] = { |
787 | "MTCLKA-MTCLKB" , |
788 | "MTCLKC-MTCLKD" , |
789 | }; |
790 | |
791 | static DEFINE_COUNTER_ENUM(rz_mtu3_ext_input_phase_clock_select_enum, |
792 | rz_mtu3_ext_input_phase_clock_select); |
793 | |
794 | static struct counter_comp rz_mtu3_device_ext[] = { |
795 | COUNTER_COMP_DEVICE_BOOL("cascade_counts_enable" , |
796 | rz_mtu3_cascade_counts_enable_get, |
797 | rz_mtu3_cascade_counts_enable_set), |
798 | COUNTER_COMP_DEVICE_ENUM("external_input_phase_clock_select" , |
799 | rz_mtu3_ext_input_phase_clock_select_get, |
800 | rz_mtu3_ext_input_phase_clock_select_set, |
801 | rz_mtu3_ext_input_phase_clock_select_enum), |
802 | }; |
803 | |
804 | static int rz_mtu3_cnt_pm_runtime_suspend(struct device *dev) |
805 | { |
806 | struct clk *const clk = dev_get_drvdata(dev); |
807 | |
808 | clk_disable_unprepare(clk); |
809 | |
810 | return 0; |
811 | } |
812 | |
813 | static int rz_mtu3_cnt_pm_runtime_resume(struct device *dev) |
814 | { |
815 | struct clk *const clk = dev_get_drvdata(dev); |
816 | |
817 | clk_prepare_enable(clk); |
818 | |
819 | return 0; |
820 | } |
821 | |
822 | static DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_cnt_pm_ops, |
823 | rz_mtu3_cnt_pm_runtime_suspend, |
824 | rz_mtu3_cnt_pm_runtime_resume, NULL); |
825 | |
826 | static void rz_mtu3_cnt_pm_disable(void *data) |
827 | { |
828 | struct device *dev = data; |
829 | |
830 | pm_runtime_disable(dev); |
831 | pm_runtime_set_suspended(dev); |
832 | } |
833 | |
834 | static int rz_mtu3_cnt_probe(struct platform_device *pdev) |
835 | { |
836 | struct rz_mtu3 *ddata = dev_get_drvdata(dev: pdev->dev.parent); |
837 | struct device *dev = &pdev->dev; |
838 | struct counter_device *counter; |
839 | struct rz_mtu3_channel *ch; |
840 | struct rz_mtu3_cnt *priv; |
841 | unsigned int i; |
842 | int ret; |
843 | |
844 | counter = devm_counter_alloc(dev, sizeof_priv: sizeof(*priv)); |
845 | if (!counter) |
846 | return -ENOMEM; |
847 | |
848 | priv = counter_priv(counter); |
849 | priv->clk = ddata->clk; |
850 | priv->mtu_32bit_max = U32_MAX; |
851 | priv->ch = &ddata->channels[RZ_MTU3_CHAN_1]; |
852 | ch = &priv->ch[0]; |
853 | for (i = 0; i < RZ_MTU3_MAX_HW_CNTR_CHANNELS; i++) { |
854 | ch->dev = dev; |
855 | priv->mtu_16bit_max[i] = U16_MAX; |
856 | ch++; |
857 | } |
858 | |
859 | mutex_init(&priv->lock); |
860 | platform_set_drvdata(pdev, data: priv->clk); |
861 | clk_prepare_enable(clk: priv->clk); |
862 | pm_runtime_set_active(dev: &pdev->dev); |
863 | pm_runtime_enable(dev: &pdev->dev); |
864 | ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_cnt_pm_disable, dev); |
865 | if (ret < 0) |
866 | goto disable_clock; |
867 | |
868 | counter->name = dev_name(dev); |
869 | counter->parent = dev; |
870 | counter->ops = &rz_mtu3_cnt_ops; |
871 | counter->counts = rz_mtu3_counts; |
872 | counter->num_counts = ARRAY_SIZE(rz_mtu3_counts); |
873 | counter->signals = rz_mtu3_signals; |
874 | counter->num_signals = ARRAY_SIZE(rz_mtu3_signals); |
875 | counter->ext = rz_mtu3_device_ext; |
876 | counter->num_ext = ARRAY_SIZE(rz_mtu3_device_ext); |
877 | |
878 | /* Register Counter device */ |
879 | ret = devm_counter_add(dev, counter); |
880 | if (ret < 0) { |
881 | dev_err_probe(dev, err: ret, fmt: "Failed to add counter\n" ); |
882 | goto disable_clock; |
883 | } |
884 | |
885 | return 0; |
886 | |
887 | disable_clock: |
888 | clk_disable_unprepare(clk: priv->clk); |
889 | |
890 | return ret; |
891 | } |
892 | |
893 | static struct platform_driver rz_mtu3_cnt_driver = { |
894 | .probe = rz_mtu3_cnt_probe, |
895 | .driver = { |
896 | .name = "rz-mtu3-counter" , |
897 | .pm = pm_ptr(&rz_mtu3_cnt_pm_ops), |
898 | }, |
899 | }; |
900 | module_platform_driver(rz_mtu3_cnt_driver); |
901 | |
902 | MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>" ); |
903 | MODULE_ALIAS("platform:rz-mtu3-counter" ); |
904 | MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a counter driver" ); |
905 | MODULE_LICENSE("GPL" ); |
906 | MODULE_IMPORT_NS(COUNTER); |
907 | |