diff options
Diffstat (limited to 'init/calibrate.c')
-rw-r--r-- | init/calibrate.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/init/calibrate.c b/init/calibrate.c index 24fe022c55f9..b71643a7acae 100644 --- a/init/calibrate.c +++ b/init/calibrate.c | |||
@@ -119,10 +119,47 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} | |||
119 | */ | 119 | */ |
120 | #define LPS_PREC 8 | 120 | #define LPS_PREC 8 |
121 | 121 | ||
122 | void __cpuinit calibrate_delay(void) | 122 | static unsigned long __cpuinit calibrate_delay_converge(void) |
123 | { | 123 | { |
124 | unsigned long ticks, loopbit; | 124 | unsigned long lpj, ticks, loopbit; |
125 | int lps_precision = LPS_PREC; | 125 | int lps_precision = LPS_PREC; |
126 | |||
127 | lpj = (1<<12); | ||
128 | while ((lpj <<= 1) != 0) { | ||
129 | /* wait for "start of" clock tick */ | ||
130 | ticks = jiffies; | ||
131 | while (ticks == jiffies) | ||
132 | /* nothing */; | ||
133 | /* Go .. */ | ||
134 | ticks = jiffies; | ||
135 | __delay(lpj); | ||
136 | ticks = jiffies - ticks; | ||
137 | if (ticks) | ||
138 | break; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * Do a binary approximation to get lpj set to | ||
143 | * equal one clock (up to lps_precision bits) | ||
144 | */ | ||
145 | lpj >>= 1; | ||
146 | loopbit = lpj; | ||
147 | while (lps_precision-- && (loopbit >>= 1)) { | ||
148 | lpj |= loopbit; | ||
149 | ticks = jiffies; | ||
150 | while (ticks == jiffies) | ||
151 | /* nothing */; | ||
152 | ticks = jiffies; | ||
153 | __delay(lpj); | ||
154 | if (jiffies != ticks) /* longer than 1 tick */ | ||
155 | lpj &= ~loopbit; | ||
156 | } | ||
157 | |||
158 | return lpj; | ||
159 | } | ||
160 | |||
161 | void __cpuinit calibrate_delay(void) | ||
162 | { | ||
126 | static bool printed; | 163 | static bool printed; |
127 | 164 | ||
128 | if (preset_lpj) { | 165 | if (preset_lpj) { |
@@ -139,39 +176,9 @@ void __cpuinit calibrate_delay(void) | |||
139 | pr_info("Calibrating delay using timer " | 176 | pr_info("Calibrating delay using timer " |
140 | "specific routine.. "); | 177 | "specific routine.. "); |
141 | } else { | 178 | } else { |
142 | loops_per_jiffy = (1<<12); | ||
143 | |||
144 | if (!printed) | 179 | if (!printed) |
145 | pr_info("Calibrating delay loop... "); | 180 | pr_info("Calibrating delay loop... "); |
146 | while ((loops_per_jiffy <<= 1) != 0) { | 181 | loops_per_jiffy = calibrate_delay_converge(); |
147 | /* wait for "start of" clock tick */ | ||
148 | ticks = jiffies; | ||
149 | while (ticks == jiffies) | ||
150 | /* nothing */; | ||
151 | /* Go .. */ | ||
152 | ticks = jiffies; | ||
153 | __delay(loops_per_jiffy); | ||
154 | ticks = jiffies - ticks; | ||
155 | if (ticks) | ||
156 | break; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Do a binary approximation to get loops_per_jiffy set to | ||
161 | * equal one clock (up to lps_precision bits) | ||
162 | */ | ||
163 | loops_per_jiffy >>= 1; | ||
164 | loopbit = loops_per_jiffy; | ||
165 | while (lps_precision-- && (loopbit >>= 1)) { | ||
166 | loops_per_jiffy |= loopbit; | ||
167 | ticks = jiffies; | ||
168 | while (ticks == jiffies) | ||
169 | /* nothing */; | ||
170 | ticks = jiffies; | ||
171 | __delay(loops_per_jiffy); | ||
172 | if (jiffies != ticks) /* longer than 1 tick */ | ||
173 | loops_per_jiffy &= ~loopbit; | ||
174 | } | ||
175 | } | 182 | } |
176 | if (!printed) | 183 | if (!printed) |
177 | pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", | 184 | pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", |