Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* calibrate.c: default delay calibration |
| 2 | * |
| 3 | * Excised from init/main.c |
| 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
| 5 | */ |
| 6 | |
| 7 | #include <linux/sched.h> |
| 8 | #include <linux/delay.h> |
| 9 | #include <linux/init.h> |
| 10 | |
| 11 | static unsigned long preset_lpj; |
| 12 | static int __init lpj_setup(char *str) |
| 13 | { |
| 14 | preset_lpj = simple_strtoul(str,NULL,0); |
| 15 | return 1; |
| 16 | } |
| 17 | |
| 18 | __setup("lpj=", lpj_setup); |
| 19 | |
| 20 | /* |
| 21 | * This is the number of bits of precision for the loops_per_jiffy. Each |
| 22 | * bit takes on average 1.5/HZ seconds. This (like the original) is a little |
| 23 | * better than 1% |
| 24 | */ |
| 25 | #define LPS_PREC 8 |
| 26 | |
| 27 | void __devinit calibrate_delay(void) |
| 28 | { |
| 29 | unsigned long ticks, loopbit; |
| 30 | int lps_precision = LPS_PREC; |
| 31 | |
| 32 | if (preset_lpj) { |
| 33 | loops_per_jiffy = preset_lpj; |
| 34 | printk("Calibrating delay loop (skipped)... " |
| 35 | "%lu.%02lu BogoMIPS preset\n", |
| 36 | loops_per_jiffy/(500000/HZ), |
| 37 | (loops_per_jiffy/(5000/HZ)) % 100); |
| 38 | } else { |
| 39 | loops_per_jiffy = (1<<12); |
| 40 | |
| 41 | printk(KERN_DEBUG "Calibrating delay loop... "); |
| 42 | while ((loops_per_jiffy <<= 1) != 0) { |
| 43 | /* wait for "start of" clock tick */ |
| 44 | ticks = jiffies; |
| 45 | while (ticks == jiffies) |
| 46 | /* nothing */; |
| 47 | /* Go .. */ |
| 48 | ticks = jiffies; |
| 49 | __delay(loops_per_jiffy); |
| 50 | ticks = jiffies - ticks; |
| 51 | if (ticks) |
| 52 | break; |
| 53 | } |
| 54 | |
| 55 | /* |
| 56 | * Do a binary approximation to get loops_per_jiffy set to |
| 57 | * equal one clock (up to lps_precision bits) |
| 58 | */ |
| 59 | loops_per_jiffy >>= 1; |
| 60 | loopbit = loops_per_jiffy; |
| 61 | while (lps_precision-- && (loopbit >>= 1)) { |
| 62 | loops_per_jiffy |= loopbit; |
| 63 | ticks = jiffies; |
| 64 | while (ticks == jiffies) |
| 65 | /* nothing */; |
| 66 | ticks = jiffies; |
| 67 | __delay(loops_per_jiffy); |
| 68 | if (jiffies != ticks) /* longer than 1 tick */ |
| 69 | loops_per_jiffy &= ~loopbit; |
| 70 | } |
| 71 | |
| 72 | /* Round the value and print it */ |
| 73 | printk("%lu.%02lu BogoMIPS (lpj=%lu)\n", |
| 74 | loops_per_jiffy/(500000/HZ), |
| 75 | (loops_per_jiffy/(5000/HZ)) % 100, |
| 76 | loops_per_jiffy); |
| 77 | } |
| 78 | |
| 79 | } |