diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/calibrate.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/init/calibrate.c b/init/calibrate.c index b71643a7acae..f9000dfbe227 100644 --- a/init/calibrate.c +++ b/init/calibrate.c | |||
@@ -110,8 +110,8 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} | |||
110 | 110 | ||
111 | /* | 111 | /* |
112 | * This is the number of bits of precision for the loops_per_jiffy. Each | 112 | * This is the number of bits of precision for the loops_per_jiffy. Each |
113 | * bit takes on average 1.5/HZ seconds. This (like the original) is a little | 113 | * time we refine our estimate after the first takes 1.5/HZ seconds, so try |
114 | * better than 1% | 114 | * to start with a good estimate. |
115 | * For the boot cpu we can skip the delay calibration and assign it a value | 115 | * For the boot cpu we can skip the delay calibration and assign it a value |
116 | * calculated based on the timer frequency. | 116 | * calculated based on the timer frequency. |
117 | * For the rest of the CPUs we cannot assume that the timer frequency is same as | 117 | * For the rest of the CPUs we cannot assume that the timer frequency is same as |
@@ -121,38 +121,49 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} | |||
121 | 121 | ||
122 | static unsigned long __cpuinit calibrate_delay_converge(void) | 122 | static unsigned long __cpuinit calibrate_delay_converge(void) |
123 | { | 123 | { |
124 | unsigned long lpj, ticks, loopbit; | 124 | /* First stage - slowly accelerate to find initial bounds */ |
125 | int lps_precision = LPS_PREC; | 125 | unsigned long lpj, ticks, loopadd, chop_limit; |
126 | int trials = 0, band = 0, trial_in_band = 0; | ||
126 | 127 | ||
127 | lpj = (1<<12); | 128 | lpj = (1<<12); |
128 | while ((lpj <<= 1) != 0) { | 129 | |
129 | /* wait for "start of" clock tick */ | 130 | /* wait for "start of" clock tick */ |
130 | ticks = jiffies; | 131 | ticks = jiffies; |
131 | while (ticks == jiffies) | 132 | while (ticks == jiffies) |
132 | /* nothing */; | 133 | ; /* nothing */ |
133 | /* Go .. */ | 134 | /* Go .. */ |
134 | ticks = jiffies; | 135 | ticks = jiffies; |
135 | __delay(lpj); | 136 | do { |
136 | ticks = jiffies - ticks; | 137 | if (++trial_in_band == (1<<band)) { |
137 | if (ticks) | 138 | ++band; |
138 | break; | 139 | trial_in_band = 0; |
139 | } | 140 | } |
141 | __delay(lpj * band); | ||
142 | trials += band; | ||
143 | } while (ticks == jiffies); | ||
144 | /* | ||
145 | * We overshot, so retreat to a clear underestimate. Then estimate | ||
146 | * the largest likely undershoot. This defines our chop bounds. | ||
147 | */ | ||
148 | trials -= band; | ||
149 | loopadd = lpj * band; | ||
150 | lpj *= trials; | ||
151 | chop_limit = lpj >> (LPS_PREC + 1); | ||
140 | 152 | ||
141 | /* | 153 | /* |
142 | * Do a binary approximation to get lpj set to | 154 | * Do a binary approximation to get lpj set to |
143 | * equal one clock (up to lps_precision bits) | 155 | * equal one clock (up to LPS_PREC bits) |
144 | */ | 156 | */ |
145 | lpj >>= 1; | 157 | while (loopadd > chop_limit) { |
146 | loopbit = lpj; | 158 | lpj += loopadd; |
147 | while (lps_precision-- && (loopbit >>= 1)) { | ||
148 | lpj |= loopbit; | ||
149 | ticks = jiffies; | 159 | ticks = jiffies; |
150 | while (ticks == jiffies) | 160 | while (ticks == jiffies) |
151 | /* nothing */; | 161 | ; /* nothing */ |
152 | ticks = jiffies; | 162 | ticks = jiffies; |
153 | __delay(lpj); | 163 | __delay(lpj); |
154 | if (jiffies != ticks) /* longer than 1 tick */ | 164 | if (jiffies != ticks) /* longer than 1 tick */ |
155 | lpj &= ~loopbit; | 165 | lpj -= loopadd; |
166 | loopadd >>= 1; | ||
156 | } | 167 | } |
157 | 168 | ||
158 | return lpj; | 169 | return lpj; |