|
@@ -91,48 +91,6 @@ static struct clocksource clocksource_mips = {
|
|
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
|
|
};
|
|
|
|
|
|
-static unsigned int __init calibrate_hpt(void)
|
|
|
-{
|
|
|
- cycle_t frequency, hpt_start, hpt_end, hpt_count, hz;
|
|
|
-
|
|
|
- const int loops = HZ / 10;
|
|
|
- int log_2_loops = 0;
|
|
|
- int i;
|
|
|
-
|
|
|
- /*
|
|
|
- * We want to calibrate for 0.1s, but to avoid a 64-bit
|
|
|
- * division we round the number of loops up to the nearest
|
|
|
- * power of 2.
|
|
|
- */
|
|
|
- while (loops > 1 << log_2_loops)
|
|
|
- log_2_loops++;
|
|
|
- i = 1 << log_2_loops;
|
|
|
-
|
|
|
- /*
|
|
|
- * Wait for a rising edge of the timer interrupt.
|
|
|
- */
|
|
|
- while (mips_timer_state());
|
|
|
- while (!mips_timer_state());
|
|
|
-
|
|
|
- /*
|
|
|
- * Now see how many high precision timer ticks happen
|
|
|
- * during the calculated number of periods between timer
|
|
|
- * interrupts.
|
|
|
- */
|
|
|
- hpt_start = clocksource_mips.read();
|
|
|
- do {
|
|
|
- while (mips_timer_state());
|
|
|
- while (!mips_timer_state());
|
|
|
- } while (--i);
|
|
|
- hpt_end = clocksource_mips.read();
|
|
|
-
|
|
|
- hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask;
|
|
|
- hz = HZ;
|
|
|
- frequency = hpt_count * hz;
|
|
|
-
|
|
|
- return frequency >> log_2_loops;
|
|
|
-}
|
|
|
-
|
|
|
void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
|
|
|
{
|
|
|
u64 temp;
|
|
@@ -194,21 +152,42 @@ void __init plat_timer_setup(void)
|
|
|
BUG();
|
|
|
}
|
|
|
|
|
|
+static __init int cpu_has_mfc0_count_bug(void)
|
|
|
+{
|
|
|
+ switch (current_cpu_type()) {
|
|
|
+ case CPU_R4000PC:
|
|
|
+ case CPU_R4000SC:
|
|
|
+ case CPU_R4000MC:
|
|
|
+ /*
|
|
|
+ * V3.0 is documented as suffering from the mfc0 from count bug.
|
|
|
+ * Afaik this is the last version of the R4000. Later versions
|
|
|
+ * were marketed as R4400.
|
|
|
+ */
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ case CPU_R4400PC:
|
|
|
+ case CPU_R4400SC:
|
|
|
+ case CPU_R4400MC:
|
|
|
+ /*
|
|
|
+ * The published errata for the R4400 upto 3.0 say the CPU
|
|
|
+ * has the mfc0 from count bug.
|
|
|
+ */
|
|
|
+ if ((current_cpu_data.processor_id & 0xff) <= 0x30)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * I don't have erratas for newer R4400 so be paranoid.
|
|
|
+ */
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
void __init time_init(void)
|
|
|
{
|
|
|
plat_time_init();
|
|
|
|
|
|
- if (cpu_has_counter && (mips_hpt_frequency || mips_timer_state)) {
|
|
|
- /* We know counter frequency. Or we can get it. */
|
|
|
- if (!mips_hpt_frequency)
|
|
|
- mips_hpt_frequency = calibrate_hpt();
|
|
|
-
|
|
|
- /* Report the high precision timer rate for a reference. */
|
|
|
- printk("Using %u.%03u MHz high precision timer.\n",
|
|
|
- ((mips_hpt_frequency + 500) / 1000) / 1000,
|
|
|
- ((mips_hpt_frequency + 500) / 1000) % 1000);
|
|
|
+ if (mips_clockevent_init() || !cpu_has_mfc0_count_bug())
|
|
|
init_mips_clocksource();
|
|
|
- }
|
|
|
-
|
|
|
- mips_clockevent_init();
|
|
|
}
|