aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/calibrate.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/init/calibrate.c b/init/calibrate.c
index ecb3822d4f70..7963e3fc51d9 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -8,7 +8,9 @@
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/timex.h> 10#include <linux/timex.h>
11#include <linux/smp.h>
11 12
13unsigned long lpj_fine;
12unsigned long preset_lpj; 14unsigned long preset_lpj;
13static int __init lpj_setup(char *str) 15static int __init lpj_setup(char *str)
14{ 16{
@@ -33,9 +35,9 @@ static unsigned long __cpuinit calibrate_delay_direct(void)
33 unsigned long pre_start, start, post_start; 35 unsigned long pre_start, start, post_start;
34 unsigned long pre_end, end, post_end; 36 unsigned long pre_end, end, post_end;
35 unsigned long start_jiffies; 37 unsigned long start_jiffies;
36 unsigned long tsc_rate_min, tsc_rate_max; 38 unsigned long timer_rate_min, timer_rate_max;
37 unsigned long good_tsc_sum = 0; 39 unsigned long good_timer_sum = 0;
38 unsigned long good_tsc_count = 0; 40 unsigned long good_timer_count = 0;
39 int i; 41 int i;
40 42
41 if (read_current_timer(&pre_start) < 0 ) 43 if (read_current_timer(&pre_start) < 0 )
@@ -79,22 +81,24 @@ static unsigned long __cpuinit calibrate_delay_direct(void)
79 } 81 }
80 read_current_timer(&post_end); 82 read_current_timer(&post_end);
81 83
82 tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS; 84 timer_rate_max = (post_end - pre_start) /
83 tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS; 85 DELAY_CALIBRATION_TICKS;
86 timer_rate_min = (pre_end - post_start) /
87 DELAY_CALIBRATION_TICKS;
84 88
85 /* 89 /*
86 * If the upper limit and lower limit of the tsc_rate is 90 * If the upper limit and lower limit of the timer_rate is
87 * >= 12.5% apart, redo calibration. 91 * >= 12.5% apart, redo calibration.
88 */ 92 */
89 if (pre_start != 0 && pre_end != 0 && 93 if (pre_start != 0 && pre_end != 0 &&
90 (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) { 94 (timer_rate_max - timer_rate_min) < (timer_rate_max >> 3)) {
91 good_tsc_count++; 95 good_timer_count++;
92 good_tsc_sum += tsc_rate_max; 96 good_timer_sum += timer_rate_max;
93 } 97 }
94 } 98 }
95 99
96 if (good_tsc_count) 100 if (good_timer_count)
97 return (good_tsc_sum/good_tsc_count); 101 return (good_timer_sum/good_timer_count);
98 102
99 printk(KERN_WARNING "calibrate_delay_direct() failed to get a good " 103 printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
100 "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n"); 104 "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
@@ -108,6 +112,10 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;}
108 * 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
109 * bit takes on average 1.5/HZ seconds. This (like the original) is a little 113 * bit takes on average 1.5/HZ seconds. This (like the original) is a little
110 * better than 1% 114 * better than 1%
115 * For the boot cpu we can skip the delay calibration and assign it a value
116 * calculated based on the timer frequency.
117 * For the rest of the CPUs we cannot assume that the timer frequency is same as
118 * the cpu frequency, hence do the calibration for those.
111 */ 119 */
112#define LPS_PREC 8 120#define LPS_PREC 8
113 121
@@ -118,20 +126,20 @@ void __cpuinit calibrate_delay(void)
118 126
119 if (preset_lpj) { 127 if (preset_lpj) {
120 loops_per_jiffy = preset_lpj; 128 loops_per_jiffy = preset_lpj;
121 printk("Calibrating delay loop (skipped)... " 129 printk(KERN_INFO
122 "%lu.%02lu BogoMIPS preset\n", 130 "Calibrating delay loop (skipped) preset value.. ");
123 loops_per_jiffy/(500000/HZ), 131 } else if ((smp_processor_id() == 0) && lpj_fine) {
124 (loops_per_jiffy/(5000/HZ)) % 100); 132 loops_per_jiffy = lpj_fine;
133 printk(KERN_INFO
134 "Calibrating delay loop (skipped), "
135 "value calculated using timer frequency.. ");
125 } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) { 136 } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
126 printk("Calibrating delay using timer specific routine.. "); 137 printk(KERN_INFO
127 printk("%lu.%02lu BogoMIPS (lpj=%lu)\n", 138 "Calibrating delay using timer specific routine.. ");
128 loops_per_jiffy/(500000/HZ),
129 (loops_per_jiffy/(5000/HZ)) % 100,
130 loops_per_jiffy);
131 } else { 139 } else {
132 loops_per_jiffy = (1<<12); 140 loops_per_jiffy = (1<<12);
133 141
134 printk(KERN_DEBUG "Calibrating delay loop... "); 142 printk(KERN_INFO "Calibrating delay loop... ");
135 while ((loops_per_jiffy <<= 1) != 0) { 143 while ((loops_per_jiffy <<= 1) != 0) {
136 /* wait for "start of" clock tick */ 144 /* wait for "start of" clock tick */
137 ticks = jiffies; 145 ticks = jiffies;
@@ -161,12 +169,8 @@ void __cpuinit calibrate_delay(void)
161 if (jiffies != ticks) /* longer than 1 tick */ 169 if (jiffies != ticks) /* longer than 1 tick */
162 loops_per_jiffy &= ~loopbit; 170 loops_per_jiffy &= ~loopbit;
163 } 171 }
164
165 /* Round the value and print it */
166 printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
167 loops_per_jiffy/(500000/HZ),
168 (loops_per_jiffy/(5000/HZ)) % 100,
169 loops_per_jiffy);
170 } 172 }
171 173 printk(KERN_INFO "%lu.%02lu BogoMIPS (lpj=%lu)\n",
174 loops_per_jiffy/(500000/HZ),
175 (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
172} 176}