aboutsummaryrefslogtreecommitdiffstats
path: root/init/calibrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'init/calibrate.c')
-rw-r--r--init/calibrate.c57
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
122static unsigned long __cpuinit calibrate_delay_converge(void) 122static 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;