1 /*
2 * Copyright (c) 2025 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/timer/system_timer.h>
9 #include <zephyr/irq.h>
10 #include <zephyr/spinlock.h>
11 #include <zephyr/sys_clock.h>
12 #include <soc.h>
13
14 #define DT_DRV_COMPAT renesas_ra_ulpt_timer
15
16 /* Ensure there are exactly two ULPT timer instances
17 * enabled in the device tree.
18 */
19 BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 2,
20 "Requires two instances of the ULPT timer to be enabled.");
21
22 /* ULPT instance 0: Used to announce ticks to the kernel. */
23 #define RA_ULPT_INST0_NODE DT_INST_PARENT(0)
24 #define RA_ULPT_INST0_REG ((R_ULPT0_Type *)DT_REG_ADDR(RA_ULPT_INST0_NODE))
25 #define RA_ULPT_INST0_IRQN DT_IRQ_BY_NAME(RA_ULPT_INST0_NODE, ulpti, irq)
26 #define RA_ULPT_INST0_IRQP 0U
27 #define RA_ULPT_INST0_CHANNEL DT_PROP(RA_ULPT_INST0_NODE, channel)
28
29 /* ULPT instance 1: Used for synchronization with hardware cycle clock. */
30 #define RA_ULPT_INST1_NODE DT_INST_PARENT(1)
31 #define RA_ULPT_INST1_REG ((R_ULPT0_Type *)DT_REG_ADDR(RA_ULPT_INST1_NODE))
32 #define RA_ULPT_INST1_CHANNEL DT_PROP(RA_ULPT_INST1_NODE, channel)
33
34 /* Constants for timer configuration and behavior. */
35 #define RA_ULPT_RELOAD_DELAY 4U
36 #define RA_ULPT_RELOAD_MIN 4U
37 #define RA_ULPT_RELOAD_MAX UINT32_MAX
38
39 #define RA_ULPT_PRV_ULPTCR_STATUS_FLAGS 0xE0U
40 #define RA_ULPT_PRV_ULPTCR_START_TIMER 0xE1U
41
42 /* Macro to get ELC event for ULPT interrupt based on the channel. */
43 #define ELC_EVENT_ULPT_INT(channel) CONCAT(ELC_EVENT_ULPT, channel, _INT)
44
45 /* Calculated constants for timer operation. */
46 #define CYCLE_PER_TICK ((sys_clock_hw_cycles_per_sec() / CONFIG_SYS_CLOCK_TICKS_PER_SEC))
47 #define MAX_TICKS ((k_ticks_t)(RA_ULPT_RELOAD_MAX / CYCLE_PER_TICK) - 1)
48
49 /* Static variables for maintaining timer state. */
50 static uint32_t cycle_announced;
51 static struct k_spinlock lock;
52
ra_ulpt_timer_isr(void)53 static void ra_ulpt_timer_isr(void)
54 {
55 uint32_t cycles;
56 uint32_t dcycles;
57 uint32_t dticks;
58 IRQn_Type irq = R_FSP_CurrentIrqGet();
59
60 /* Clear pending IRQ to prevent re-triggering. */
61 R_BSP_IrqStatusClear(irq);
62
63 if (RA_ULPT_INST0_REG->ULPTCR_b.TUNDF) {
64 k_spinlock_key_t key = k_spin_lock(&lock);
65
66 if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
67 /* Calculate elapsed cycles and ticks. */
68 cycles = ~RA_ULPT_INST1_REG->ULPTCNT;
69 dcycles = cycles - cycle_announced;
70 dticks = dcycles / CYCLE_PER_TICK;
71 cycle_announced += dticks * CYCLE_PER_TICK;
72 } else {
73 /* In tickful mode, announce one tick at a time. */
74 dticks = 1;
75 }
76 /* Clear the underflow flag. */
77 RA_ULPT_INST0_REG->ULPTCR_b.TUNDF = 0;
78 k_spin_unlock(&lock, key);
79
80 /* Announce the elapsed ticks to the kernel. */
81 sys_clock_announce(dticks);
82 }
83 }
84
sys_clock_set_timeout(int32_t ticks,bool idle)85 void sys_clock_set_timeout(int32_t ticks, bool idle)
86 {
87 ARG_UNUSED(idle);
88
89 /* Timeout configuration is unsupported in tickful mode. */
90 if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
91 return;
92 }
93
94 /* No timeout change for K_TICKS_FOREVER or INT32_MAX. */
95 if (ticks == K_TICKS_FOREVER || ticks == INT32_MAX) {
96 return;
97 }
98
99 /* Clamp the ticks value to a valid range. */
100 ticks = CLAMP(ticks - 1, 0, (int32_t)MAX_TICKS);
101
102 /* Calculate the timer delay in cycles. */
103 uint32_t cycles = ~RA_ULPT_INST1_REG->ULPTCNT;
104 uint32_t unannounced = cycles - cycle_announced;
105 uint32_t delay = ticks * CYCLE_PER_TICK;
106
107 /* Adjust delay to align with tick boundaries. */
108 delay += unannounced;
109 delay = DIV_ROUND_UP(delay, CYCLE_PER_TICK) * CYCLE_PER_TICK;
110 delay -= unannounced;
111 delay = MAX(delay, RA_ULPT_RELOAD_MIN + RA_ULPT_RELOAD_DELAY);
112 delay -= RA_ULPT_RELOAD_DELAY;
113
114 /* Update the timer counter. */
115 RA_ULPT_INST0_REG->ULPTCNT = delay - 1U;
116 }
117
sys_clock_elapsed(void)118 uint32_t sys_clock_elapsed(void)
119 {
120 /* Elapsed time calculation is unsupported in tickful mode. */
121 if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
122 return 0;
123 }
124
125 /* Calculate and return the number of elapsed cycles. */
126 uint32_t cycles = ~RA_ULPT_INST1_REG->ULPTCNT - cycle_announced;
127
128 return (cycles / CYCLE_PER_TICK);
129 }
130
sys_clock_cycle_get_32(void)131 uint32_t sys_clock_cycle_get_32(void)
132 {
133 return ~RA_ULPT_INST1_REG->ULPTCNT;
134 }
135
sys_clock_driver_init(void)136 static int sys_clock_driver_init(void)
137 {
138 /* Power on ULPT modules. */
139 R_BSP_MODULE_START(FSP_IP_ULPT, RA_ULPT_INST0_CHANNEL);
140 R_BSP_MODULE_START(FSP_IP_ULPT, RA_ULPT_INST1_CHANNEL);
141
142 /* Stop timers and reset control registers. */
143 RA_ULPT_INST0_REG->ULPTCR = 0U;
144 RA_ULPT_INST1_REG->ULPTCR = 0U;
145
146 /* Wait for timers to stop. */
147 FSP_HARDWARE_REGISTER_WAIT(0U, RA_ULPT_INST0_REG->ULPTCR_b.TCSTF);
148 FSP_HARDWARE_REGISTER_WAIT(0U, RA_ULPT_INST1_REG->ULPTCR_b.TCSTF);
149
150 /* Clear configuration registers before setup. */
151 RA_ULPT_INST0_REG->ULPTMR2 = 0U;
152 RA_ULPT_INST1_REG->ULPTMR2 = 0U;
153
154 /* Configure timer instance 0. */
155 RA_ULPT_INST0_REG->ULPTMR1 = 0U;
156 RA_ULPT_INST0_REG->ULPTMR2 = 0U;
157 RA_ULPT_INST0_REG->ULPTMR3 = 0U;
158 RA_ULPT_INST0_REG->ULPTIOC = 0U;
159 RA_ULPT_INST0_REG->ULPTISR = 0U;
160 RA_ULPT_INST0_REG->ULPTCMSR = 0U;
161
162 /* Configure timer instance 1. */
163 RA_ULPT_INST1_REG->ULPTMR1 = 0U;
164 RA_ULPT_INST1_REG->ULPTMR2 = 0U;
165 RA_ULPT_INST1_REG->ULPTMR3 = 0U;
166 RA_ULPT_INST1_REG->ULPTIOC = 0U;
167 RA_ULPT_INST1_REG->ULPTISR = 0U;
168 RA_ULPT_INST1_REG->ULPTCMSR = 0U;
169
170 /* Initialize timer counters. */
171 RA_ULPT_INST0_REG->ULPTCNT = CYCLE_PER_TICK - 1U;
172 RA_ULPT_INST1_REG->ULPTCNT = RA_ULPT_RELOAD_MAX;
173
174 /* Set up interrupts for timer instance 0. */
175 R_ICU->IELSR[RA_ULPT_INST0_IRQN] = ELC_EVENT_ULPT_INT(RA_ULPT_INST0_CHANNEL);
176 IRQ_CONNECT(RA_ULPT_INST0_IRQN, RA_ULPT_INST0_IRQP, ra_ulpt_timer_isr, NULL, 0);
177 irq_enable(RA_ULPT_INST0_IRQN);
178
179 /* Start both timers. */
180 RA_ULPT_INST0_REG->ULPTCR = RA_ULPT_PRV_ULPTCR_START_TIMER;
181 RA_ULPT_INST1_REG->ULPTCR = RA_ULPT_PRV_ULPTCR_START_TIMER;
182
183 /* Wait for timers to start completely. */
184 FSP_HARDWARE_REGISTER_WAIT(RA_ULPT_INST0_REG->ULPTCR_b.TSTART,
185 RA_ULPT_INST0_REG->ULPTCR_b.TCSTF);
186 FSP_HARDWARE_REGISTER_WAIT(RA_ULPT_INST1_REG->ULPTCR_b.TSTART,
187 RA_ULPT_INST1_REG->ULPTCR_b.TCSTF);
188 cycle_announced = 0U;
189
190 return 0;
191 }
192
193 /* Initialize the system timer driver during pre-kernel stage 2. */
194 SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
195