1 /*
2  * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
3  * Copyright (c) 2022 TOKITA Hiroshi <tokita.hiroshi@gmail.com>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT gd_gd32_timer
9 
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/clock_control.h>
12 #include <zephyr/drivers/clock_control/gd32.h>
13 #include <zephyr/drivers/counter.h>
14 #include <zephyr/drivers/reset.h>
15 #include <zephyr/irq.h>
16 #include <zephyr/logging/log.h>
17 #include <zephyr/sys/atomic.h>
18 
19 #include <gd32_timer.h>
20 
21 LOG_MODULE_REGISTER(counter_gd32_timer);
22 
23 #define TIMER_INT_CH(ch)  (TIMER_INT_CH0 << ch)
24 #define TIMER_FLAG_CH(ch) (TIMER_FLAG_CH0 << ch)
25 #define TIMER_INT_ALL	  (0xFFu)
26 
27 struct counter_gd32_ch_data {
28 	counter_alarm_callback_t callback;
29 	void *user_data;
30 };
31 
32 struct counter_gd32_data {
33 	counter_top_callback_t top_cb;
34 	void *top_user_data;
35 	uint32_t guard_period;
36 	atomic_t cc_int_pending;
37 	uint32_t freq;
38 	struct counter_gd32_ch_data alarm[];
39 };
40 
41 struct counter_gd32_config {
42 	struct counter_config_info counter_info;
43 	uint32_t reg;
44 	uint16_t clkid;
45 	struct reset_dt_spec reset;
46 	uint16_t prescaler;
47 	void (*irq_config)(const struct device *dev);
48 	void (*set_irq_pending)(void);
49 	uint32_t (*get_irq_pending)(void);
50 };
51 
get_autoreload_value(const struct device * dev)52 static uint32_t get_autoreload_value(const struct device *dev)
53 {
54 	const struct counter_gd32_config *config = dev->config;
55 
56 	return TIMER_CAR(config->reg);
57 }
58 
set_autoreload_value(const struct device * dev,uint32_t value)59 static void set_autoreload_value(const struct device *dev, uint32_t value)
60 {
61 	const struct counter_gd32_config *config = dev->config;
62 
63 	TIMER_CAR(config->reg) = value;
64 }
65 
get_counter(const struct device * dev)66 static uint32_t get_counter(const struct device *dev)
67 {
68 	const struct counter_gd32_config *config = dev->config;
69 
70 	return TIMER_CNT(config->reg);
71 }
72 
set_counter(const struct device * dev,uint32_t value)73 static void set_counter(const struct device *dev, uint32_t value)
74 {
75 	const struct counter_gd32_config *config = dev->config;
76 
77 	TIMER_CNT(config->reg) = value;
78 }
79 
set_software_event_gen(const struct device * dev,uint8_t evt)80 static void set_software_event_gen(const struct device *dev, uint8_t evt)
81 {
82 	const struct counter_gd32_config *config = dev->config;
83 
84 	TIMER_SWEVG(config->reg) |= evt;
85 }
86 
set_prescaler(const struct device * dev,uint16_t prescaler)87 static void set_prescaler(const struct device *dev, uint16_t prescaler)
88 {
89 	const struct counter_gd32_config *config = dev->config;
90 
91 	TIMER_PSC(config->reg) = prescaler;
92 }
93 
set_compare_value(const struct device * dev,uint16_t chan,uint32_t compare_value)94 static void set_compare_value(const struct device *dev, uint16_t chan,
95 			      uint32_t compare_value)
96 {
97 	const struct counter_gd32_config *config = dev->config;
98 
99 	switch (chan) {
100 	case 0:
101 		TIMER_CH0CV(config->reg) = compare_value;
102 		break;
103 	case 1:
104 		TIMER_CH1CV(config->reg) = compare_value;
105 		break;
106 	case 2:
107 		TIMER_CH2CV(config->reg) = compare_value;
108 		break;
109 	case 3:
110 		TIMER_CH3CV(config->reg) = compare_value;
111 		break;
112 	}
113 }
114 
interrupt_enable(const struct device * dev,uint32_t interrupt)115 static void interrupt_enable(const struct device *dev, uint32_t interrupt)
116 {
117 	const struct counter_gd32_config *config = dev->config;
118 
119 	TIMER_DMAINTEN(config->reg) |= interrupt;
120 }
121 
interrupt_disable(const struct device * dev,uint32_t interrupt)122 static void interrupt_disable(const struct device *dev, uint32_t interrupt)
123 {
124 	const struct counter_gd32_config *config = dev->config;
125 
126 	TIMER_DMAINTEN(config->reg) &= ~interrupt;
127 }
128 
interrupt_flag_get(const struct device * dev,uint32_t interrupt)129 static uint32_t interrupt_flag_get(const struct device *dev, uint32_t interrupt)
130 {
131 	const struct counter_gd32_config *config = dev->config;
132 
133 	return (TIMER_DMAINTEN(config->reg) & TIMER_INTF(config->reg) &
134 		interrupt);
135 }
136 
interrupt_flag_clear(const struct device * dev,uint32_t interrupt)137 static void interrupt_flag_clear(const struct device *dev, uint32_t interrupt)
138 {
139 	const struct counter_gd32_config *config = dev->config;
140 
141 	TIMER_INTF(config->reg) &= ~interrupt;
142 }
143 
counter_gd32_timer_start(const struct device * dev)144 static int counter_gd32_timer_start(const struct device *dev)
145 {
146 	const struct counter_gd32_config *config = dev->config;
147 
148 	TIMER_CTL0(config->reg) |= (uint32_t)TIMER_CTL0_CEN;
149 
150 	return 0;
151 }
152 
counter_gd32_timer_stop(const struct device * dev)153 static int counter_gd32_timer_stop(const struct device *dev)
154 {
155 	const struct counter_gd32_config *config = dev->config;
156 
157 	TIMER_CTL0(config->reg) &= ~(uint32_t)TIMER_CTL0_CEN;
158 
159 	return 0;
160 }
161 
counter_gd32_timer_get_value(const struct device * dev,uint32_t * ticks)162 static int counter_gd32_timer_get_value(const struct device *dev,
163 					uint32_t *ticks)
164 {
165 	*ticks = get_counter(dev);
166 
167 	return 0;
168 }
169 
counter_gd32_timer_get_top_value(const struct device * dev)170 static uint32_t counter_gd32_timer_get_top_value(const struct device *dev)
171 {
172 	return get_autoreload_value(dev);
173 }
174 
ticks_add(uint32_t val1,uint32_t val2,uint32_t top)175 static uint32_t ticks_add(uint32_t val1, uint32_t val2, uint32_t top)
176 {
177 	uint32_t to_top;
178 
179 	if (likely(IS_BIT_MASK(top))) {
180 		return (val1 + val2) & top;
181 	}
182 
183 	to_top = top - val1;
184 
185 	return (val2 <= to_top) ? val1 + val2 : val2 - to_top;
186 }
187 
ticks_sub(uint32_t val,uint32_t old,uint32_t top)188 static uint32_t ticks_sub(uint32_t val, uint32_t old, uint32_t top)
189 {
190 	if (likely(IS_BIT_MASK(top))) {
191 		return (val - old) & top;
192 	}
193 
194 	/* if top is not 2^n-1 */
195 	return (val >= old) ? (val - old) : val + top + 1 - old;
196 }
197 
set_cc_int_pending(const struct device * dev,uint8_t chan)198 static void set_cc_int_pending(const struct device *dev, uint8_t chan)
199 {
200 	const struct counter_gd32_config *config = dev->config;
201 	struct counter_gd32_data *data = dev->data;
202 
203 	atomic_or(&data->cc_int_pending, TIMER_INT_CH(chan));
204 	config->set_irq_pending();
205 }
206 
set_cc(const struct device * dev,uint8_t chan,uint32_t val,uint32_t flags)207 static int set_cc(const struct device *dev, uint8_t chan, uint32_t val,
208 		  uint32_t flags)
209 {
210 	const struct counter_gd32_config *config = dev->config;
211 	struct counter_gd32_data *data = dev->data;
212 
213 	__ASSERT_NO_MSG(data->guard_period <
214 			counter_gd32_timer_get_top_value(dev));
215 	bool absolute = flags & COUNTER_ALARM_CFG_ABSOLUTE;
216 	uint32_t top = counter_gd32_timer_get_top_value(dev);
217 	uint32_t now, diff, max_rel_val;
218 	bool irq_on_late;
219 	int err = 0;
220 
221 	ARG_UNUSED(config);
222 	__ASSERT(!(TIMER_DMAINTEN(config->reg) & TIMER_INT_CH(chan)),
223 		 "Expected that CC interrupt is disabled.");
224 
225 	/* First take care of a risk of an event coming from CC being set to
226 	 * next tick. Reconfigure CC to future (now tick is the furthest
227 	 * future).
228 	 */
229 	now = get_counter(dev);
230 	set_compare_value(dev, chan, now);
231 	interrupt_flag_clear(dev, TIMER_FLAG_CH(chan));
232 
233 	if (absolute) {
234 		max_rel_val = top - data->guard_period;
235 		irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
236 	} else {
237 		/* If relative value is smaller than half of the counter range
238 		 * it is assumed that there is a risk of setting value too late
239 		 * and late detection algorithm must be applied. When late
240 		 * setting is detected, interrupt shall be triggered for
241 		 * immediate expiration of the timer. Detection is performed
242 		 * by limiting relative distance between CC and counter.
243 		 *
244 		 * Note that half of counter range is an arbitrary value.
245 		 */
246 		irq_on_late = val < (top / 2);
247 		/* limit max to detect short relative being set too late. */
248 		max_rel_val = irq_on_late ? top / 2 : top;
249 		val = ticks_add(now, val, top);
250 	}
251 
252 	set_compare_value(dev, chan, val);
253 
254 	/* decrement value to detect also case when val == get_counter(dev).
255 	 * Otherwise, condition would need to include comparing diff against 0.
256 	 */
257 	diff = ticks_sub(val - 1, get_counter(dev), top);
258 	if (diff > max_rel_val) {
259 		if (absolute) {
260 			err = -ETIME;
261 		}
262 
263 		/* Interrupt is triggered always for relative alarm and
264 		 * for absolute depending on the flag.
265 		 */
266 		if (irq_on_late) {
267 			set_cc_int_pending(dev, chan);
268 		} else {
269 			data->alarm[chan].callback = NULL;
270 		}
271 	} else {
272 		interrupt_enable(dev, TIMER_INT_CH(chan));
273 	}
274 
275 	return err;
276 }
277 
278 static int
counter_gd32_timer_set_alarm(const struct device * dev,uint8_t chan,const struct counter_alarm_cfg * alarm_cfg)279 counter_gd32_timer_set_alarm(const struct device *dev, uint8_t chan,
280 			     const struct counter_alarm_cfg *alarm_cfg)
281 {
282 	struct counter_gd32_data *data = dev->data;
283 	struct counter_gd32_ch_data *chdata = &data->alarm[chan];
284 
285 	if (alarm_cfg->ticks > counter_gd32_timer_get_top_value(dev)) {
286 		return -EINVAL;
287 	}
288 
289 	if (chdata->callback) {
290 		return -EBUSY;
291 	}
292 
293 	chdata->callback = alarm_cfg->callback;
294 	chdata->user_data = alarm_cfg->user_data;
295 
296 	return set_cc(dev, chan, alarm_cfg->ticks, alarm_cfg->flags);
297 }
298 
counter_gd32_timer_cancel_alarm(const struct device * dev,uint8_t chan)299 static int counter_gd32_timer_cancel_alarm(const struct device *dev,
300 					   uint8_t chan)
301 {
302 	struct counter_gd32_data *data = dev->data;
303 
304 	interrupt_disable(dev, TIMER_INT_CH(chan));
305 	data->alarm[chan].callback = NULL;
306 
307 	return 0;
308 }
309 
counter_gd32_timer_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)310 static int counter_gd32_timer_set_top_value(const struct device *dev,
311 					    const struct counter_top_cfg *cfg)
312 {
313 	const struct counter_gd32_config *config = dev->config;
314 	struct counter_gd32_data *data = dev->data;
315 	int err = 0;
316 
317 	for (uint32_t i = 0; i < config->counter_info.channels; i++) {
318 		/* Overflow can be changed only when all alarms are
319 		 * disables.
320 		 */
321 		if (data->alarm[i].callback) {
322 			return -EBUSY;
323 		}
324 	}
325 
326 	interrupt_disable(dev, TIMER_INT_UP);
327 	set_autoreload_value(dev, cfg->ticks);
328 	interrupt_flag_clear(dev, TIMER_INT_FLAG_UP);
329 
330 	data->top_cb = cfg->callback;
331 	data->top_user_data = cfg->user_data;
332 
333 	if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
334 		set_counter(dev, 0);
335 	} else if (get_counter(dev) >= cfg->ticks) {
336 		err = -ETIME;
337 		if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) {
338 			set_counter(dev, 0);
339 		}
340 	}
341 
342 	if (cfg->callback) {
343 		interrupt_enable(dev, TIMER_INT_UP);
344 	}
345 
346 	return err;
347 }
348 
counter_gd32_timer_get_pending_int(const struct device * dev)349 static uint32_t counter_gd32_timer_get_pending_int(const struct device *dev)
350 {
351 	const struct counter_gd32_config *cfg = dev->config;
352 
353 	return cfg->get_irq_pending();
354 }
355 
counter_gd32_timer_get_freq(const struct device * dev)356 static uint32_t counter_gd32_timer_get_freq(const struct device *dev)
357 {
358 	struct counter_gd32_data *data = dev->data;
359 
360 	return data->freq;
361 }
362 
counter_gd32_timer_get_guard_period(const struct device * dev,uint32_t flags)363 static uint32_t counter_gd32_timer_get_guard_period(const struct device *dev,
364 						    uint32_t flags)
365 {
366 	struct counter_gd32_data *data = dev->data;
367 
368 	return data->guard_period;
369 }
370 
counter_gd32_timer_set_guard_period(const struct device * dev,uint32_t guard,uint32_t flags)371 static int counter_gd32_timer_set_guard_period(const struct device *dev,
372 					       uint32_t guard, uint32_t flags)
373 {
374 	struct counter_gd32_data *data = dev->data;
375 
376 	__ASSERT_NO_MSG(guard < counter_gd32_timer_get_top_value(dev));
377 
378 	data->guard_period = guard;
379 	return 0;
380 }
381 
top_irq_handle(const struct device * dev)382 static void top_irq_handle(const struct device *dev)
383 {
384 	struct counter_gd32_data *data = dev->data;
385 	counter_top_callback_t cb = data->top_cb;
386 
387 	if (interrupt_flag_get(dev, TIMER_INT_FLAG_UP) != 0) {
388 		interrupt_flag_clear(dev, TIMER_INT_FLAG_UP);
389 		__ASSERT(cb != NULL, "top event enabled - expecting callback");
390 		cb(dev, data->top_user_data);
391 	}
392 }
393 
alarm_irq_handle(const struct device * dev,uint32_t chan)394 static void alarm_irq_handle(const struct device *dev, uint32_t chan)
395 {
396 	struct counter_gd32_data *data = dev->data;
397 	struct counter_gd32_ch_data *alarm = &data->alarm[chan];
398 	counter_alarm_callback_t cb;
399 	bool hw_irq_pending = !!(interrupt_flag_get(dev, TIMER_FLAG_CH(chan)));
400 	bool sw_irq_pending = data->cc_int_pending & TIMER_INT_CH(chan);
401 
402 	if (hw_irq_pending || sw_irq_pending) {
403 		atomic_and(&data->cc_int_pending, ~TIMER_INT_CH(chan));
404 		interrupt_disable(dev, TIMER_INT_CH(chan));
405 		interrupt_flag_clear(dev, TIMER_FLAG_CH(chan));
406 
407 		cb = alarm->callback;
408 		alarm->callback = NULL;
409 
410 		if (cb) {
411 			cb(dev, chan, get_counter(dev), alarm->user_data);
412 		}
413 	}
414 }
415 
irq_handler(const struct device * dev)416 static void irq_handler(const struct device *dev)
417 {
418 	const struct counter_gd32_config *cfg = dev->config;
419 
420 	top_irq_handle(dev);
421 
422 	for (uint32_t i = 0; i < cfg->counter_info.channels; i++) {
423 		alarm_irq_handle(dev, i);
424 	}
425 }
426 
counter_gd32_timer_init(const struct device * dev)427 static int counter_gd32_timer_init(const struct device *dev)
428 {
429 	const struct counter_gd32_config *cfg = dev->config;
430 	struct counter_gd32_data *data = dev->data;
431 	uint32_t pclk;
432 
433 	clock_control_on(GD32_CLOCK_CONTROLLER,
434 			 (clock_control_subsys_t)&cfg->clkid);
435 	clock_control_get_rate(GD32_CLOCK_CONTROLLER,
436 			       (clock_control_subsys_t)&cfg->clkid, &pclk);
437 
438 	data->freq = pclk / (cfg->prescaler + 1);
439 
440 	interrupt_disable(dev, TIMER_INT_ALL);
441 	reset_line_toggle_dt(&cfg->reset);
442 
443 	cfg->irq_config(dev);
444 	set_prescaler(dev, cfg->prescaler);
445 	set_autoreload_value(dev, cfg->counter_info.max_top_value);
446 	set_software_event_gen(dev, TIMER_SWEVG_UPG);
447 
448 	return 0;
449 }
450 
451 static const struct counter_driver_api counter_api = {
452 	.start = counter_gd32_timer_start,
453 	.stop = counter_gd32_timer_stop,
454 	.get_value = counter_gd32_timer_get_value,
455 	.set_alarm = counter_gd32_timer_set_alarm,
456 	.cancel_alarm = counter_gd32_timer_cancel_alarm,
457 	.set_top_value = counter_gd32_timer_set_top_value,
458 	.get_pending_int = counter_gd32_timer_get_pending_int,
459 	.get_top_value = counter_gd32_timer_get_top_value,
460 	.get_guard_period = counter_gd32_timer_get_guard_period,
461 	.set_guard_period = counter_gd32_timer_set_guard_period,
462 	.get_freq = counter_gd32_timer_get_freq,
463 };
464 
465 #define TIMER_IRQ_CONFIG(n)                                                    \
466 	static void irq_config_##n(const struct device *dev)                   \
467 	{                                                                      \
468 		IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, global, irq),               \
469 			    DT_INST_IRQ_BY_NAME(n, global, priority),          \
470 			    irq_handler, DEVICE_DT_INST_GET(n), 0);            \
471 		irq_enable(DT_INST_IRQ_BY_NAME(n, global, irq));               \
472 	}                                                                      \
473 	static void set_irq_pending_##n(void)                                  \
474 	{                                                                      \
475 		(NVIC_SetPendingIRQ(DT_INST_IRQ_BY_NAME(n, global, irq)));     \
476 	}                                                                      \
477 	static uint32_t get_irq_pending_##n(void)                              \
478 	{                                                                      \
479 		return NVIC_GetPendingIRQ(                                     \
480 			DT_INST_IRQ_BY_NAME(n, global, irq));                  \
481 	}
482 
483 #define TIMER_IRQ_CONFIG_ADVANCED(n)                                           \
484 	static void irq_config_##n(const struct device *dev)                   \
485 	{                                                                      \
486 		IRQ_CONNECT((DT_INST_IRQ_BY_NAME(n, up, irq)),                 \
487 			    (DT_INST_IRQ_BY_NAME(n, up, priority)),            \
488 			    irq_handler, (DEVICE_DT_INST_GET(n)), 0);          \
489 		irq_enable((DT_INST_IRQ_BY_NAME(n, up, irq)));                 \
490 		IRQ_CONNECT((DT_INST_IRQ_BY_NAME(n, cc, irq)),                 \
491 			    (DT_INST_IRQ_BY_NAME(n, cc, priority)),            \
492 			    irq_handler, (DEVICE_DT_INST_GET(n)), 0);          \
493 		irq_enable((DT_INST_IRQ_BY_NAME(n, cc, irq)));                 \
494 	}                                                                      \
495 	static void set_irq_pending_##n(void)                                  \
496 	{                                                                      \
497 		(NVIC_SetPendingIRQ(DT_INST_IRQ_BY_NAME(n, cc, irq)));         \
498 	}                                                                      \
499 	static uint32_t get_irq_pending_##n(void)                              \
500 	{                                                                      \
501 		return NVIC_GetPendingIRQ(DT_INST_IRQ_BY_NAME(n, cc, irq));    \
502 	}
503 
504 #define GD32_TIMER_INIT(n)                                                     \
505 	COND_CODE_1(DT_INST_PROP(n, is_advanced),                              \
506 		    (TIMER_IRQ_CONFIG_ADVANCED(n)), (TIMER_IRQ_CONFIG(n)));    \
507 	static struct counter_gd32_data_##n {                                  \
508 		struct counter_gd32_data data;                                 \
509 		struct counter_gd32_ch_data alarm[DT_INST_PROP(n, channels)];  \
510 	} timer_data_##n = {0};                                                \
511 	static const struct counter_gd32_config timer_config_##n = {           \
512 		.counter_info = {.max_top_value = COND_CODE_1(                 \
513 					 DT_INST_PROP(n, is_32bit),            \
514 					 (UINT32_MAX), (UINT16_MAX)),          \
515 				 .flags = COUNTER_CONFIG_INFO_COUNT_UP,        \
516 				 .freq = 0,                                    \
517 				 .channels = DT_INST_PROP(n, channels)},       \
518 		.reg = DT_INST_REG_ADDR(n),                                    \
519 		.clkid = DT_INST_CLOCKS_CELL(n, id),                           \
520 		.reset = RESET_DT_SPEC_INST_GET(n),                            \
521 		.prescaler = DT_INST_PROP(n, prescaler),                       \
522 		.irq_config = irq_config_##n,                                  \
523 		.set_irq_pending = set_irq_pending_##n,                        \
524 		.get_irq_pending = get_irq_pending_##n,                        \
525 	};                                                                     \
526                                                                                \
527 	DEVICE_DT_INST_DEFINE(n, counter_gd32_timer_init, NULL,                \
528 			      &timer_data_##n, &timer_config_##n,              \
529 			      PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY,      \
530 			      &counter_api);
531 
532 DT_INST_FOREACH_STATUS_OKAY(GD32_TIMER_INIT);
533