Fix timer overflow in DaVinci
authorPeter Pearse <peter.pearse@arm.com>
Fri, 1 Feb 2008 16:50:24 +0000 (16:50 +0000)
committerPeter Pearse <peter.pearse@arm.com>
Thu, 14 Feb 2008 09:37:42 +0000 (09:37 +0000)
Signed-off-by: Dirk Behme <dirk.behme@gmail.com>
cpu/arm926ejs/davinci/timer.c

index c6b1dda51fcf86b782c78abd8aab23655d07ce5e..4a1a54dcf1777675707a8610817c44df8f66b28c 100644 (file)
@@ -61,6 +61,11 @@ davinci_timer                *timer = (davinci_timer *)CFG_TIMERBASE;
 #define TIMER_LOAD_VAL (CFG_HZ_CLOCK / CFG_HZ)
 #define READ_TIMER     timer->tim34
 
+/* Timer runs with CFG_HZ_CLOCK, currently 27MHz. To avoid wrap 
+   around of timestamp already after min ~159s, divide it, e.g. by 16.
+   timestamp will then wrap around all min ~42min */
+#define DIV(x)          ((x) >> 4)
+
 static ulong timestamp;
 static ulong lastinc;
 
@@ -101,20 +106,20 @@ void udelay(unsigned long usec)
 
 void reset_timer_masked(void)
 {
-       lastinc = READ_TIMER;
+        lastinc = DIV(READ_TIMER);
        timestamp = 0;
 }
 
 ulong get_timer_raw(void)
 {
-       ulong now = READ_TIMER;
+        ulong now = DIV(READ_TIMER);
 
        if (now >= lastinc) {
                /* normal mode */
                timestamp += now - lastinc;
        } else {
                /* overflow ... */
-               timestamp += now + TIMER_LOAD_VAL - lastinc;
+               timestamp += now + DIV(TIMER_LOAD_VAL) - lastinc;
        }
        lastinc = now;
        return timestamp;
@@ -122,7 +127,7 @@ ulong get_timer_raw(void)
 
 ulong get_timer_masked(void)
 {
-       return(get_timer_raw() / TIMER_LOAD_VAL);
+        return(get_timer_raw() / DIV(TIMER_LOAD_VAL));
 }
 
 void udelay_masked(unsigned long usec)