diff options
Diffstat (limited to 'arch/microblaze/include/asm/delay.h')
-rw-r--r-- | arch/microblaze/include/asm/delay.h | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/microblaze/include/asm/delay.h b/arch/microblaze/include/asm/delay.h new file mode 100644 index 000000000000..05b7d39e4391 --- /dev/null +++ b/arch/microblaze/include/asm/delay.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * include/asm-microblaze/delay.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2008 Michal Simek | ||
9 | * Copyright (C) 2007 John Williams | ||
10 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_DELAY_H | ||
14 | #define _ASM_MICROBLAZE_DELAY_H | ||
15 | |||
16 | extern inline void __delay(unsigned long loops) | ||
17 | { | ||
18 | asm volatile ("# __delay \n\t" \ | ||
19 | "1: addi %0, %0, -1\t\n" \ | ||
20 | "bneid %0, 1b \t\n" \ | ||
21 | "nop \t\n" | ||
22 | : "=r" (loops) | ||
23 | : "0" (loops)); | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so | ||
28 | * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32. | ||
29 | * | ||
30 | * The mul instruction gives us loops = (a * b) / 2^32. | ||
31 | * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226 | ||
32 | * because this lets us support a wide range of HZ and | ||
33 | * loops_per_jiffy values without either a or b overflowing 2^32. | ||
34 | * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and | ||
35 | * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280 | ||
36 | * (which corresponds to ~3800 bogomips at HZ = 100). | ||
37 | * -- paulus | ||
38 | */ | ||
39 | #define __MAX_UDELAY (226050910UL/HZ) /* maximum udelay argument */ | ||
40 | #define __MAX_NDELAY (4294967295UL/HZ) /* maximum ndelay argument */ | ||
41 | |||
42 | extern unsigned long loops_per_jiffy; | ||
43 | |||
44 | extern inline void __udelay(unsigned int x) | ||
45 | { | ||
46 | |||
47 | unsigned long long tmp = | ||
48 | (unsigned long long)x * (unsigned long long)loops_per_jiffy \ | ||
49 | * 226LL; | ||
50 | unsigned loops = tmp >> 32; | ||
51 | |||
52 | /* | ||
53 | __asm__("mulxuu %0,%1,%2" : "=r" (loops) : | ||
54 | "r" (x), "r" (loops_per_jiffy * 226)); | ||
55 | */ | ||
56 | __delay(loops); | ||
57 | } | ||
58 | |||
59 | extern void __bad_udelay(void); /* deliberately undefined */ | ||
60 | extern void __bad_ndelay(void); /* deliberately undefined */ | ||
61 | |||
62 | #define udelay(n) (__builtin_constant_p(n) ? \ | ||
63 | ((n) > __MAX_UDELAY ? __bad_udelay() : __udelay((n) * (19 * HZ))) : \ | ||
64 | __udelay((n) * (19 * HZ))) | ||
65 | |||
66 | #define ndelay(n) (__builtin_constant_p(n) ? \ | ||
67 | ((n) > __MAX_NDELAY ? __bad_ndelay() : __udelay((n) * HZ)) : \ | ||
68 | __udelay((n) * HZ)) | ||
69 | |||
70 | #define muldiv(a, b, c) (((a)*(b))/(c)) | ||
71 | |||
72 | #endif /* _ASM_MICROBLAZE_DELAY_H */ | ||