1 // SPDX-License-Identifier: GPL-2.0 << 2 /* calibrate.c: default delay calibration 1 /* calibrate.c: default delay calibration 3 * 2 * 4 * Excised from init/main.c 3 * Excised from init/main.c 5 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds 6 */ 5 */ 7 6 8 #include <linux/jiffies.h> 7 #include <linux/jiffies.h> 9 #include <linux/delay.h> 8 #include <linux/delay.h> 10 #include <linux/init.h> 9 #include <linux/init.h> 11 #include <linux/timex.h> 10 #include <linux/timex.h> 12 #include <linux/smp.h> 11 #include <linux/smp.h> 13 #include <linux/percpu.h> << 14 12 15 unsigned long lpj_fine; 13 unsigned long lpj_fine; 16 unsigned long preset_lpj; 14 unsigned long preset_lpj; 17 static int __init lpj_setup(char *str) 15 static int __init lpj_setup(char *str) 18 { 16 { 19 preset_lpj = simple_strtoul(str,NULL,0 17 preset_lpj = simple_strtoul(str,NULL,0); 20 return 1; 18 return 1; 21 } 19 } 22 20 23 __setup("lpj=", lpj_setup); 21 __setup("lpj=", lpj_setup); 24 22 25 #ifdef ARCH_HAS_READ_CURRENT_TIMER 23 #ifdef ARCH_HAS_READ_CURRENT_TIMER 26 24 27 /* This routine uses the read_current_timer() 25 /* This routine uses the read_current_timer() routine and gets the 28 * loops per jiffy directly, instead of guessi 26 * loops per jiffy directly, instead of guessing it using delay(). 29 * Also, this code tries to handle non-maskabl 27 * Also, this code tries to handle non-maskable asynchronous events 30 * (like SMIs) 28 * (like SMIs) 31 */ 29 */ 32 #define DELAY_CALIBRATION_TICKS 30 #define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100)) 33 #define MAX_DIRECT_CALIBRATION_RETRIES 31 #define MAX_DIRECT_CALIBRATION_RETRIES 5 34 32 35 static unsigned long calibrate_delay_direct(vo !! 33 static unsigned long __cpuinit calibrate_delay_direct(void) 36 { 34 { 37 unsigned long pre_start, start, post_s 35 unsigned long pre_start, start, post_start; 38 unsigned long pre_end, end, post_end; 36 unsigned long pre_end, end, post_end; 39 unsigned long start_jiffies; 37 unsigned long start_jiffies; 40 unsigned long timer_rate_min, timer_ra 38 unsigned long timer_rate_min, timer_rate_max; 41 unsigned long good_timer_sum = 0; 39 unsigned long good_timer_sum = 0; 42 unsigned long good_timer_count = 0; 40 unsigned long good_timer_count = 0; 43 unsigned long measured_times[MAX_DIREC << 44 int max = -1; /* index of measured_tim << 45 int min = -1; << 46 int i; 41 int i; 47 42 48 if (read_current_timer(&pre_start) < 0 43 if (read_current_timer(&pre_start) < 0 ) 49 return 0; 44 return 0; 50 45 51 /* 46 /* 52 * A simple loop like 47 * A simple loop like 53 * while ( jiffies < start_jiffie 48 * while ( jiffies < start_jiffies+1) 54 * start = read_current_t 49 * start = read_current_timer(); 55 * will not do. As we don't really kno 50 * will not do. As we don't really know whether jiffy switch 56 * happened first or timer_value was r 51 * happened first or timer_value was read first. And some asynchronous 57 * event can happen between these two 52 * event can happen between these two events introducing errors in lpj. 58 * 53 * 59 * So, we do 54 * So, we do 60 * 1. pre_start <- When we are sure th 55 * 1. pre_start <- When we are sure that jiffy switch hasn't happened 61 * 2. check jiffy switch 56 * 2. check jiffy switch 62 * 3. start <- timer value before or a 57 * 3. start <- timer value before or after jiffy switch 63 * 4. post_start <- When we are sure t 58 * 4. post_start <- When we are sure that jiffy switch has happened 64 * 59 * 65 * Note, we don't know anything about 60 * Note, we don't know anything about order of 2 and 3. 66 * Now, by looking at post_start and p 61 * Now, by looking at post_start and pre_start difference, we can 67 * check whether any asynchronous even 62 * check whether any asynchronous event happened or not 68 */ 63 */ 69 64 70 for (i = 0; i < MAX_DIRECT_CALIBRATION 65 for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) { 71 pre_start = 0; 66 pre_start = 0; 72 read_current_timer(&start); 67 read_current_timer(&start); 73 start_jiffies = jiffies; 68 start_jiffies = jiffies; 74 while (time_before_eq(jiffies, 69 while (time_before_eq(jiffies, start_jiffies + 1)) { 75 pre_start = start; 70 pre_start = start; 76 read_current_timer(&st 71 read_current_timer(&start); 77 } 72 } 78 read_current_timer(&post_start 73 read_current_timer(&post_start); 79 74 80 pre_end = 0; 75 pre_end = 0; 81 end = post_start; 76 end = post_start; 82 while (time_before_eq(jiffies, 77 while (time_before_eq(jiffies, start_jiffies + 1 + 83 78 DELAY_CALIBRATION_TICKS)) { 84 pre_end = end; 79 pre_end = end; 85 read_current_timer(&en 80 read_current_timer(&end); 86 } 81 } 87 read_current_timer(&post_end); 82 read_current_timer(&post_end); 88 83 89 timer_rate_max = (post_end - p 84 timer_rate_max = (post_end - pre_start) / 90 DELAY_ 85 DELAY_CALIBRATION_TICKS; 91 timer_rate_min = (pre_end - po 86 timer_rate_min = (pre_end - post_start) / 92 DELAY_ 87 DELAY_CALIBRATION_TICKS; 93 88 94 /* 89 /* 95 * If the upper limit and lowe 90 * If the upper limit and lower limit of the timer_rate is 96 * >= 12.5% apart, redo calibr 91 * >= 12.5% apart, redo calibration. 97 */ 92 */ 98 if (start >= post_end) !! 93 if (pre_start != 0 && pre_end != 0 && 99 printk(KERN_NOTICE "ca << 100 "timer << 101 " star << 102 start, post_en << 103 if (start < post_end && pre_st << 104 (timer_rate_max - timer_ra 94 (timer_rate_max - timer_rate_min) < (timer_rate_max >> 3)) { 105 good_timer_count++; 95 good_timer_count++; 106 good_timer_sum += time 96 good_timer_sum += timer_rate_max; 107 measured_times[i] = ti << 108 if (max < 0 || timer_r << 109 max = i; << 110 if (min < 0 || timer_r << 111 min = i; << 112 } else << 113 measured_times[i] = 0; << 114 << 115 } << 116 << 117 /* << 118 * Find the maximum & minimum - if the << 119 * one with the largest difference fro << 120 */ << 121 while (good_timer_count > 1) { << 122 unsigned long estimate; << 123 unsigned long maxdiff; << 124 << 125 /* compute the estimate */ << 126 estimate = (good_timer_sum/goo << 127 maxdiff = estimate >> 3; << 128 << 129 /* if range is within 12% let' << 130 if ((measured_times[max] - mea << 131 return estimate; << 132 << 133 /* ok - drop the worse value a << 134 good_timer_sum = 0; << 135 good_timer_count = 0; << 136 if ((measured_times[max] - est << 137 (estimate - me << 138 printk(KERN_NOTICE "ca << 139 "min b << 140 min, measured_ << 141 measured_times[min] = << 142 min = max; << 143 } else { << 144 printk(KERN_NOTICE "ca << 145 "max b << 146 max, measured_ << 147 measured_times[max] = << 148 max = min; << 149 } 97 } 150 << 151 for (i = 0; i < MAX_DIRECT_CAL << 152 if (measured_times[i] << 153 continue; << 154 good_timer_count++; << 155 good_timer_sum += meas << 156 if (measured_times[i] << 157 min = i; << 158 if (measured_times[i] << 159 max = i; << 160 } << 161 << 162 } 98 } 163 99 164 printk(KERN_NOTICE "calibrate_delay_di !! 100 if (good_timer_count) 165 "estimate for loops_per_jiffy.\ !! 101 return (good_timer_sum/good_timer_count); 166 "interrupts. Consider using \" !! 102 >> 103 printk(KERN_WARNING "calibrate_delay_direct() failed to get a good " >> 104 "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n"); 167 return 0; 105 return 0; 168 } 106 } 169 #else 107 #else 170 static unsigned long calibrate_delay_direct(vo !! 108 static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} 171 { << 172 return 0; << 173 } << 174 #endif 109 #endif 175 110 176 /* 111 /* 177 * This is the number of bits of precision for 112 * This is the number of bits of precision for the loops_per_jiffy. Each 178 * time we refine our estimate after the first !! 113 * bit takes on average 1.5/HZ seconds. This (like the original) is a little 179 * to start with a good estimate. !! 114 * better than 1% 180 * For the boot cpu we can skip the delay cali 115 * For the boot cpu we can skip the delay calibration and assign it a value 181 * calculated based on the timer frequency. 116 * calculated based on the timer frequency. 182 * For the rest of the CPUs we cannot assume t 117 * For the rest of the CPUs we cannot assume that the timer frequency is same as 183 * the cpu frequency, hence do the calibration 118 * the cpu frequency, hence do the calibration for those. 184 */ 119 */ 185 #define LPS_PREC 8 120 #define LPS_PREC 8 186 121 187 static unsigned long calibrate_delay_converge( !! 122 void __cpuinit calibrate_delay(void) 188 { << 189 /* First stage - slowly accelerate to << 190 unsigned long lpj, lpj_base, ticks, lo << 191 int trials = 0, band = 0, trial_in_ban << 192 << 193 lpj = (1<<12); << 194 << 195 /* wait for "start of" clock tick */ << 196 ticks = jiffies; << 197 while (ticks == jiffies) << 198 ; /* nothing */ << 199 /* Go .. */ << 200 ticks = jiffies; << 201 do { << 202 if (++trial_in_band == (1<<ban << 203 ++band; << 204 trial_in_band = 0; << 205 } << 206 __delay(lpj * band); << 207 trials += band; << 208 } while (ticks == jiffies); << 209 /* << 210 * We overshot, so retreat to a clear << 211 * the largest likely undershoot. This << 212 */ << 213 trials -= band; << 214 loopadd_base = lpj * band; << 215 lpj_base = lpj * trials; << 216 << 217 recalibrate: << 218 lpj = lpj_base; << 219 loopadd = loopadd_base; << 220 << 221 /* << 222 * Do a binary approximation to get lp << 223 * equal one clock (up to LPS_PREC bit << 224 */ << 225 chop_limit = lpj >> LPS_PREC; << 226 while (loopadd > chop_limit) { << 227 lpj += loopadd; << 228 ticks = jiffies; << 229 while (ticks == jiffies) << 230 ; /* nothing */ << 231 ticks = jiffies; << 232 __delay(lpj); << 233 if (jiffies != ticks) /* lon << 234 lpj -= loopadd; << 235 loopadd >>= 1; << 236 } << 237 /* << 238 * If we incremented every single time << 239 * massively underestimated initially, << 240 * start, and larger range. (Only seen << 241 */ << 242 if (lpj + loopadd * 2 == lpj_base + lo << 243 lpj_base = lpj; << 244 loopadd_base <<= 2; << 245 goto recalibrate; << 246 } << 247 << 248 return lpj; << 249 } << 250 << 251 static DEFINE_PER_CPU(unsigned long, cpu_loops << 252 << 253 /* << 254 * Check if cpu calibration delay is already k << 255 * some processors with multi-core sockets may << 256 * with the same calibration delay. << 257 * << 258 * Architectures should override this function << 259 * method is available. << 260 */ << 261 unsigned long __attribute__((weak)) calibrate_ << 262 { << 263 return 0; << 264 } << 265 << 266 /* << 267 * Indicate the cpu delay calibration is done. << 268 * architectures to stop accepting delay timer << 269 */ << 270 << 271 void __attribute__((weak)) calibration_delay_d << 272 { 123 { 273 } !! 124 unsigned long ticks, loopbit; 274 !! 125 int lps_precision = LPS_PREC; 275 void calibrate_delay(void) << 276 { << 277 unsigned long lpj; << 278 static bool printed; 126 static bool printed; 279 int this_cpu = smp_processor_id(); << 280 127 281 if (per_cpu(cpu_loops_per_jiffy, this_ !! 128 if (preset_lpj) { 282 lpj = per_cpu(cpu_loops_per_ji !! 129 loops_per_jiffy = preset_lpj; 283 if (!printed) << 284 pr_info("Calibrating d << 285 "already calib << 286 } else if (preset_lpj) { << 287 lpj = preset_lpj; << 288 if (!printed) 130 if (!printed) 289 pr_info("Calibrating d 131 pr_info("Calibrating delay loop (skipped) " 290 "preset value. 132 "preset value.. "); 291 } else if ((!printed) && lpj_fine) { 133 } else if ((!printed) && lpj_fine) { 292 lpj = lpj_fine; !! 134 loops_per_jiffy = lpj_fine; 293 pr_info("Calibrating delay loo 135 pr_info("Calibrating delay loop (skipped), " 294 "value calculated usin 136 "value calculated using timer frequency.. "); 295 } else if ((lpj = calibrate_delay_is_k !! 137 } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) { 296 ; << 297 } else if ((lpj = calibrate_delay_dire << 298 if (!printed) 138 if (!printed) 299 pr_info("Calibrating d 139 pr_info("Calibrating delay using timer " 300 "specific rout 140 "specific routine.. "); 301 } else { 141 } else { >> 142 loops_per_jiffy = (1<<12); >> 143 302 if (!printed) 144 if (!printed) 303 pr_info("Calibrating d 145 pr_info("Calibrating delay loop... "); 304 lpj = calibrate_delay_converge !! 146 while ((loops_per_jiffy <<= 1) != 0) { >> 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 } 305 } 175 } 306 per_cpu(cpu_loops_per_jiffy, this_cpu) << 307 if (!printed) 176 if (!printed) 308 pr_cont("%lu.%02lu BogoMIPS (l 177 pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", 309 lpj/(500000/HZ), !! 178 loops_per_jiffy/(500000/HZ), 310 (lpj/(5000/HZ)) % 100, !! 179 (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); 311 180 312 loops_per_jiffy = lpj; << 313 printed = true; 181 printed = true; 314 << 315 calibration_delay_done(); << 316 } 182 } 317 183
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.