diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-06-01 16:18:15 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-08-05 08:26:20 -0400 |
commit | ca148125e6134de334b61822539d220794d8da18 (patch) | |
tree | e31af5840a8873ec6613bf9b09fe0f9ad3e6a9c7 /arch/mips/cavium-octeon/csrc-octeon.c | |
parent | e6b78c4f224925c71cce57033b1e6e30dd56add7 (diff) |
MIPS: Octeon: Implement delays with cycle counter.
Power throttling make deterministic delay loops impossible.
Re-implement delays using the cycle counter. This also allows us to
get rid of the code that calculates loops per jiffy.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1317/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/cavium-octeon/csrc-octeon.c')
-rw-r--r-- | arch/mips/cavium-octeon/csrc-octeon.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c index 36400d23ff59..b6847c8e0ddd 100644 --- a/arch/mips/cavium-octeon/csrc-octeon.c +++ b/arch/mips/cavium-octeon/csrc-octeon.c | |||
@@ -80,3 +80,58 @@ void __init plat_time_init(void) | |||
80 | clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); | 80 | clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); |
81 | clocksource_register(&clocksource_mips); | 81 | clocksource_register(&clocksource_mips); |
82 | } | 82 | } |
83 | |||
84 | static u64 octeon_udelay_factor; | ||
85 | static u64 octeon_ndelay_factor; | ||
86 | |||
87 | void __init octeon_setup_delays(void) | ||
88 | { | ||
89 | octeon_udelay_factor = octeon_get_clock_rate() / 1000000; | ||
90 | /* | ||
91 | * For __ndelay we divide by 2^16, so the factor is multiplied | ||
92 | * by the same amount. | ||
93 | */ | ||
94 | octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull; | ||
95 | |||
96 | preset_lpj = octeon_get_clock_rate() / HZ; | ||
97 | } | ||
98 | |||
99 | void __udelay(unsigned long us) | ||
100 | { | ||
101 | u64 cur, end, inc; | ||
102 | |||
103 | cur = read_c0_cvmcount(); | ||
104 | |||
105 | inc = us * octeon_udelay_factor; | ||
106 | end = cur + inc; | ||
107 | |||
108 | while (end > cur) | ||
109 | cur = read_c0_cvmcount(); | ||
110 | } | ||
111 | EXPORT_SYMBOL(__udelay); | ||
112 | |||
113 | void __ndelay(unsigned long ns) | ||
114 | { | ||
115 | u64 cur, end, inc; | ||
116 | |||
117 | cur = read_c0_cvmcount(); | ||
118 | |||
119 | inc = ((ns * octeon_ndelay_factor) >> 16); | ||
120 | end = cur + inc; | ||
121 | |||
122 | while (end > cur) | ||
123 | cur = read_c0_cvmcount(); | ||
124 | } | ||
125 | EXPORT_SYMBOL(__ndelay); | ||
126 | |||
127 | void __delay(unsigned long loops) | ||
128 | { | ||
129 | u64 cur, end; | ||
130 | |||
131 | cur = read_c0_cvmcount(); | ||
132 | end = cur + loops; | ||
133 | |||
134 | while (end > cur) | ||
135 | cur = read_c0_cvmcount(); | ||
136 | } | ||
137 | EXPORT_SYMBOL(__delay); | ||