--- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -177,6 +178,58 @@ bool plat_cpu_core_present(int core) return true; } +#define LPS_PREC 8 +/* +* Re-calibration lpj(loop-per-jiffy). +* (derived from kernel/calibrate.c) +*/ +static int udelay_recal(void) +{ + unsigned int i, lpj = 0; + unsigned long ticks, loopbit; + int lps_precision = LPS_PREC; + + lpj = (1<<12); + + while ((lpj <<= 1) != 0) { + /* wait for "start of" clock tick */ + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + + /* Go .. */ + ticks = jiffies; + __delay(lpj); + ticks = jiffies - ticks; + if (ticks) + break; + } + + /* + * Do a binary approximation to get lpj set to + * equal one clock (up to lps_precision bits) + */ + lpj >>= 1; + loopbit = lpj; + while (lps_precision-- && (loopbit >>= 1)) { + lpj |= loopbit; + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + ticks = jiffies; + __delay(lpj); + if (jiffies != ticks) /* longer than 1 tick */ + lpj &= ~loopbit; + } + printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj); + + for(i=0; i< NR_CPUS; i++) + cpu_data[i].udelay_val = lpj; + + return 0; +} +device_initcall(udelay_recal); + void prom_soc_init(struct ralink_soc_info *soc_info) { void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE); --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -58,6 +58,7 @@ choice select CLKSRC_MIPS_GIC select HW_HAS_PCI select WEAK_REORDERING_BEYOND_LLSC + select GENERIC_CLOCKEVENTS_BROADCAST endchoice choice --- a/arch/mips/ralink/timer-gic.c +++ b/arch/mips/ralink/timer-gic.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "common.h" @@ -19,6 +20,8 @@ void __init plat_time_init(void) { ralink_of_remap(); + mips_hpt_frequency = 880000000 / 2; + of_clk_init(NULL); timer_probe(); }