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