|
@@ -110,8 +110,8 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;}
|
|
|
|
|
|
/*
|
|
|
* This is the number of bits of precision for the loops_per_jiffy. Each
|
|
|
- * bit takes on average 1.5/HZ seconds. This (like the original) is a little
|
|
|
- * better than 1%
|
|
|
+ * time we refine our estimate after the first takes 1.5/HZ seconds, so try
|
|
|
+ * to start with a good estimate.
|
|
|
* For the boot cpu we can skip the delay calibration and assign it a value
|
|
|
* calculated based on the timer frequency.
|
|
|
* 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;}
|
|
|
|
|
|
static unsigned long __cpuinit calibrate_delay_converge(void)
|
|
|
{
|
|
|
- unsigned long lpj, ticks, loopbit;
|
|
|
- int lps_precision = LPS_PREC;
|
|
|
+ /* First stage - slowly accelerate to find initial bounds */
|
|
|
+ unsigned long lpj, ticks, loopadd, chop_limit;
|
|
|
+ int trials = 0, band = 0, trial_in_band = 0;
|
|
|
|
|
|
lpj = (1<<12);
|
|
|
- while ((lpj <<= 1) != 0) {
|
|
|
- /* wait for "start of" clock tick */
|
|
|
- ticks = jiffies;
|
|
|
- while (ticks == jiffies)
|
|
|
- /* nothing */;
|
|
|
- /* Go .. */
|
|
|
- ticks = jiffies;
|
|
|
- __delay(lpj);
|
|
|
- ticks = jiffies - ticks;
|
|
|
- if (ticks)
|
|
|
- break;
|
|
|
- }
|
|
|
+
|
|
|
+ /* wait for "start of" clock tick */
|
|
|
+ ticks = jiffies;
|
|
|
+ while (ticks == jiffies)
|
|
|
+ ; /* nothing */
|
|
|
+ /* Go .. */
|
|
|
+ ticks = jiffies;
|
|
|
+ do {
|
|
|
+ if (++trial_in_band == (1<<band)) {
|
|
|
+ ++band;
|
|
|
+ trial_in_band = 0;
|
|
|
+ }
|
|
|
+ __delay(lpj * band);
|
|
|
+ trials += band;
|
|
|
+ } while (ticks == jiffies);
|
|
|
+ /*
|
|
|
+ * We overshot, so retreat to a clear underestimate. Then estimate
|
|
|
+ * the largest likely undershoot. This defines our chop bounds.
|
|
|
+ */
|
|
|
+ trials -= band;
|
|
|
+ loopadd = lpj * band;
|
|
|
+ lpj *= trials;
|
|
|
+ chop_limit = lpj >> (LPS_PREC + 1);
|
|
|
|
|
|
/*
|
|
|
* Do a binary approximation to get lpj set to
|
|
|
- * equal one clock (up to lps_precision bits)
|
|
|
+ * equal one clock (up to LPS_PREC bits)
|
|
|
*/
|
|
|
- lpj >>= 1;
|
|
|
- loopbit = lpj;
|
|
|
- while (lps_precision-- && (loopbit >>= 1)) {
|
|
|
- lpj |= loopbit;
|
|
|
+ while (loopadd > chop_limit) {
|
|
|
+ lpj += loopadd;
|
|
|
ticks = jiffies;
|
|
|
while (ticks == jiffies)
|
|
|
- /* nothing */;
|
|
|
+ ; /* nothing */
|
|
|
ticks = jiffies;
|
|
|
__delay(lpj);
|
|
|
if (jiffies != ticks) /* longer than 1 tick */
|
|
|
- lpj &= ~loopbit;
|
|
|
+ lpj -= loopadd;
|
|
|
+ loopadd >>= 1;
|
|
|
}
|
|
|
|
|
|
return lpj;
|