1 /*
2  * Copyright (c) 2022 Renesas Electronics Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT renesas_smartbond_timer
8 
9 #include <zephyr/drivers/counter.h>
10 #include <zephyr/drivers/clock_control/smartbond_clock_control.h>
11 #include <zephyr/irq.h>
12 #include <zephyr/sys/atomic.h>
13 #include <zephyr/pm/device.h>
14 #include <zephyr/pm/device_runtime.h>
15 #include <zephyr/pm/policy.h>
16 #include <DA1469xAB.h>
17 #include <da1469x_pdc.h>
18 #include <zephyr/logging/log.h>
19 
20 LOG_MODULE_REGISTER(counter_timer, CONFIG_COUNTER_LOG_LEVEL);
21 
22 #define LP_CLK_OSC_RC32K	0
23 #define LP_CLK_OSC_RCX		1
24 #define LP_CLK_OSC_XTAL32K	2
25 
26 #define TIMER_TOP_VALUE		0xFFFFFF
27 
28 #define COUNTER_DT_DEVICE(_idx) DEVICE_DT_GET_OR_NULL(DT_NODELABEL(timer##_idx))
29 
30 #define PDC_XTAL_EN (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(xtal32m)) ? \
31 					MCU_PDC_EN_XTAL : MCU_PDC_EN_NONE)
32 
33 struct counter_smartbond_data {
34 	counter_alarm_callback_t callback;
35 	void *user_data;
36 	uint32_t guard_period;
37 	uint32_t freq;
38 #if defined(CONFIG_PM_DEVICE)
39 	uint8_t pdc_idx;
40 #endif
41 };
42 
43 struct counter_smartbond_ch_data {
44 	counter_alarm_callback_t callback;
45 	void *user_data;
46 };
47 
48 struct counter_smartbond_config {
49 	struct counter_config_info info;
50 	/* Register set for timer */
51 	TIMER2_Type *timer;
52 	uint8_t prescaler;
53 	/* Timer driven by DIVn if 1 or lp_clk if 0 */
54 	uint8_t clock_src_divn;
55 	uint8_t irqn;
56 	void (*irq_config_func)(const struct device *dev);
57 
58 	LOG_INSTANCE_PTR_DECLARE(log);
59 };
60 
61 #if defined(CONFIG_PM_DEVICE)
counter_smartbond_pm_policy_state_lock_get(const struct device * dev)62 static void counter_smartbond_pm_policy_state_lock_get(const struct device *dev)
63 {
64 	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
65 	pm_device_runtime_get(dev);
66 }
67 
counter_smartbond_pm_policy_state_lock_put(const struct device * dev)68 static void counter_smartbond_pm_policy_state_lock_put(const struct device *dev)
69 {
70 	pm_device_runtime_put(dev);
71 	if (pm_policy_state_lock_is_active(PM_STATE_STANDBY, PM_ALL_SUBSTATES)) {
72 		pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
73 	}
74 }
75 
76 /*
77  * Routine to check whether the device is allowed to enter the sleep state or not.
78  * Entering the standby mode should be allowed for TIMER1/2 that are clocked by LP
79  * clock. Although, TIMER1/2 are powered by a distinct power domain,
80  * namely PD_TMR which is always enabled (used to generate the sleep tick count),
81  * the DIVN path which reflects the main crystal, that is XTAL32M, is turned off
82  * during sleep by PDC. It's worth noting that during sleep the clock source of
83  * a timer block will automatically be switched from DIVN to LP and vice versa.
84  */
counter_smartbond_is_sleep_allowed(const struct device * dev)85 static inline bool counter_smartbond_is_sleep_allowed(const struct device *dev)
86 {
87 	const struct counter_smartbond_config *config = dev->config;
88 
89 	return (((dev == COUNTER_DT_DEVICE(1)) ||
90 			 (dev == COUNTER_DT_DEVICE(2))) && !config->clock_src_divn);
91 }
92 
93 /* Get the PDC trigger associated with the requested counter device */
counter_smartbond_pdc_trigger_get(const struct device * dev)94 static uint8_t counter_smartbond_pdc_trigger_get(const struct device *dev)
95 {
96 	const struct counter_smartbond_config *config = dev->config;
97 
98 	switch ((uint32_t)config->timer) {
99 	case (uint32_t)TIMER:
100 		return MCU_PDC_TRIGGER_TIMER;
101 	case (uint32_t)TIMER2:
102 		return MCU_PDC_TRIGGER_TIMER2;
103 	case (uint32_t)TIMER3:
104 		return MCU_PDC_TRIGGER_TIMER3;
105 	case (uint32_t)TIMER4:
106 		return MCU_PDC_TRIGGER_TIMER4;
107 	default:
108 		return 0;
109 	}
110 }
111 
112 /*
113  * Add PDC entry so that the application core, which should be turned off during sleep,
114  * can get notified upon counter events. This routine is called for counter instances
115  * that are powered by PD_TMR and can operate during sleep.
116  */
counter_smartbond_pdc_add(const struct device * dev)117 static void counter_smartbond_pdc_add(const struct device *dev)
118 {
119 	struct counter_smartbond_data *data = dev->data;
120 	uint8_t trigger = counter_smartbond_pdc_trigger_get(dev);
121 
122 	data->pdc_idx = da1469x_pdc_add(trigger, MCU_PDC_MASTER_M33, PDC_XTAL_EN);
123 	__ASSERT_NO_MSG(data->pdc_idx >= 0);
124 
125 	da1469x_pdc_set(data->pdc_idx);
126 	da1469x_pdc_ack(data->pdc_idx);
127 }
128 
counter_smartbond_pdc_del(const struct device * dev)129 static void counter_smartbond_pdc_del(const struct device *dev)
130 {
131 	struct counter_smartbond_data *data = dev->data;
132 
133 	da1469x_pdc_del(data->pdc_idx);
134 }
135 #endif
136 
counter_smartbond_start(const struct device * dev)137 static int counter_smartbond_start(const struct device *dev)
138 {
139 	const struct counter_smartbond_config *config = dev->config;
140 	TIMER2_Type *timer = config->timer;
141 
142 #if defined(CONFIG_PM_DEVICE)
143 	if (!counter_smartbond_is_sleep_allowed(dev)) {
144 		/*
145 		 * Power mode constraints should be applied as long as the device
146 		 * is up and running.
147 		 */
148 		counter_smartbond_pm_policy_state_lock_get(dev);
149 	} else {
150 		counter_smartbond_pdc_add(dev);
151 	}
152 #endif
153 
154 	/* Enable counter in free running mode */
155 	timer->TIMER2_CTRL_REG |= (TIMER2_TIMER2_CTRL_REG_TIM_CLK_EN_Msk |
156 				  TIMER2_TIMER2_CTRL_REG_TIM_EN_Msk |
157 				  TIMER2_TIMER2_CTRL_REG_TIM_FREE_RUN_MODE_EN_Msk);
158 
159 	return 0;
160 }
161 
counter_smartbond_stop(const struct device * dev)162 static int counter_smartbond_stop(const struct device *dev)
163 {
164 	const struct counter_smartbond_config *config = dev->config;
165 	struct counter_smartbond_data *data = dev->data;
166 	TIMER2_Type *timer = config->timer;
167 
168 	/* disable counter */
169 	timer->TIMER2_CTRL_REG &= ~(TIMER2_TIMER2_CTRL_REG_TIM_EN_Msk |
170 				    TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Msk |
171 					TIMER2_TIMER2_CTRL_REG_TIM_CLK_EN_Msk);
172 	data->callback = NULL;
173 
174 #if defined(CONFIG_PM_DEVICE)
175 	if (!counter_smartbond_is_sleep_allowed(dev)) {
176 		counter_smartbond_pm_policy_state_lock_put(dev);
177 	} else {
178 		counter_smartbond_pdc_del(dev);
179 	}
180 #endif
181 
182 	return 0;
183 }
184 
counter_smartbond_get_top_value(const struct device * dev)185 static uint32_t counter_smartbond_get_top_value(const struct device *dev)
186 {
187 	ARG_UNUSED(dev);
188 
189 	return TIMER_TOP_VALUE;
190 }
191 
counter_smartbond_read(const struct device * dev)192 static uint32_t counter_smartbond_read(const struct device *dev)
193 {
194 	const struct counter_smartbond_config *config = dev->config;
195 	TIMER2_Type *timer = config->timer;
196 
197 	return timer->TIMER2_TIMER_VAL_REG;
198 }
199 
counter_smartbond_get_value(const struct device * dev,uint32_t * ticks)200 static int counter_smartbond_get_value(const struct device *dev, uint32_t *ticks)
201 {
202 	*ticks = counter_smartbond_read(dev);
203 
204 	return 0;
205 }
206 
counter_smartbond_set_alarm(const struct device * dev,uint8_t chan,const struct counter_alarm_cfg * alarm_cfg)207 static int counter_smartbond_set_alarm(const struct device *dev, uint8_t chan,
208 				       const struct counter_alarm_cfg *alarm_cfg)
209 {
210 	const struct counter_smartbond_config *config = dev->config;
211 	struct counter_smartbond_data *data = dev->data;
212 	TIMER2_Type *timer = config->timer;
213 	volatile uint32_t *timer_clear_irq_reg = ((TIMER_Type *)timer) == TIMER ?
214 					&((TIMER_Type *)timer)->TIMER_CLEAR_IRQ_REG :
215 					&timer->TIMER2_CLEAR_IRQ_REG;
216 	bool absolute = alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE;
217 	uint32_t flags = alarm_cfg->flags;
218 	uint32_t val = alarm_cfg->ticks;
219 	bool irq_on_late;
220 	int err = 0;
221 	uint32_t max_rel_val;
222 	uint32_t now;
223 	uint32_t diff;
224 
225 	if (chan != 0 || alarm_cfg->ticks > counter_smartbond_get_top_value(dev)) {
226 		return -EINVAL;
227 	}
228 
229 	if (data->callback) {
230 		return -EBUSY;
231 	}
232 
233 	now = counter_smartbond_read(dev);
234 	data->callback = alarm_cfg->callback;
235 	data->user_data = alarm_cfg->user_data;
236 
237 	__ASSERT_NO_MSG(data->guard_period < TIMER_TOP_VALUE);
238 
239 	if (absolute) {
240 		max_rel_val = TIMER_TOP_VALUE - data->guard_period;
241 		irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
242 	} else {
243 		/* If relative value is smaller than half of the counter range
244 		 * it is assumed that there is a risk of setting value too late
245 		 * and late detection algorithm must be applied. When late
246 		 * setting is detected, interrupt shall be triggered for
247 		 * immediate expiration of the timer. Detection is performed
248 		 * by limiting relative distance between CC and counter.
249 		 *
250 		 * Note that half of counter range is an arbitrary value.
251 		 */
252 		irq_on_late = val < (TIMER_TOP_VALUE / 2U);
253 		/* limit max to detect short relative being set too late. */
254 		max_rel_val = irq_on_late ? TIMER_TOP_VALUE / 2U : TIMER_TOP_VALUE;
255 		val = (now + val) & TIMER_TOP_VALUE;
256 	}
257 	timer->TIMER2_RELOAD_REG = val;
258 	*timer_clear_irq_reg = 1;
259 	/* decrement value to detect also case when val == counter_smartbond_read(dev). Otherwise,
260 	 * condition would need to include comparing diff against 0.
261 	 */
262 	diff = ((val - 1U) - counter_smartbond_read(dev)) & TIMER_TOP_VALUE;
263 	if (diff > max_rel_val) {
264 		if (absolute) {
265 			err = -ETIME;
266 		}
267 
268 		/* Interrupt is triggered always for relative alarm and
269 		 * for absolute depending on the flag.
270 		 */
271 		if (irq_on_late) {
272 			NVIC_SetPendingIRQ(config->irqn);
273 		} else {
274 			data->callback = NULL;
275 		}
276 	} else {
277 		if (diff == 0) {
278 			/* RELOAD value could be set just in time for interrupt
279 			 * trigger or too late. In any case time is interrupt
280 			 * should be triggered. No need to enable interrupt
281 			 * on TIMER just make sure interrupt is pending.
282 			 */
283 			NVIC_SetPendingIRQ(config->irqn);
284 		} else {
285 			timer->TIMER2_CTRL_REG |= TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Msk;
286 		}
287 	}
288 
289 	return err;
290 }
291 
counter_smartbond_cancel_alarm(const struct device * dev,uint8_t chan)292 static int counter_smartbond_cancel_alarm(const struct device *dev, uint8_t chan)
293 {
294 	const struct counter_smartbond_config *config = dev->config;
295 	TIMER2_Type *timer = config->timer;
296 	struct counter_smartbond_data *data = dev->data;
297 
298 	ARG_UNUSED(chan);
299 
300 	timer->TIMER2_CTRL_REG &= ~TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Msk;
301 	data->callback = NULL;
302 
303 	return 0;
304 }
305 
counter_smartbond_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)306 static int counter_smartbond_set_top_value(const struct device *dev,
307 					   const struct counter_top_cfg *cfg)
308 {
309 	ARG_UNUSED(dev);
310 
311 	if (cfg->ticks != 0xFFFFFF) {
312 		return -ENOTSUP;
313 	}
314 
315 	return 0;
316 }
317 
counter_smartbond_get_pending_int(const struct device * dev)318 static uint32_t counter_smartbond_get_pending_int(const struct device *dev)
319 {
320 	const struct counter_smartbond_config *config = dev->config;
321 
322 	/* There is no register to check TIMER peripheral to check for interrupt
323 	 * pending, check directly in NVIC.
324 	 */
325 	return NVIC_GetPendingIRQ(config->irqn);
326 }
327 
counter_smartbond_init_timer(const struct device * dev)328 static int counter_smartbond_init_timer(const struct device *dev)
329 {
330 	const struct counter_smartbond_config *cfg = dev->config;
331 	struct counter_smartbond_data *data = dev->data;
332 	TIMER2_Type *timer = cfg->timer;
333 	TIMER_Type *timer0 = ((TIMER_Type *)cfg->timer) == TIMER ? TIMER : NULL;
334 	const struct device *osc_dev;
335 	uint32_t osc_freq;
336 	enum smartbond_clock osc;
337 
338 	if (cfg->clock_src_divn) {
339 		/* Timer clock source is DIVn 32MHz */
340 		timer->TIMER2_CTRL_REG = TIMER2_TIMER2_CTRL_REG_TIM_SYS_CLK_EN_Msk;
341 		data->freq = DT_PROP(DT_NODELABEL(divn_clk), clock_frequency) /
342 			     (cfg->prescaler + 1);
343 	} else {
344 		osc_dev = DEVICE_DT_GET(DT_NODELABEL(osc));
345 		timer->TIMER2_CTRL_REG = 0;
346 		switch ((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
347 			 CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) {
348 		case LP_CLK_OSC_RC32K:
349 			osc = SMARTBOND_CLK_RC32K;
350 			break;
351 		case LP_CLK_OSC_RCX:
352 			osc = SMARTBOND_CLK_RCX;
353 			break;
354 		default:
355 		case LP_CLK_OSC_XTAL32K:
356 			osc = SMARTBOND_CLK_XTAL32K;
357 			break;
358 		}
359 		clock_control_get_rate(osc_dev, (clock_control_subsys_t)osc, &osc_freq);
360 		data->freq = osc_freq / (cfg->prescaler + 1);
361 	}
362 	timer->TIMER2_PRESCALER_REG = cfg->prescaler;
363 	timer->TIMER2_RELOAD_REG = counter_get_max_top_value(dev);
364 	timer->TIMER2_GPIO1_CONF_REG = 0;
365 	timer->TIMER2_GPIO2_CONF_REG = 0;
366 	timer->TIMER2_SHOTWIDTH_REG = 0;
367 	timer->TIMER2_CAPTURE_GPIO1_REG = 0;
368 	timer->TIMER2_CAPTURE_GPIO2_REG = 0;
369 	timer->TIMER2_PWM_FREQ_REG = 0;
370 	timer->TIMER2_PWM_DC_REG = 0;
371 	if (timer0) {
372 		timer0->TIMER_CAPTURE_GPIO3_REG = 0;
373 		timer0->TIMER_CAPTURE_GPIO4_REG = 0;
374 	}
375 
376 	/* config/enable IRQ */
377 	cfg->irq_config_func(dev);
378 
379 #ifdef CONFIG_PM_DEVICE_RUNTIME
380 	/* Make sure device state is marked as suspended */
381 	pm_device_init_suspended(dev);
382 
383 	return pm_device_runtime_enable(dev);
384 #endif
385 
386 	return 0;
387 }
388 
counter_smartbond_get_guard_period(const struct device * dev,uint32_t flags)389 static uint32_t counter_smartbond_get_guard_period(const struct device *dev, uint32_t flags)
390 {
391 	struct counter_smartbond_data *data = dev->data;
392 
393 	ARG_UNUSED(flags);
394 	return data->guard_period;
395 }
396 
counter_smartbond_set_guard_period(const struct device * dev,uint32_t guard,uint32_t flags)397 static int counter_smartbond_set_guard_period(const struct device *dev, uint32_t guard,
398 					      uint32_t flags)
399 {
400 	struct counter_smartbond_data *data = dev->data;
401 
402 	ARG_UNUSED(flags);
403 	__ASSERT_NO_MSG(guard < counter_smartbond_get_top_value(dev));
404 
405 	data->guard_period = guard;
406 
407 	return 0;
408 }
409 
counter_smartbond_get_freq(const struct device * dev)410 static uint32_t counter_smartbond_get_freq(const struct device *dev)
411 {
412 	struct counter_smartbond_data *data = dev->data;
413 
414 	return data->freq;
415 }
416 
417 #if defined(CONFIG_PM_DEVICE)
counter_smartbond_resume(const struct device * dev)418 static void counter_smartbond_resume(const struct device *dev)
419 {
420 	const struct counter_smartbond_config *cfg = dev->config;
421 	TIMER2_Type *timer = cfg->timer;
422 
423 	/*
424 	 * Resume only for block instances that are powered by PD_SYS
425 	 * and so their register contents should reset after sleep.
426 	 */
427 	if (!counter_smartbond_is_sleep_allowed(dev)) {
428 		if (cfg->clock_src_divn) {
429 			timer->TIMER2_CTRL_REG = TIMER2_TIMER2_CTRL_REG_TIM_SYS_CLK_EN_Msk;
430 		} else {
431 			timer->TIMER2_CTRL_REG = 0;
432 		}
433 		timer->TIMER2_PRESCALER_REG = cfg->prescaler;
434 		timer->TIMER2_RELOAD_REG = counter_get_max_top_value(dev);
435 	}
436 }
437 
counter_smartbond_pm_action(const struct device * dev,enum pm_device_action action)438 static int counter_smartbond_pm_action(const struct device *dev, enum pm_device_action action)
439 {
440 	int ret = 0;
441 
442 	switch (action) {
443 	case PM_DEVICE_ACTION_SUSPEND:
444 		break;
445 	case PM_DEVICE_ACTION_RESUME:
446 		counter_smartbond_resume(dev);
447 		break;
448 	default:
449 		ret = -ENOTSUP;
450 	}
451 
452 	return ret;
453 }
454 #endif
455 
456 static DEVICE_API(counter, counter_smartbond_driver_api) = {
457 	.start = counter_smartbond_start,
458 	.stop = counter_smartbond_stop,
459 	.get_value = counter_smartbond_get_value,
460 	.set_alarm = counter_smartbond_set_alarm,
461 	.cancel_alarm = counter_smartbond_cancel_alarm,
462 	.set_top_value = counter_smartbond_set_top_value,
463 	.get_pending_int = counter_smartbond_get_pending_int,
464 	.get_top_value = counter_smartbond_get_top_value,
465 	.get_guard_period = counter_smartbond_get_guard_period,
466 	.set_guard_period = counter_smartbond_set_guard_period,
467 	.get_freq = counter_smartbond_get_freq,
468 };
469 
counter_smartbond_irq_handler(const struct device * dev)470 void counter_smartbond_irq_handler(const struct device *dev)
471 {
472 	const struct counter_smartbond_config *cfg = dev->config;
473 	struct counter_smartbond_data *data = dev->data;
474 	counter_alarm_callback_t alarm_callback = data->callback;
475 	TIMER2_Type *timer = cfg->timer;
476 	/* Timer0 has interrupt clear register in other offset */
477 	__IOM uint32_t *timer_clear_irq_reg = ((TIMER_Type *)timer) == TIMER ?
478 					      &((TIMER_Type *)timer)->TIMER_CLEAR_IRQ_REG :
479 					      &timer->TIMER2_CLEAR_IRQ_REG;
480 
481 	timer->TIMER2_CTRL_REG &= ~TIMER2_TIMER2_CTRL_REG_TIM_IRQ_EN_Msk;
482 	*timer_clear_irq_reg = 1;
483 
484 	if (alarm_callback != NULL) {
485 		data->callback = NULL;
486 		alarm_callback(dev, 0, timer->TIMER2_TIMER_VAL_REG,
487 			       data->user_data);
488 	}
489 }
490 
491 #define TIMERN(idx)              DT_DRV_INST(idx)
492 
493 /** TIMERn instance from DT */
494 #define TIM(idx) ((TIMER2_Type *)DT_REG_ADDR(TIMERN(idx)))
495 
496 #define COUNTER_DEVICE_INIT(idx)						\
497 	BUILD_ASSERT(DT_PROP(TIMERN(idx), prescaler) <= 32 &&			\
498 		     DT_PROP(TIMERN(idx), prescaler) > 0,			\
499 		     "TIMER prescaler out of range (1..32)");			\
500 										\
501 	static struct counter_smartbond_data counter##idx##_data;		\
502 										\
503 	static void counter##idx##_smartbond_irq_config(const struct device *dev)\
504 	{									\
505 		IRQ_CONNECT(DT_IRQN(TIMERN(idx)),				\
506 			    DT_IRQ(TIMERN(idx), priority),			\
507 			    counter_smartbond_irq_handler,			\
508 			    DEVICE_DT_INST_GET(idx),				\
509 			    0);							\
510 		irq_enable(DT_IRQN(TIMERN(idx)));				\
511 	}									\
512 										\
513 	static const struct counter_smartbond_config counter##idx##_config = {	\
514 		.info = {							\
515 			.max_top_value = 0x00FFFFFF,				\
516 			.flags = COUNTER_CONFIG_INFO_COUNT_UP,			\
517 			.channels = 1,						\
518 		},								\
519 		.timer = TIM(idx),						\
520 		.prescaler = DT_PROP(TIMERN(idx), prescaler) - 1,		\
521 		.clock_src_divn = DT_SAME_NODE(DT_PROP(TIMERN(idx), clock_src), \
522 					       DT_NODELABEL(divn_clk)) ? 1 : 0,	\
523 		.irq_config_func = counter##idx##_smartbond_irq_config,		\
524 		.irqn = DT_IRQN(TIMERN(idx)),					\
525 	};									\
526 										\
527 	PM_DEVICE_DT_INST_DEFINE(idx, counter_smartbond_pm_action);	\
528 	DEVICE_DT_INST_DEFINE(idx,						\
529 			      counter_smartbond_init_timer,			\
530 			      PM_DEVICE_DT_INST_GET(idx),	\
531 			      &counter##idx##_data,				\
532 			      &counter##idx##_config,				\
533 			      PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY,	\
534 			      &counter_smartbond_driver_api);
535 
536 DT_INST_FOREACH_STATUS_OKAY(COUNTER_DEVICE_INIT)
537