]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/mips/au1000/common/time.c
[MIPS] Alchemy: work around clock misdetection on early Au1000
[linux-2.6-omap-h63xx.git] / arch / mips / au1000 / common / time.c
index 726c340460b6544f2a62d65d8657638e5c558b1d..e122bbc6cd88ff640d957df1d164a472ea288137 100644 (file)
@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(time_lock);
 unsigned long wtimer;
 
 #ifdef CONFIG_PM
-irqreturn_t counter0_irq(int irq, void *dev_id)
+static irqreturn_t counter0_irq(int irq, void *dev_id)
 {
        unsigned long pc0;
        int time_elapsed;
@@ -117,6 +117,13 @@ irqreturn_t counter0_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+struct irqaction counter0_action = {
+       .handler        = counter0_irq,
+       .flags          = IRQF_DISABLED,
+       .name           = "alchemy-toy",
+       .dev_id         = NULL,
+};
+
 /* When we wakeup from sleep, we have to "catch up" on all of the
  * timer ticks we have missed.
  */
@@ -200,20 +207,24 @@ unsigned long cal_r4koff(void)
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
 
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
-               au_writel (0, SYS_TOYWRITE);
+               au_writel(0, SYS_TOYWRITE);
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+       } else
+               no_au1xxx_32khz = 1;
 
-               cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) *
-                       AU1000_SRC_CLK;
-       }
-       else {
-               /* The 32KHz oscillator isn't running, so assume there
-                * isn't one and grab the processor speed from the PLL.
-                * NOTE: some old silicon doesn't allow reading the PLL.
-                */
+       /*
+        * On early Au1000, sys_cpupll was write-only. Since these
+        * silicon versions of Au1000 are not sold by AMD, we don't bend
+        * over backwards trying to determine the frequency.
+        */
+       if (cur_cpu_spec[0]->cpu_pll_wo)
+#ifdef CONFIG_SOC_AU1000_FREQUENCY
+               cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
+#else
+               cpu_speed = 396000000;
+#endif
+       else
                cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
-               no_au1xxx_32khz = 1;
-       }
        mips_hpt_frequency = cpu_speed;
        // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
        set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
@@ -221,7 +232,7 @@ unsigned long cal_r4koff(void)
        return (cpu_speed / HZ);
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
+void __init plat_time_init(void)
 {
        unsigned int est_freq;
 
@@ -255,15 +266,10 @@ void __init plat_timer_setup(struct irqaction *irq)
         * we do this.
         */
        if (no_au1xxx_32khz) {
-               unsigned int c0_status;
-
                printk("WARNING: no 32KHz clock found.\n");
 
-               /* Ensure we get CPO_COUNTER interrupts.
-               */
-               c0_status = read_c0_status();
-               c0_status |= IE_IRQ5;
-               write_c0_status(c0_status);
+               /* Ensure we get CPO_COUNTER interrupts.  */
+               set_c0_status(IE_IRQ5);
        }
        else {
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
@@ -280,7 +286,7 @@ void __init plat_timer_setup(struct irqaction *irq)
                au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
                au_sync();
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
-               startup_match20_interrupt(counter0_irq);
+               setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
 
                /* We can use the real 'wait' instruction.
                */