1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/irq.h>
10 #if defined(CONFIG_CLOCK_CONTROL_NRF)
11 #include <zephyr/drivers/clock_control/nrf_clock_control.h>
12 #endif
13 #include <zephyr/drivers/pinctrl.h>
14 #include <zephyr/drivers/timer/system_timer.h>
15 #include <zephyr/drivers/timer/nrf_grtc_timer.h>
16 #include <nrfx_grtc.h>
17 #include <zephyr/sys/math_extras.h>
18 
19 #define GRTC_NODE DT_NODELABEL(grtc)
20 #define HFCLK_NODE DT_PHANDLE_BY_NAME(GRTC_NODE, clocks, hfclock)
21 #define LFCLK_NODE DT_PHANDLE_BY_NAME(GRTC_NODE, clocks, lfclock)
22 
23 /* Ensure that GRTC properties in devicetree are defined correctly. */
24 #if !DT_NODE_HAS_PROP(GRTC_NODE, owned_channels)
25 #error GRTC owned-channels DT property is not defined
26 #endif
27 #define OWNED_CHANNELS_MASK       NRFX_CONFIG_MASK_DT(GRTC_NODE, owned_channels)
28 #define CHILD_OWNED_CHANNELS_MASK NRFX_CONFIG_MASK_DT(GRTC_NODE, child_owned_channels)
29 #if ((OWNED_CHANNELS_MASK | CHILD_OWNED_CHANNELS_MASK) != OWNED_CHANNELS_MASK)
30 #error GRTC child-owned-channels DT property must be a subset of owned-channels
31 #endif
32 
33 #define CHAN_COUNT     NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS
34 #define EXT_CHAN_COUNT (CHAN_COUNT - 1)
35 
36 #ifndef GRTC_SYSCOUNTERL_VALUE_Msk
37 #define GRTC_SYSCOUNTERL_VALUE_Msk GRTC_SYSCOUNTER_SYSCOUNTERL_VALUE_Msk
38 #endif
39 
40 #ifndef GRTC_SYSCOUNTERH_VALUE_Msk
41 #define GRTC_SYSCOUNTERH_VALUE_Msk GRTC_SYSCOUNTER_SYSCOUNTERH_VALUE_Msk
42 #endif
43 
44 #define MAX_CC_LATCH_WAIT_TIME_US 77
45 
46 #define CYC_PER_TICK                                                                               \
47 	((uint64_t)sys_clock_hw_cycles_per_sec() / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)
48 
49 #define COUNTER_SPAN (GRTC_SYSCOUNTERL_VALUE_Msk | ((uint64_t)GRTC_SYSCOUNTERH_VALUE_Msk << 32))
50 #define MAX_TICKS                                                                                  \
51 	(((COUNTER_SPAN / CYC_PER_TICK) > INT_MAX) ? INT_MAX : (COUNTER_SPAN / CYC_PER_TICK))
52 
53 #define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK)
54 
55 #define LFCLK_FREQUENCY_HZ DT_PROP(LFCLK_NODE, clock_frequency)
56 
57 #if defined(CONFIG_TEST)
58 const int32_t z_sys_timer_irq_for_test = DT_IRQN(GRTC_NODE);
59 #endif
60 
61 static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context);
62 
63 static struct k_spinlock lock;
64 static uint64_t last_count; /* Time (SYSCOUNTER value) @last sys_clock_announce() */
65 static atomic_t int_mask;
66 static uint8_t ext_channels_allocated;
67 static nrfx_grtc_channel_t system_clock_channel_data = {
68 	.handler = sys_clock_timeout_handler,
69 	.p_context = NULL,
70 	.channel = (uint8_t)-1,
71 };
72 
73 #define IS_CHANNEL_ALLOWED_ASSERT(chan)                                                            \
74 	__ASSERT_NO_MSG((NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK & (1UL << (chan))) &&           \
75 			((chan) != system_clock_channel_data.channel))
76 
counter_sub(uint64_t a,uint64_t b)77 static inline uint64_t counter_sub(uint64_t a, uint64_t b)
78 {
79 	return (a - b);
80 }
81 
counter(void)82 static inline uint64_t counter(void)
83 {
84 	uint64_t now;
85 	nrfx_grtc_syscounter_get(&now);
86 	return now;
87 }
88 
get_comparator(uint32_t chan,uint64_t * cc)89 static inline int get_comparator(uint32_t chan, uint64_t *cc)
90 {
91 	nrfx_err_t result;
92 
93 	result = nrfx_grtc_syscounter_cc_value_read(chan, cc);
94 	if (result != NRFX_SUCCESS) {
95 		if (result != NRFX_ERROR_INVALID_PARAM) {
96 			return -EAGAIN;
97 		}
98 		return -EPERM;
99 	}
100 	return 0;
101 }
102 
103 /*
104  * Program a new callback <value> microseconds in the future
105  */
system_timeout_set_relative(uint64_t value)106 static void system_timeout_set_relative(uint64_t value)
107 {
108 	if (value <= NRF_GRTC_SYSCOUNTER_CCADD_MASK) {
109 		nrfx_grtc_syscounter_cc_relative_set(&system_clock_channel_data, value, true,
110 						     NRFX_GRTC_CC_RELATIVE_SYSCOUNTER);
111 	} else {
112 		nrfx_grtc_syscounter_cc_absolute_set(&system_clock_channel_data, value + counter(),
113 						     true);
114 	}
115 }
116 
117 /*
118  * Program a new callback in the absolute time given by <value>
119  */
system_timeout_set_abs(uint64_t value)120 static void system_timeout_set_abs(uint64_t value)
121 {
122 	nrfx_grtc_syscounter_cc_absolute_set(&system_clock_channel_data, value,
123 					     true);
124 }
125 
compare_int_lock(int32_t chan)126 static bool compare_int_lock(int32_t chan)
127 {
128 	atomic_val_t prev = atomic_and(&int_mask, ~BIT(chan));
129 
130 	nrfx_grtc_syscounter_cc_int_disable(chan);
131 
132 	return prev & BIT(chan);
133 }
134 
compare_int_unlock(int32_t chan,bool key)135 static void compare_int_unlock(int32_t chan, bool key)
136 {
137 	if (key) {
138 		atomic_or(&int_mask, BIT(chan));
139 		nrfx_grtc_syscounter_cc_int_enable(chan);
140 	}
141 }
142 
sys_clock_timeout_handler(int32_t id,uint64_t cc_val,void * p_context)143 static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context)
144 {
145 	ARG_UNUSED(id);
146 	ARG_UNUSED(p_context);
147 	uint64_t dticks;
148 	uint64_t now = counter();
149 
150 	if (unlikely(now < cc_val)) {
151 		return;
152 	}
153 
154 	dticks = counter_sub(cc_val, last_count) / CYC_PER_TICK;
155 
156 	last_count += dticks * CYC_PER_TICK;
157 
158 	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
159 		/* protection is not needed because we are in the GRTC interrupt
160 		 * so it won't get preempted by the interrupt.
161 		 */
162 		system_timeout_set_abs(last_count + CYC_PER_TICK);
163 	}
164 
165 	sys_clock_announce((int32_t)dticks);
166 }
167 
z_nrf_grtc_timer_chan_alloc(void)168 int32_t z_nrf_grtc_timer_chan_alloc(void)
169 {
170 	uint8_t chan;
171 	nrfx_err_t err_code;
172 
173 	/* Prevent allocating all available channels - one must be left for system purposes. */
174 	if (ext_channels_allocated >= EXT_CHAN_COUNT) {
175 		return -ENOMEM;
176 	}
177 	err_code = nrfx_grtc_channel_alloc(&chan);
178 	if (err_code != NRFX_SUCCESS) {
179 		return -ENOMEM;
180 	}
181 	ext_channels_allocated++;
182 	return (int32_t)chan;
183 }
184 
z_nrf_grtc_timer_chan_free(int32_t chan)185 void z_nrf_grtc_timer_chan_free(int32_t chan)
186 {
187 	IS_CHANNEL_ALLOWED_ASSERT(chan);
188 	nrfx_err_t err_code = nrfx_grtc_channel_free(chan);
189 
190 	if (err_code == NRFX_SUCCESS) {
191 		ext_channels_allocated--;
192 	}
193 }
194 
z_nrf_grtc_timer_compare_evt_check(int32_t chan)195 bool z_nrf_grtc_timer_compare_evt_check(int32_t chan)
196 {
197 	IS_CHANNEL_ALLOWED_ASSERT(chan);
198 
199 	uint32_t event_address = nrfx_grtc_event_compare_address_get(chan);
200 
201 	return *(volatile uint32_t *)event_address != 0;
202 }
203 
z_nrf_grtc_timer_compare_evt_address_get(int32_t chan)204 uint32_t z_nrf_grtc_timer_compare_evt_address_get(int32_t chan)
205 {
206 	IS_CHANNEL_ALLOWED_ASSERT(chan);
207 
208 	return nrfx_grtc_event_compare_address_get(chan);
209 }
210 
z_nrf_grtc_timer_capture_task_address_get(int32_t chan)211 uint32_t z_nrf_grtc_timer_capture_task_address_get(int32_t chan)
212 {
213 	IS_CHANNEL_ALLOWED_ASSERT(chan);
214 
215 	return nrfx_grtc_capture_task_address_get(chan);
216 }
217 
z_nrf_grtc_timer_read(void)218 uint64_t z_nrf_grtc_timer_read(void)
219 {
220 	return counter();
221 }
222 
z_nrf_grtc_timer_compare_int_lock(int32_t chan)223 bool z_nrf_grtc_timer_compare_int_lock(int32_t chan)
224 {
225 	IS_CHANNEL_ALLOWED_ASSERT(chan);
226 
227 	return compare_int_lock(chan);
228 }
229 
z_nrf_grtc_timer_compare_int_unlock(int32_t chan,bool key)230 void z_nrf_grtc_timer_compare_int_unlock(int32_t chan, bool key)
231 {
232 	IS_CHANNEL_ALLOWED_ASSERT(chan);
233 
234 	compare_int_unlock(chan, key);
235 }
236 
z_nrf_grtc_timer_compare_read(int32_t chan,uint64_t * val)237 int z_nrf_grtc_timer_compare_read(int32_t chan, uint64_t *val)
238 {
239 	IS_CHANNEL_ALLOWED_ASSERT(chan);
240 
241 	return get_comparator(chan, val);
242 }
243 
compare_set_nolocks(int32_t chan,uint64_t target_time,z_nrf_grtc_timer_compare_handler_t handler,void * user_data)244 static int compare_set_nolocks(int32_t chan, uint64_t target_time,
245 			       z_nrf_grtc_timer_compare_handler_t handler, void *user_data)
246 {
247 	nrfx_err_t result;
248 
249 	__ASSERT_NO_MSG(target_time < COUNTER_SPAN);
250 	nrfx_grtc_channel_t user_channel_data = {
251 		.handler = handler,
252 		.p_context = user_data,
253 		.channel = chan,
254 	};
255 	result = nrfx_grtc_syscounter_cc_absolute_set(&user_channel_data, target_time, true);
256 	if (result != NRFX_SUCCESS) {
257 		return -EPERM;
258 	}
259 	return 0;
260 }
261 
compare_set(int32_t chan,uint64_t target_time,z_nrf_grtc_timer_compare_handler_t handler,void * user_data)262 static int compare_set(int32_t chan, uint64_t target_time,
263 		       z_nrf_grtc_timer_compare_handler_t handler, void *user_data)
264 {
265 	bool key = compare_int_lock(chan);
266 	int ret = compare_set_nolocks(chan, target_time, handler, user_data);
267 
268 	compare_int_unlock(chan, key);
269 
270 	return ret;
271 }
272 
z_nrf_grtc_timer_set(int32_t chan,uint64_t target_time,z_nrf_grtc_timer_compare_handler_t handler,void * user_data)273 int z_nrf_grtc_timer_set(int32_t chan, uint64_t target_time,
274 			 z_nrf_grtc_timer_compare_handler_t handler, void *user_data)
275 {
276 	IS_CHANNEL_ALLOWED_ASSERT(chan);
277 
278 	return compare_set(chan, target_time, (nrfx_grtc_cc_handler_t)handler, user_data);
279 }
280 
z_nrf_grtc_timer_abort(int32_t chan)281 void z_nrf_grtc_timer_abort(int32_t chan)
282 {
283 	IS_CHANNEL_ALLOWED_ASSERT(chan);
284 
285 	bool key = compare_int_lock(chan);
286 	(void)nrfx_grtc_syscounter_cc_disable(chan);
287 	compare_int_unlock(chan, key);
288 }
289 
z_nrf_grtc_timer_get_ticks(k_timeout_t t)290 uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t)
291 {
292 	uint64_t curr_time;
293 	int64_t curr_tick;
294 	int64_t result;
295 	int64_t abs_ticks;
296 	int64_t grtc_ticks;
297 
298 	curr_time = counter();
299 	curr_tick = sys_clock_tick_get();
300 
301 	grtc_ticks = t.ticks * CYC_PER_TICK;
302 	abs_ticks = Z_TICK_ABS(t.ticks);
303 	if (Z_IS_TIMEOUT_RELATIVE(t)) {
304 		return (grtc_ticks > (int64_t)COUNTER_SPAN) ?
305 			-EINVAL : (curr_time + grtc_ticks);
306 	}
307 
308 	/* absolute timeout */
309 	result = (abs_ticks - curr_tick) * CYC_PER_TICK;
310 
311 	if (result > (int64_t)COUNTER_SPAN) {
312 		return -EINVAL;
313 	}
314 
315 	return curr_time + result;
316 }
317 
z_nrf_grtc_timer_capture_prepare(int32_t chan)318 int z_nrf_grtc_timer_capture_prepare(int32_t chan)
319 {
320 	nrfx_grtc_channel_t user_channel_data = {
321 		.handler = NULL,
322 		.p_context = NULL,
323 		.channel = chan,
324 	};
325 	nrfx_err_t result;
326 
327 	IS_CHANNEL_ALLOWED_ASSERT(chan);
328 
329 	/* Set the CC value to mark channel as not triggered and also to enable it
330 	 * (makes CCEN=1). COUNTER_SPAN is used so as not to fire an event unnecessarily
331 	 * - it can be assumed that such a large value will never be reached.
332 	 */
333 	result = nrfx_grtc_syscounter_cc_absolute_set(&user_channel_data, COUNTER_SPAN, false);
334 
335 	if (result != NRFX_SUCCESS) {
336 		return -EPERM;
337 	}
338 
339 	return 0;
340 }
341 
z_nrf_grtc_timer_capture_read(int32_t chan,uint64_t * captured_time)342 int z_nrf_grtc_timer_capture_read(int32_t chan, uint64_t *captured_time)
343 {
344 	/* TODO: The implementation should probably go to nrfx_grtc and this
345 	 *       should be just a wrapper for some nrfx_grtc_syscounter_capture_read.
346 	 */
347 
348 	uint64_t capt_time;
349 	nrfx_err_t result;
350 
351 	IS_CHANNEL_ALLOWED_ASSERT(chan);
352 
353 	/* TODO: Use `nrfy_grtc_sys_counter_enable_check` when available (NRFX-2480) */
354 	if (NRF_GRTC->CC[chan].CCEN == GRTC_CC_CCEN_ACTIVE_Enable) {
355 		/* If the channel is enabled (.CCEN), it means that there was no capture
356 		 * triggering event.
357 		 */
358 		return -EBUSY;
359 	}
360 	result = nrfx_grtc_syscounter_cc_value_read(chan, &capt_time);
361 	if (result != NRFX_SUCCESS) {
362 		return -EPERM;
363 	}
364 
365 	__ASSERT_NO_MSG(capt_time < COUNTER_SPAN);
366 
367 	*captured_time = capt_time;
368 
369 	return 0;
370 }
371 
372 #if defined(CONFIG_POWEROFF) && defined(CONFIG_NRF_GRTC_START_SYSCOUNTER)
z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)373 int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)
374 {
375 	nrfx_err_t err_code;
376 	static uint8_t systemoff_channel;
377 	uint64_t now = counter();
378 	nrfx_grtc_sleep_config_t sleep_cfg;
379 	/* Minimum time that ensures valid execution of system-off procedure. */
380 	uint32_t minimum_latency_us;
381 	uint32_t chan;
382 	int ret;
383 
384 	nrfx_grtc_sleep_configuration_get(&sleep_cfg);
385 	minimum_latency_us = (sleep_cfg.waketime + sleep_cfg.timeout) *
386 		USEC_PER_SEC / LFCLK_FREQUENCY_HZ +
387 		CONFIG_NRF_GRTC_SYSCOUNTER_SLEEP_MINIMUM_LATENCY;
388 	sleep_cfg.auto_mode = false;
389 	nrfx_grtc_sleep_configure(&sleep_cfg);
390 
391 	if (minimum_latency_us > wake_time_us) {
392 		return -EINVAL;
393 	}
394 
395 	k_spinlock_key_t key = k_spin_lock(&lock);
396 
397 	err_code = nrfx_grtc_channel_alloc(&systemoff_channel);
398 	if (err_code != NRFX_SUCCESS) {
399 		k_spin_unlock(&lock, key);
400 		return -ENOMEM;
401 	}
402 	(void)nrfx_grtc_syscounter_cc_int_disable(systemoff_channel);
403 	ret = compare_set(systemoff_channel,
404 			  now + wake_time_us * sys_clock_hw_cycles_per_sec() / USEC_PER_SEC, NULL,
405 			  NULL);
406 	if (ret < 0) {
407 		k_spin_unlock(&lock, key);
408 		return ret;
409 	}
410 
411 	for (uint32_t grtc_chan_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
412 	     grtc_chan_mask > 0; grtc_chan_mask &= ~BIT(chan)) {
413 		/* Clear all GRTC channels except the systemoff_channel. */
414 		chan = u32_count_trailing_zeros(grtc_chan_mask);
415 		if (chan != systemoff_channel) {
416 			nrfx_grtc_syscounter_cc_disable(chan);
417 		}
418 	}
419 
420 	/* Make sure that wake_time_us was not triggered yet. */
421 	if (nrfx_grtc_syscounter_compare_event_check(systemoff_channel)) {
422 		k_spin_unlock(&lock, key);
423 		return -EINVAL;
424 	}
425 
426 	/* This mechanism ensures that stored CC value is latched. */
427 	uint32_t wait_time =
428 		nrfy_grtc_timeout_get(NRF_GRTC) * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 32768 +
429 		MAX_CC_LATCH_WAIT_TIME_US;
430 	k_busy_wait(wait_time);
431 #if NRF_GRTC_HAS_CLKSEL
432 #if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)
433 	nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFLPRC);
434 #elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lfxo))
435 	nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFXO);
436 #endif
437 #endif
438 	k_spin_unlock(&lock, key);
439 	return 0;
440 }
441 #endif /* CONFIG_POWEROFF */
442 
sys_clock_cycle_get_32(void)443 uint32_t sys_clock_cycle_get_32(void)
444 {
445 	k_spinlock_key_t key = k_spin_lock(&lock);
446 	uint32_t ret = (uint32_t)counter();
447 
448 	k_spin_unlock(&lock, key);
449 	return ret;
450 }
451 
sys_clock_cycle_get_64(void)452 uint64_t sys_clock_cycle_get_64(void)
453 {
454 	k_spinlock_key_t key = k_spin_lock(&lock);
455 	uint64_t ret = counter();
456 
457 	k_spin_unlock(&lock, key);
458 	return ret;
459 }
460 
sys_clock_elapsed(void)461 uint32_t sys_clock_elapsed(void)
462 {
463 	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
464 		return 0;
465 	}
466 
467 	return (uint32_t)(counter_sub(counter(), last_count) / CYC_PER_TICK);
468 }
469 
sys_clock_driver_init(void)470 static int sys_clock_driver_init(void)
471 {
472 	nrfx_err_t err_code;
473 
474 	IRQ_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), nrfx_isr,
475 		    nrfx_grtc_irq_handler, 0);
476 
477 	err_code = nrfx_grtc_init(0);
478 	if (err_code != NRFX_SUCCESS) {
479 		return -EPERM;
480 	}
481 
482 #if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER)
483 	err_code = nrfx_grtc_syscounter_start(true, &system_clock_channel_data.channel);
484 	if (err_code != NRFX_SUCCESS) {
485 		return err_code == NRFX_ERROR_NO_MEM ? -ENOMEM : -EPERM;
486 	}
487 #else
488 	err_code = nrfx_grtc_channel_alloc(&system_clock_channel_data.channel);
489 	if (err_code != NRFX_SUCCESS) {
490 		return -ENOMEM;
491 	}
492 #endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */
493 
494 	int_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
495 	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
496 		system_timeout_set_relative(CYC_PER_TICK);
497 	}
498 
499 #if defined(CONFIG_CLOCK_CONTROL_NRF)
500 	static const enum nrf_lfclk_start_mode mode =
501 		IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)
502 			? CLOCK_CONTROL_NRF_LF_START_NOWAIT
503 			: (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)
504 				   ? CLOCK_CONTROL_NRF_LF_START_AVAILABLE
505 				   : CLOCK_CONTROL_NRF_LF_START_STABLE);
506 
507 	z_nrf_clock_control_lf_on(mode);
508 #endif
509 
510 #if defined(CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) && NRF_GRTC_HAS_CLKSEL
511 #if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)
512 	/* Switch to LFPRC as the low-frequency clock source. */
513 	nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFLPRC);
514 #elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lfxo))
515 	/* Switch to LFXO as the low-frequency clock source. */
516 	nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFXO);
517 #endif
518 #endif
519 
520 #if defined(CONFIG_NRF_GRTC_ALWAYS_ON)
521 	nrfx_grtc_active_request_set(true);
522 #endif
523 
524 #if DT_PROP(GRTC_NODE, clkout_32k)
525 	nrfy_grtc_clkout_set(NRF_GRTC, NRF_GRTC_CLKOUT_32K, true);
526 #endif
527 
528 #if DT_NODE_HAS_PROP(GRTC_NODE, clkout_fast_frequency_hz)
529 #if !DT_NODE_HAS_PROP(HFCLK_NODE, clock_frequency)
530 #error "hfclock reference required when fast clock output is enabled."
531 #endif
532 
533 #if DT_PROP(GRTC_NODE, clkout_fast_frequency_hz) > (DT_PROP(HFCLK_NODE, clock_frequency) / 2)
534 #error "Invalid frequency value for fast clock output."
535 #endif
536 	uint32_t base_frequency = DT_PROP(HFCLK_NODE, clock_frequency);
537 	uint32_t requested_frequency = DT_PROP(GRTC_NODE, clkout_fast_frequency_hz);
538 	uint32_t grtc_div = base_frequency / (requested_frequency * 2);
539 
540 	nrfy_grtc_clkout_divider_set(NRF_GRTC, (uint8_t)grtc_div);
541 	nrfy_grtc_clkout_set(NRF_GRTC, NRF_GRTC_CLKOUT_FAST, true);
542 #endif
543 
544 #if DT_PROP(GRTC_NODE, clkout_32k) || DT_NODE_HAS_PROP(GRTC_NODE, clkout_fast_frequency_hz)
545 	PINCTRL_DT_DEFINE(GRTC_NODE);
546 	const struct pinctrl_dev_config *pcfg = PINCTRL_DT_DEV_CONFIG_GET(GRTC_NODE);
547 
548 	return pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT);
549 #else
550 	return 0;
551 #endif
552 }
553 
sys_clock_set_timeout(int32_t ticks,bool idle)554 void sys_clock_set_timeout(int32_t ticks, bool idle)
555 {
556 	ARG_UNUSED(idle);
557 
558 	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
559 		return;
560 	}
561 
562 	ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : MIN(MAX_TICKS, MAX(ticks, 0));
563 
564 	uint64_t delta_time = ticks * CYC_PER_TICK;
565 
566 	uint64_t target_time = counter() + delta_time;
567 
568 	/* Rounded down target_time to the tick boundary
569 	 * (but not less than one tick after the last)
570 	 */
571 	target_time = MAX((target_time - last_count)/CYC_PER_TICK, 1)*CYC_PER_TICK + last_count;
572 
573 	system_timeout_set_abs(target_time);
574 }
575 
576 #if defined(CONFIG_NRF_GRTC_TIMER_APP_DEFINED_INIT)
nrf_grtc_timer_clock_driver_init(void)577 int nrf_grtc_timer_clock_driver_init(void)
578 {
579 	return sys_clock_driver_init();
580 }
581 #else
582 SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
583 #endif
584