xref: /optee_os/core/arch/arm/kernel/generic_timer.c (revision 5b7afacfba964a2f4a41be916b4a76c675bfa72f)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2024, Linaro Limited
4  */
5 
6 #include <arm.h>
7 #include <kernel/callout.h>
8 #include <kernel/timer.h>
9 
10 static void timer_disable(const struct callout_timer_desc *desc __unused)
11 {
12 	write_cntps_ctl(0);
13 }
14 
15 static void timer_set_next(const struct callout_timer_desc *desc __unused,
16 			   uint64_t ctrval)
17 {
18 	write_cntps_cval(ctrval);
19 	write_cntps_ctl(1);
20 }
21 
22 static uint64_t
23 timer_ms_to_ticks(const struct callout_timer_desc *desc __unused,
24 		  uint32_t timeout_ms)
25 {
26 	uint64_t freq = read_cntfrq();
27 
28 	return (freq * timeout_ms) / 1000;
29 }
30 
31 static uint64_t timer_now(const struct callout_timer_desc *desc __unused)
32 {
33 	return barrier_read_counter_timer();
34 }
35 
36 static struct itr_handler timer_itr __nex_bss;
37 static const struct callout_timer_desc timer_desc
38 __relrodata_unpaged("timer_desc") = {
39 	.disable_timeout = timer_disable,
40 	.set_next_timeout = timer_set_next,
41 	.ms_to_ticks = timer_ms_to_ticks,
42 	.get_now = timer_now,
43 	.is_per_cpu = true,
44 };
45 
46 static enum itr_return timer_itr_cb(struct itr_handler *h __unused)
47 {
48 	callout_service_cb();
49 
50 	return ITRR_HANDLED;
51 }
52 
53 void timer_init_callout_service(struct itr_chip *itr_chip, size_t itr_number)
54 {
55 	timer_itr = (struct itr_handler){
56 		.it = itr_number,
57 		.flags = ITRF_TRIGGER_LEVEL,
58 		.handler = timer_itr_cb,
59 	};
60 
61 	if (interrupt_add_handler_with_chip(itr_chip, &timer_itr))
62 		panic();
63 
64 	interrupt_enable(timer_itr.chip, timer_itr.it);
65 	callout_service_init(&timer_desc);
66 }
67