aboutsummaryrefslogtreecommitdiffstats
path: root/init/calibrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'init/calibrate.c')
-rw-r--r--init/calibrate.c102
1 files changed, 67 insertions, 35 deletions
diff --git a/init/calibrate.c b/init/calibrate.c
index 24fe022c55f9..76ac9194cbc4 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
@@ -119,10 +119,72 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;}
119 */ 119 */
120#define LPS_PREC 8 120#define LPS_PREC 8
121 121
122static unsigned long __cpuinit calibrate_delay_converge(void)
123{
124 /* First stage - slowly accelerate to find initial bounds */
125 unsigned long lpj, lpj_base, ticks, loopadd, loopadd_base, chop_limit;
126 int trials = 0, band = 0, trial_in_band = 0;
127
128 lpj = (1<<12);
129
130 /* wait for "start of" clock tick */
131 ticks = jiffies;
132 while (ticks == jiffies)
133 ; /* nothing */
134 /* Go .. */
135 ticks = jiffies;
136 do {
137 if (++trial_in_band == (1<<band)) {
138 ++band;
139 trial_in_band = 0;
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_base = lpj * band;
150 lpj_base = lpj * trials;
151
152recalibrate:
153 lpj = lpj_base;
154 loopadd = loopadd_base;
155
156 /*
157 * Do a binary approximation to get lpj set to
158 * equal one clock (up to LPS_PREC bits)
159 */
160 chop_limit = lpj >> LPS_PREC;
161 while (loopadd > chop_limit) {
162 lpj += loopadd;
163 ticks = jiffies;
164 while (ticks == jiffies)
165 ; /* nothing */
166 ticks = jiffies;
167 __delay(lpj);
168 if (jiffies != ticks) /* longer than 1 tick */
169 lpj -= loopadd;
170 loopadd >>= 1;
171 }
172 /*
173 * If we incremented every single time possible, presume we've
174 * massively underestimated initially, and retry with a higher
175 * start, and larger range. (Only seen on x86_64, due to SMIs)
176 */
177 if (lpj + loopadd * 2 == lpj_base + loopadd_base * 2) {
178 lpj_base = lpj;
179 loopadd_base <<= 2;
180 goto recalibrate;
181 }
182
183 return lpj;
184}
185
122void __cpuinit calibrate_delay(void) 186void __cpuinit calibrate_delay(void)
123{ 187{
124 unsigned long ticks, loopbit;
125 int lps_precision = LPS_PREC;
126 static bool printed; 188 static bool printed;
127 189
128 if (preset_lpj) { 190 if (preset_lpj) {
@@ -139,39 +201,9 @@ void __cpuinit calibrate_delay(void)
139 pr_info("Calibrating delay using timer " 201 pr_info("Calibrating delay using timer "
140 "specific routine.. "); 202 "specific routine.. ");
141 } else { 203 } else {
142 loops_per_jiffy = (1<<12);
143
144 if (!printed) 204 if (!printed)
145 pr_info("Calibrating delay loop... "); 205 pr_info("Calibrating delay loop... ");
146 while ((loops_per_jiffy <<= 1) != 0) { 206 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 } 207 }
176 if (!printed) 208 if (!printed)
177 pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", 209 pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",