|
@@ -273,30 +273,43 @@ static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin)
|
|
|
* use the TSC value at the transitions to calculate a pretty
|
|
|
* good value for the TSC frequencty.
|
|
|
*/
|
|
|
-static inline int pit_expect_msb(unsigned char val)
|
|
|
+static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap)
|
|
|
{
|
|
|
- int count = 0;
|
|
|
+ int count;
|
|
|
+ u64 tsc = 0;
|
|
|
|
|
|
for (count = 0; count < 50000; count++) {
|
|
|
/* Ignore LSB */
|
|
|
inb(0x42);
|
|
|
if (inb(0x42) != val)
|
|
|
break;
|
|
|
+ tsc = get_cycles();
|
|
|
}
|
|
|
- return count > 50;
|
|
|
+ *deltap = get_cycles() - tsc;
|
|
|
+ *tscp = tsc;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We require _some_ success, but the quality control
|
|
|
+ * will be based on the error terms on the TSC values.
|
|
|
+ */
|
|
|
+ return count > 5;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * How many MSB values do we want to see? We aim for a
|
|
|
- * 15ms calibration, which assuming a 2us counter read
|
|
|
- * error should give us roughly 150 ppm precision for
|
|
|
- * the calibration.
|
|
|
+ * How many MSB values do we want to see? We aim for
|
|
|
+ * a maximum error rate of 500ppm (in practice the
|
|
|
+ * real error is much smaller), but refuse to spend
|
|
|
+ * more than 25ms on it.
|
|
|
*/
|
|
|
-#define QUICK_PIT_MS 15
|
|
|
-#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
|
|
|
+#define MAX_QUICK_PIT_MS 25
|
|
|
+#define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
|
|
|
|
|
|
static unsigned long quick_pit_calibrate(void)
|
|
|
{
|
|
|
+ int i;
|
|
|
+ u64 tsc, delta;
|
|
|
+ unsigned long d1, d2;
|
|
|
+
|
|
|
/* Set the Gate high, disable speaker */
|
|
|
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
|
|
|
|
|
@@ -324,45 +337,43 @@ static unsigned long quick_pit_calibrate(void)
|
|
|
inb(0x42);
|
|
|
inb(0x42);
|
|
|
|
|
|
- if (pit_expect_msb(0xff)) {
|
|
|
- int i;
|
|
|
- u64 t1, t2, delta;
|
|
|
- unsigned char expect = 0xfe;
|
|
|
-
|
|
|
- t1 = get_cycles();
|
|
|
- for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) {
|
|
|
- if (!pit_expect_msb(expect))
|
|
|
- goto failed;
|
|
|
+ if (pit_expect_msb(0xff, &tsc, &d1)) {
|
|
|
+ for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) {
|
|
|
+ if (!pit_expect_msb(0xff-i, &delta, &d2))
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Iterate until the error is less than 500 ppm
|
|
|
+ */
|
|
|
+ delta -= tsc;
|
|
|
+ if (d1+d2 < delta >> 11)
|
|
|
+ goto success;
|
|
|
}
|
|
|
- t2 = get_cycles();
|
|
|
-
|
|
|
- /*
|
|
|
- * Make sure we can rely on the second TSC timestamp:
|
|
|
- */
|
|
|
- if (!pit_expect_msb(expect))
|
|
|
- goto failed;
|
|
|
-
|
|
|
- /*
|
|
|
- * Ok, if we get here, then we've seen the
|
|
|
- * MSB of the PIT decrement QUICK_PIT_ITERATIONS
|
|
|
- * times, and each MSB had many hits, so we never
|
|
|
- * had any sudden jumps.
|
|
|
- *
|
|
|
- * As a result, we can depend on there not being
|
|
|
- * any odd delays anywhere, and the TSC reads are
|
|
|
- * reliable.
|
|
|
- *
|
|
|
- * kHz = ticks / time-in-seconds / 1000;
|
|
|
- * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000
|
|
|
- * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000)
|
|
|
- */
|
|
|
- delta = (t2 - t1)*PIT_TICK_RATE;
|
|
|
- do_div(delta, QUICK_PIT_ITERATIONS*256*1000);
|
|
|
- printk("Fast TSC calibration using PIT\n");
|
|
|
- return delta;
|
|
|
}
|
|
|
-failed:
|
|
|
+ printk("Fast TSC calibration failed\n");
|
|
|
return 0;
|
|
|
+
|
|
|
+success:
|
|
|
+ /*
|
|
|
+ * Ok, if we get here, then we've seen the
|
|
|
+ * MSB of the PIT decrement 'i' times, and the
|
|
|
+ * error has shrunk to less than 500 ppm.
|
|
|
+ *
|
|
|
+ * As a result, we can depend on there not being
|
|
|
+ * any odd delays anywhere, and the TSC reads are
|
|
|
+ * reliable (within the error). We also adjust the
|
|
|
+ * delta to the middle of the error bars, just
|
|
|
+ * because it looks nicer.
|
|
|
+ *
|
|
|
+ * kHz = ticks / time-in-seconds / 1000;
|
|
|
+ * kHz = (t2 - t1) / (I * 256 / PIT_TICK_RATE) / 1000
|
|
|
+ * kHz = ((t2 - t1) * PIT_TICK_RATE) / (I * 256 * 1000)
|
|
|
+ */
|
|
|
+ delta += (long)(d2 - d1)/2;
|
|
|
+ delta *= PIT_TICK_RATE;
|
|
|
+ do_div(delta, i*256*1000);
|
|
|
+ printk("Fast TSC calibration using PIT\n");
|
|
|
+ return delta;
|
|
|
}
|
|
|
|
|
|
/**
|