diff options
Diffstat (limited to 'cpu/arm926ejs/davinci/timer.c')
-rw-r--r-- | cpu/arm926ejs/davinci/timer.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/cpu/arm926ejs/davinci/timer.c b/cpu/arm926ejs/davinci/timer.c index 4797797..8bb8b45 100644 --- a/cpu/arm926ejs/davinci/timer.c +++ b/cpu/arm926ejs/davinci/timer.c @@ -42,9 +42,9 @@ typedef volatile struct { u_int32_t pid12; - u_int32_t emumgt; - u_int32_t na1; - u_int32_t na2; + u_int32_t emumgt_clksped; + u_int32_t gpint_en; + u_int32_t gpdir_dat; u_int32_t tim12; u_int32_t tim34; u_int32_t prd12; @@ -52,12 +52,21 @@ typedef volatile struct { u_int32_t tcr; u_int32_t tgcr; u_int32_t wdtcr; + u_int32_t tlgc; + u_int32_t tlmr; } davinci_timer; davinci_timer *timer = (davinci_timer *)CFG_TIMERBASE; #define TIMER_LOAD_VAL (CFG_HZ_CLOCK / CFG_HZ) -#define TIM_CLK_DIV 16 +#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; @@ -67,50 +76,63 @@ int timer_init(void) /* We are using timer34 in unchained 32-bit mode, full speed */ timer->tcr = 0x0; timer->tgcr = 0x0; - timer->tgcr = 0x06 | ((TIM_CLK_DIV - 1) << 8); + timer->tgcr = 0x06; timer->tim34 = 0x0; timer->prd34 = TIMER_LOAD_VAL; lastinc = 0; + timer->tcr = 0x80 << 16; timestamp = 0; - timer->tcr = 2 << 22; return(0); } void reset_timer(void) { - timer->tcr = 0x0; - timer->tim34 = 0; - lastinc = 0; + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return(get_timer_masked() - base); +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void udelay(unsigned long usec) +{ + udelay_masked(usec); +} + +void reset_timer_masked(void) +{ + lastinc = DIV(READ_TIMER); timestamp = 0; - timer->tcr = 2 << 22; } -static ulong get_timer_raw(void) +ulong get_timer_raw(void) { - ulong now = timer->tim34; + 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; } -ulong get_timer(ulong base) -{ - return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base); } - -void set_timer(ulong t) +ulong get_timer_masked(void) { - timestamp = t; + return(get_timer_raw() / DIV(TIMER_LOAD_VAL)); } -void udelay(unsigned long usec) +void udelay_masked(unsigned long usec) { ulong tmo; ulong endtime; @@ -118,7 +140,7 @@ void udelay(unsigned long usec) tmo = CFG_HZ_CLOCK / 1000; tmo *= usec; - tmo /= (1000 * TIM_CLK_DIV); + tmo /= 1000; endtime = get_timer_raw() + tmo; @@ -143,5 +165,8 @@ unsigned long long get_ticks(void) */ ulong get_tbclk(void) { - return CFG_HZ; + ulong tbclk; + + tbclk = CFG_HZ; + return(tbclk); } |