
Wolfgang Denk wrote:
In message 265CBF1670611D47B47E67959D02EBE3C381D8@mngilex001.Jerusalem.mangodsp.com you wrote:
The get_timer() function in DaVinci's timer.c doesn't handle overflow -- it simply subtracts the "base" from the current time, but if the timer overflowed and the current time is smaller than base, a negative number results. The attached patch fixes that.
I think this is the wrong approach. get_timer() should not have to deal with wrap arounds, because get_timer_masked() is suppsoed to handle this internally. So please fix it there.
Do you like to test this? It should decrease the counter values from the timer running at high frequency by division. With this, we should have some more time before timestamp wraps around.
Signed-off-by: Dirk Behme dirk.behme@gmail.com
Index: uboot_davinci/cpu/arm926ejs/davinci/timer.c =================================================================== --- uboot_davinci.orig/cpu/arm926ejs/davinci/timer.c +++ uboot_davinci/cpu/arm926ejs/davinci/timer.c @@ -61,6 +61,11 @@ davinci_timer *timer = (davinci_timer * #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)