]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/xtensa/lib/time.c
2 * (C) Copyright 2008 - 2013 Tensilica Inc.
4 * SPDX-License-Identifier: GPL-2.0+
8 #include <asm/global_data.h>
9 #include <linux/stringify.h>
11 DECLARE_GLOBAL_DATA_PTR
;
14 static ulong
get_ccount(void)
17 asm volatile ("rsr %0,"__stringify(CCOUNT
) : "=a" (ccount
));
21 static ulong fake_ccount
;
22 #define get_ccount() fake_ccount
25 static void delay_cycles(unsigned cycles
)
28 unsigned expiry
= get_ccount() + cycles
;
29 while ((signed)(expiry
- get_ccount()) > 0)
32 #warning "Without Xtensa timer option, timing will not be accurate."
35 * Approximate the cycle count by a loop iteration count.
36 * This is highly dependent on config and optimization.
40 for (i
= cycles
>> 4U; i
> 0; --i
)
42 fake_ccount
+= cycles
;
47 * Delay (busy-wait) for a number of microseconds.
50 void __udelay(unsigned long usec
)
53 ulong mhz
= CONFIG_SYS_CLK_FREQ
/ 1000000;
55 /* Scale to support full 32-bit usec range */
57 lo
= usec
& ((1<<22)-1);
59 for (i
= 0; i
< hi
; ++i
)
60 delay_cycles(mhz
<< 22);
61 delay_cycles(mhz
* lo
);
66 * Return the elapsed time (ticks) since 'base'.
69 ulong
get_timer(ulong base
)
71 /* Don't tie up a timer; use cycle counter if available (or fake it) */
74 register ulong ccount
;
75 __asm__
volatile ("rsr %0, CCOUNT" : "=a"(ccount
));
76 return ccount
/ (CONFIG_SYS_CLK_FREQ
/ CONFIG_SYS_HZ
) - base
;
79 * Add at least the overhead of this call (in cycles).
80 * Avoids hanging in case caller doesn't use udelay().
81 * Note that functions that don't call udelay() (such as
82 * the "sleep" command) will not get a significant delay
83 * because there is no time reference.
87 return fake_ccount
/ (CONFIG_SYS_CLK_FREQ
/ CONFIG_SYS_HZ
) - base
;
93 * This function is derived from ARM/PowerPC code (read timebase as long long).
94 * On Xtensa it just returns the timer value.
96 unsigned long long get_ticks(void)
102 * This function is derived from ARM/PowerPC code (timebase clock frequency).
103 * On Xtensa it returns the number of timer ticks per second.
105 ulong
get_tbclk(void)
109 tbclk
= CONFIG_SYS_HZ
;
113 #if XCHAL_HAVE_CCOUNT
114 unsigned long timer_get_us(void)
116 unsigned long ccount
;
118 __asm__
volatile ("rsr %0, CCOUNT" : "=a"(ccount
));
119 return ccount
/ (CONFIG_SYS_CLK_FREQ
/ 1000000);