Merge branch 'master' of git://git.denx.de/u-boot-blackfin
[platform/kernel/u-boot.git] / cpu / nios2 / interrupts.c
index aeb5b65..b552db4 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <nios2.h>
 #include <nios2-io.h>
+#include <asm/types.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
 #include <common.h>
@@ -36,8 +37,8 @@
 #include <status_led.h>
 #endif
 
-#if defined(CFG_NIOS_TMRBASE) && !defined(CFG_NIOS_TMRIRQ)
-#error CFG_NIOS_TMRIRQ not defined (see documentation)
+#if defined(CONFIG_SYS_NIOS_TMRBASE) && !defined(CONFIG_SYS_NIOS_TMRIRQ)
+#error CONFIG_SYS_NIOS_TMRIRQ not defined (see documentation)
 #endif
 
 /****************************************************************************/
@@ -55,7 +56,40 @@ volatile ulong timestamp = 0;
 
 void reset_timer (void)
 {
+       nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE;
+
+       /* From Embedded Peripherals Handbook:
+        *
+        * "When the hardware is configured with Writeable period
+        * disabled, writing to one of the period_n registers causes
+        * the counter to reset to the fixed Timeout Period specified
+        * at system generation time."
+        *
+        * Here we force a reload to prevent early timeouts from
+        * get_timer() when the interrupt period is greater than
+        * than 1 msec.
+        *
+        * Simply write to periodl with its own value to force an
+        * internal counter reload, THEN reset the timestamp.
+        */
+       writel (readl (&tmr->periodl), &tmr->periodl);
        timestamp = 0;
+
+       /* From Embedded Peripherals Handbook:
+        *
+        * "Writing to one of the period_n registers stops the internal
+        * counter, except when the hardware is configured with Start/Stop
+        * control bits off. If Start/Stop control bits is off, writing
+        * either register does not stop the counter."
+        *
+        * In order to accomodate either configuration, the control
+        * register is re-written. If the counter is stopped, it will
+        * be restarted. If it is running, the write is essentially
+        * a nop.
+        */
+       writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START,
+                       &tmr->control);
+
 }
 
 ulong get_timer (ulong base)
@@ -73,15 +107,15 @@ void set_timer (ulong t)
 /* The board must handle this interrupt if a timer is not
  * provided.
  */
-#if defined(CFG_NIOS_TMRBASE)
+#if defined(CONFIG_SYS_NIOS_TMRBASE)
 void tmr_isr (void *arg)
 {
        nios_timer_t *tmr = (nios_timer_t *)arg;
        /* Interrupt is cleared by writing anything to the
         * status register.
         */
-       writel (&tmr->status, 0);
-       timestamp += CFG_NIOS_TMRMS;
+       writel (0, &tmr->status);
+       timestamp += CONFIG_SYS_NIOS_TMRMS;
 #ifdef CONFIG_STATUS_LED
        status_led_tick(timestamp);
 #endif
@@ -89,22 +123,22 @@ void tmr_isr (void *arg)
 
 static void tmr_init (void)
 {
-       nios_timer_t *tmr =(nios_timer_t *)CFG_NIOS_TMRBASE;
+       nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE;
 
-       writel (&tmr->status, 0);
-       writel (&tmr->control, 0);
-       writel (&tmr->control, NIOS_TIMER_STOP);
+       writel (0, &tmr->status);
+       writel (0, &tmr->control);
+       writel (NIOS_TIMER_STOP, &tmr->control);
 
-#if defined(CFG_NIOS_TMRCNT)
-       writel (&tmr->periodl, CFG_NIOS_TMRCNT & 0xffff);
-       writel (&tmr->periodh, (CFG_NIOS_TMRCNT >> 16) & 0xffff);
+#if defined(CONFIG_SYS_NIOS_TMRCNT)
+       writel (CONFIG_SYS_NIOS_TMRCNT & 0xffff, &tmr->periodl);
+       writel ((CONFIG_SYS_NIOS_TMRCNT >> 16) & 0xffff, &tmr->periodh);
 #endif
-       writel (&tmr->control, NIOS_TIMER_ITO | NIOS_TIMER_CONT |
-                         NIOS_TIMER_START );
-       irq_install_handler (CFG_NIOS_TMRIRQ, tmr_isr, (void *)tmr);
+       writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START,
+                       &tmr->control);
+       irq_install_handler (CONFIG_SYS_NIOS_TMRIRQ, tmr_isr, (void *)tmr);
 }
 
-#endif /* CFG_NIOS_TMRBASE */
+#endif /* CONFIG_SYS_NIOS_TMRBASE */
 
 /*************************************************************************/
 int disable_interrupts (void)
@@ -194,7 +228,7 @@ int interrupt_init (void)
                vecs[i].count = 0;
        }
 
-#if defined(CFG_NIOS_TMRBASE)
+#if defined(CONFIG_SYS_NIOS_TMRBASE)
        tmr_init ();
 #endif