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