arch_timer.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <arch/lib_helpers.h> 4 #include <commonlib/bsd/gcd.h> 5 #include <timer.h> 6 7 void timer_monotonic_get(struct mono_time *mt) 8 { 9 uint64_t tvalue = raw_read_cntpct_el0(); 10 static uint32_t tfreq, mult; 11 uint32_t div; 12 13 /* 14 * The value from raw_read_cntfrq_el0() could be large enough to 15 * cause overflow when multiplied by USECS_PER_SEC. To prevent this, 16 * both USECS_PER_SEC. and tfreq can be reduced by dividing them by 17 * their GCD. 18 */ 19 if (tfreq == 0) { 20 tfreq = raw_read_cntfrq_el0(); 21 mult = USECS_PER_SEC; 22 div = gcd(tfreq, mult); 23 tfreq /= div; 24 mult /= div; 25 } 26 27 long usecs = (tvalue * mult) / tfreq; 28 mono_time_set_usecs(mt, usecs); 29 }