xref: /openbmc/linux/arch/loongarch/lib/delay.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*559671e0SHuacai Chen // SPDX-License-Identifier: GPL-2.0
2*559671e0SHuacai Chen /*
3*559671e0SHuacai Chen  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4*559671e0SHuacai Chen  */
5*559671e0SHuacai Chen #include <linux/delay.h>
6*559671e0SHuacai Chen #include <linux/export.h>
7*559671e0SHuacai Chen #include <linux/smp.h>
8*559671e0SHuacai Chen #include <linux/timex.h>
9*559671e0SHuacai Chen 
10*559671e0SHuacai Chen #include <asm/processor.h>
11*559671e0SHuacai Chen 
__delay(unsigned long cycles)12*559671e0SHuacai Chen void __delay(unsigned long cycles)
13*559671e0SHuacai Chen {
14*559671e0SHuacai Chen 	u64 t0 = get_cycles();
15*559671e0SHuacai Chen 
16*559671e0SHuacai Chen 	while ((unsigned long)(get_cycles() - t0) < cycles)
17*559671e0SHuacai Chen 		cpu_relax();
18*559671e0SHuacai Chen }
19*559671e0SHuacai Chen EXPORT_SYMBOL(__delay);
20*559671e0SHuacai Chen 
21*559671e0SHuacai Chen /*
22*559671e0SHuacai Chen  * Division by multiplication: you don't have to worry about
23*559671e0SHuacai Chen  * loss of precision.
24*559671e0SHuacai Chen  *
25*559671e0SHuacai Chen  * Use only for very small delays ( < 1 msec).	Should probably use a
26*559671e0SHuacai Chen  * lookup table, really, as the multiplications take much too long with
27*559671e0SHuacai Chen  * short delays.  This is a "reasonable" implementation, though (and the
28*559671e0SHuacai Chen  * first constant multiplications gets optimized away if the delay is
29*559671e0SHuacai Chen  * a constant)
30*559671e0SHuacai Chen  */
31*559671e0SHuacai Chen 
__udelay(unsigned long us)32*559671e0SHuacai Chen void __udelay(unsigned long us)
33*559671e0SHuacai Chen {
34*559671e0SHuacai Chen 	__delay((us * 0x000010c7ull * HZ * lpj_fine) >> 32);
35*559671e0SHuacai Chen }
36*559671e0SHuacai Chen EXPORT_SYMBOL(__udelay);
37*559671e0SHuacai Chen 
__ndelay(unsigned long ns)38*559671e0SHuacai Chen void __ndelay(unsigned long ns)
39*559671e0SHuacai Chen {
40*559671e0SHuacai Chen 	__delay((ns * 0x00000005ull * HZ * lpj_fine) >> 32);
41*559671e0SHuacai Chen }
42*559671e0SHuacai Chen EXPORT_SYMBOL(__ndelay);
43