arch_timer.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <timer.h> 4 #include <delay.h> 5 #include <cpu/power/spr.h> 6 7 /* Refer to hostboot/src/kernel/timemgr.C */ 8 9 /* Time base frequency is 512 MHz so 512 ticks per usec */ 10 #define TB_TICKS_PER_USEC 512 11 12 __weak void init_timer(void) { /* do nothing */ } 13 14 static struct monotonic_counter { 15 int initialized; 16 struct mono_time time; 17 uint64_t last_value; 18 } mono_counter; 19 20 void timer_monotonic_get(struct mono_time *mt) 21 { 22 uint64_t current_tick; 23 uint64_t usecs_elapsed; 24 25 if (!mono_counter.initialized) { 26 mono_counter.last_value = read_spr(SPR_TB); 27 mono_counter.initialized = 1; 28 } 29 30 current_tick = read_spr(SPR_TB); 31 usecs_elapsed = (current_tick - mono_counter.last_value) / TB_TICKS_PER_USEC; 32 33 /* Update current time and tick values only if a full tick occurred. */ 34 if (usecs_elapsed) { 35 mono_time_add_usecs(&mono_counter.time, usecs_elapsed); 36 mono_counter.last_value = current_tick; 37 } 38 39 /* Save result. */ 40 *mt = mono_counter.time; 41 }