/ src / arch / ppc64 / arch_timer.c
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  }