summaryrefslogtreecommitdiff
path: root/libdde_linux26
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2010-07-12 22:46:28 +0200
committerZheng Da <zhengda1936@gmail.com>2010-07-12 22:46:28 +0200
commit91af4ed54bbdb3a2cae9606eb69ebbaddff5602c (patch)
treebeaa39c7071abbd4718d620e08675fabfe1a48fd /libdde_linux26
parent2b91d7ba805279f3f871f95d5d49c6c1b7d6b879 (diff)
calibrate the delay loop several times.
It's necessary when we do it in the user space, as that the CPU switches to other processes and the result is too imprecise.
Diffstat (limited to 'libdde_linux26')
-rw-r--r--libdde_linux26/lib/src/init/calibrate.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/libdde_linux26/lib/src/init/calibrate.c b/libdde_linux26/lib/src/init/calibrate.c
index aede8e53..687da473 100644
--- a/libdde_linux26/lib/src/init/calibrate.c
+++ b/libdde_linux26/lib/src/init/calibrate.c
@@ -123,11 +123,50 @@ static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;}
*/
#define LPS_PREC 8
-void __cpuinit calibrate_delay(void)
+static unsigned long __cpuinit calibrate_delay_estimate(void)
{
unsigned long ticks, loopbit;
int lps_precision = LPS_PREC;
+ int loops_per_jiffy;
+
+ loops_per_jiffy = (1<<12);
+
+ while ((loops_per_jiffy <<= 1) != 0) {
+ /* wait for "start of" clock tick */
+ ticks = jiffies;
+ while (ticks == jiffies)
+ /* nothing */;
+ /* Go .. */
+ ticks = jiffies;
+ __delay(loops_per_jiffy);
+ ticks = jiffies - ticks;
+ if (ticks)
+ break;
+ }
+
+ /*
+ * Do a binary approximation to get loops_per_jiffy set to
+ * equal one clock (up to lps_precision bits)
+ */
+ loops_per_jiffy >>= 1;
+ loopbit = loops_per_jiffy;
+ while (lps_precision-- && (loopbit >>= 1)) {
+ loops_per_jiffy |= loopbit;
+ ticks = jiffies;
+ while (ticks == jiffies)
+ /* nothing */;
+ ticks = jiffies;
+ __delay(loops_per_jiffy);
+ if (jiffies != ticks) /* longer than 1 tick */
+ loops_per_jiffy &= ~loopbit;
+ }
+ return loops_per_jiffy;
+}
+#define NRETRIES 3
+
+void __cpuinit calibrate_delay(void)
+{
if (preset_lpj) {
loops_per_jiffy = preset_lpj;
printk(KERN_INFO
@@ -141,38 +180,17 @@ void __cpuinit calibrate_delay(void)
printk(KERN_INFO
"Calibrating delay using timer specific routine.. ");
} else {
- loops_per_jiffy = (1<<12);
+ int i;
+ unsigned long result;
printk(KERN_INFO "Calibrating delay loop... ");
- while ((loops_per_jiffy <<= 1) != 0) {
- /* wait for "start of" clock tick */
- ticks = jiffies;
- while (ticks == jiffies)
- /* nothing */;
- /* Go .. */
- ticks = jiffies;
- __delay(loops_per_jiffy);
- ticks = jiffies - ticks;
- if (ticks)
- break;
- }
-
- /*
- * Do a binary approximation to get loops_per_jiffy set to
- * equal one clock (up to lps_precision bits)
- */
- loops_per_jiffy >>= 1;
- loopbit = loops_per_jiffy;
- while (lps_precision-- && (loopbit >>= 1)) {
- loops_per_jiffy |= loopbit;
- ticks = jiffies;
- while (ticks == jiffies)
- /* nothing */;
- ticks = jiffies;
- __delay(loops_per_jiffy);
- if (jiffies != ticks) /* longer than 1 tick */
- loops_per_jiffy &= ~loopbit;
+ loops_per_jiffy = 0;
+ for (i = 0; i < NRETRIES; i++) {
+ result = calibrate_delay_estimate();
+ if (result > loops_per_jiffy)
+ loops_per_jiffy = result;
}
+
}
printk(KERN_CONT "%lu.%02lu BogoMIPS (lpj=%lu)\n",
loops_per_jiffy/(500000/HZ),