1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2017-2022 Intel Corporation <www.intel.com>
4  *
5  */
6 
7 #include <common.h>
8 #include <init.h>
9 #include <div64.h>
10 #include <asm/io.h>
11 #include <asm/arch/timer.h>
12 
13 /*
14  * Timer initialization
15  */
timer_init(void)16 int timer_init(void)
17 {
18 #ifdef CONFIG_SPL_BUILD
19 	int enable = 0x3;	/* timer enable + output signal masked */
20 	int loadval = ~0;
21 
22 	/* enable system counter */
23 	writel(enable, SOCFPGA_GTIMER_SEC_ADDRESS);
24 	/* enable processor pysical counter */
25 	asm volatile("msr cntp_ctl_el0, %0" : : "r" (enable));
26 	asm volatile("msr cntp_tval_el0, %0" : : "r" (loadval));
27 #endif
28 	return 0;
29 }
30 
__get_time_stamp(void)31 __always_inline u64 __get_time_stamp(void)
32 {
33 	u64 cntpct;
34 
35 	isb();
36 	asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
37 
38 	return cntpct;
39 }
40 
__usec_to_tick(unsigned long usec)41 __always_inline uint64_t __usec_to_tick(unsigned long usec)
42 {
43 	u64 tick = usec;
44 	u64 cntfrq;
45 
46 	asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
47 	tick *= cntfrq;
48 	do_div(tick, 1000000);
49 
50 	return tick;
51 }
52 
__udelay(unsigned long usec)53 __always_inline void __udelay(unsigned long usec)
54 {
55 	/* get current timestamp */
56 	u64 tmp = __get_time_stamp() + __usec_to_tick(usec);
57 
58 	while (__get_time_stamp() < tmp + 1)	/* loop till event */
59 		;
60 }