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 DECLARE_KEEP_PAGER(timer_desc); 46 47 static enum itr_return timer_itr_cb(struct itr_handler *h __unused) 48 { 49 callout_service_cb(); 50 51 return ITRR_HANDLED; 52 } 53 DECLARE_KEEP_PAGER(timer_itr_cb); 54 55 void timer_init_callout_service(struct itr_chip *itr_chip, size_t itr_number) 56 { 57 timer_itr = (struct itr_handler){ 58 .it = itr_number, 59 .flags = ITRF_TRIGGER_LEVEL, 60 .handler = timer_itr_cb, 61 }; 62 63 if (interrupt_add_handler_with_chip(itr_chip, &timer_itr)) 64 panic(); 65 66 interrupt_enable(timer_itr.chip, timer_itr.it); 67 callout_service_init(&timer_desc); 68 } 69