aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/amazon/patches-2.6.30/220-fix_timer.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/amazon/patches-2.6.30/220-fix_timer.patch')
-rw-r--r--target/linux/amazon/patches-2.6.30/220-fix_timer.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/target/linux/amazon/patches-2.6.30/220-fix_timer.patch b/target/linux/amazon/patches-2.6.30/220-fix_timer.patch
new file mode 100644
index 0000000000..6408b88f91
--- /dev/null
+++ b/target/linux/amazon/patches-2.6.30/220-fix_timer.patch
@@ -0,0 +1,93 @@
+--- a/arch/mips/amazon/setup.c
++++ b/arch/mips/amazon/setup.c
+@@ -36,6 +36,12 @@
+ #include <asm/amazon/irq.h>
+ #include <asm/amazon/model.h>
+
++static unsigned int r4k_offset;
++static unsigned int r4k_cur;
++
++/* required in arch/mips/kernel/kspd.c */
++unsigned long cpu_khz;
++
+ extern void prom_printf(const char * fmt, ...);
+ static void amazon_reboot_setup(void);
+
+@@ -91,35 +97,32 @@ unsigned int amazon_get_cpu_ver(void)
+ return cpu_ver;
+ }
+
+-void amazon_time_init(void)
++static inline u32 amazon_get_counter_resolution(void)
+ {
+- mips_hpt_frequency = amazon_get_cpu_hz()/2;
+- printk("mips_hpt_frequency:%d\n", mips_hpt_frequency);
++ u32 res;
++ __asm__ __volatile__(
++ ".set push\n"
++ ".set mips32r2\n"
++ ".set noreorder\n"
++ "rdhwr %0, $3\n"
++ "ehb\n"
++ ".set pop\n"
++ : "=&r" (res)
++ : /* no input */
++ : "memory");
++ instruction_hazard();
++ return res;
+ }
+
+-extern int hr_time_resolution;
+-
+-/* ISR GPTU Timer 6 for high resolution timer */
+-static void amazon_timer6_interrupt(int irq, void *dev_id)
++void __init plat_time_init(void)
+ {
+- timer_interrupt(AMAZON_TIMER6_INT, NULL);
+-}
+-
+-static struct irqaction hrt_irqaction = {
+- .handler = amazon_timer6_interrupt,
+- .flags = IRQF_DISABLED,
+- .name = "hrt",
+-};
++ mips_hpt_frequency = amazon_get_cpu_hz() / amazon_get_counter_resolution();
++ r4k_offset = mips_hpt_frequency / HZ;
++ printk("mips_hpt_frequency:%d\n", mips_hpt_frequency);
++ printk("r4k_offset: %08x(%d)\n", r4k_offset, r4k_offset);
+
+-/*
+- * THe CPU counter for System timer, set to HZ
+- * GPTU Timer 6 for high resolution timer, set to hr_time_resolution
+- * Also misuse this routine to print out the CPU type and clock.
+- */
+-void __init plat_timer_setup(struct irqaction *irq)
+-{
+- /* cpu counter for timer interrupts */
+- setup_irq(MIPS_CPU_TIMER_IRQ, irq);
++ r4k_cur = (read_c0_count() + r4k_offset);
++ write_c0_compare(r4k_cur);
+
+ /* enable the timer in the PMU */
+ amazon_writel(amazon_readl(AMAZON_PMU_PWDCR)| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI, AMAZON_PMU_PWDCR);
+@@ -147,7 +150,6 @@ void __init plat_mem_setup(void)
+ }
+
+ amazon_reboot_setup();
+- board_time_init = amazon_time_init;
+
+ //stop reset TPE and DFE
+ amazon_writel(0, AMAZON_RST_REQ);
+--- a/arch/mips/amazon/interrupt.c
++++ b/arch/mips/amazon/interrupt.c
+@@ -184,3 +184,10 @@ void __init arch_init_irq(void)
+ set_irq_chip(i, &amazon_irq_type);
+ }
+ }
++
++void __cpuinit arch_fixup_c0_irqs(void)
++{
++ /* FIXME: check for CPUID and only do fix for specific chips/versions */
++ cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
++ cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ;
++}