1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2013
4  * David Feng <fenghua@phytium.com.cn>
5  */
6 
7 #include <common.h>
8 #include <command.h>
9 #include <asm/system.h>
10 
11 DECLARE_GLOBAL_DATA_PTR;
12 
13 /*
14  * Generic timer implementation of get_tbclk()
15  */
16 unsigned long get_tbclk(void)
17 {
18 	unsigned long cntfrq;
19 	asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
20 	return cntfrq;
21 }
22 
23 /*
24  * Generic timer implementation of timer_read_counter()
25  */
26 unsigned long timer_read_counter(void)
27 {
28 	unsigned long cntpct;
29 #ifdef CONFIG_SYS_FSL_ERRATUM_A008585
30 	/* This erratum number needs to be confirmed to match ARM document */
31 	unsigned long temp;
32 #endif
33 	isb();
34 	asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
35 #ifdef CONFIG_SYS_FSL_ERRATUM_A008585
36 	asm volatile("mrs %0, cntpct_el0" : "=r" (temp));
37 	while (temp != cntpct) {
38 		asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
39 		asm volatile("mrs %0, cntpct_el0" : "=r" (temp));
40 	}
41 #endif
42 	return cntpct;
43 }
44 
45 uint64_t get_ticks(void)
46 {
47 	unsigned long ticks = timer_read_counter();
48 
49 	gd->arch.tbl = ticks;
50 
51 	return ticks;
52 }
53 
54 unsigned long usec2ticks(unsigned long usec)
55 {
56 	ulong ticks;
57 	if (usec < 1000)
58 		ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;
59 	else
60 		ticks = ((usec / 10) * (get_tbclk() / 100000));
61 
62 	return ticks;
63 }
64 
65 ulong timer_get_boot_us(void)
66 {
67 	u64 val = get_ticks() * 1000000;
68 
69 	return val / get_tbclk();
70 }
71