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