|
@@ -80,3 +80,58 @@ void __init plat_time_init(void)
|
|
|
clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
|
|
|
clocksource_register(&clocksource_mips);
|
|
|
}
|
|
|
+
|
|
|
+static u64 octeon_udelay_factor;
|
|
|
+static u64 octeon_ndelay_factor;
|
|
|
+
|
|
|
+void __init octeon_setup_delays(void)
|
|
|
+{
|
|
|
+ octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
|
|
|
+ /*
|
|
|
+ * For __ndelay we divide by 2^16, so the factor is multiplied
|
|
|
+ * by the same amount.
|
|
|
+ */
|
|
|
+ octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
|
|
|
+
|
|
|
+ preset_lpj = octeon_get_clock_rate() / HZ;
|
|
|
+}
|
|
|
+
|
|
|
+void __udelay(unsigned long us)
|
|
|
+{
|
|
|
+ u64 cur, end, inc;
|
|
|
+
|
|
|
+ cur = read_c0_cvmcount();
|
|
|
+
|
|
|
+ inc = us * octeon_udelay_factor;
|
|
|
+ end = cur + inc;
|
|
|
+
|
|
|
+ while (end > cur)
|
|
|
+ cur = read_c0_cvmcount();
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__udelay);
|
|
|
+
|
|
|
+void __ndelay(unsigned long ns)
|
|
|
+{
|
|
|
+ u64 cur, end, inc;
|
|
|
+
|
|
|
+ cur = read_c0_cvmcount();
|
|
|
+
|
|
|
+ inc = ((ns * octeon_ndelay_factor) >> 16);
|
|
|
+ end = cur + inc;
|
|
|
+
|
|
|
+ while (end > cur)
|
|
|
+ cur = read_c0_cvmcount();
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__ndelay);
|
|
|
+
|
|
|
+void __delay(unsigned long loops)
|
|
|
+{
|
|
|
+ u64 cur, end;
|
|
|
+
|
|
|
+ cur = read_c0_cvmcount();
|
|
|
+ end = cur + loops;
|
|
|
+
|
|
|
+ while (end > cur)
|
|
|
+ cur = read_c0_cvmcount();
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__delay);
|