From ea686f52e45b3df2938866d3f5a98bb2556dfe2b Mon Sep 17 00:00:00 2001
From: Peter Pearse <peter.pearse@arm.com>
Date: Fri, 1 Feb 2008 16:50:24 +0000
Subject: [PATCH] Fix timer overflow in DaVinci Signed-off-by: Dirk Behme
 <dirk.behme@gmail.com>

---
 cpu/arm926ejs/davinci/timer.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/cpu/arm926ejs/davinci/timer.c b/cpu/arm926ejs/davinci/timer.c
index c6b1dda51f..4a1a54dcf1 100644
--- a/cpu/arm926ejs/davinci/timer.c
+++ b/cpu/arm926ejs/davinci/timer.c
@@ -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)
-- 
2.39.5