]> git.sur5r.net Git - u-boot/commitdiff
davinci: Rewrite timer.c to use tbl/tbu emulation variables in gd
authorNick Thompson <nick.thompson@ge.com>
Sat, 11 Dec 2010 15:46:46 +0000 (10:46 -0500)
committerSandeep Paulraj <s-paulraj@ti.com>
Sat, 11 Dec 2010 15:46:46 +0000 (10:46 -0500)
This change allows the davinci timer functions to be used before
relocation since it avoids using static variables prior to BSS being
made available.

The code is based on that used in the at91 timers, modified to use
a davinci specific hardware timer. It also maintains reset_timer()
to allow deprecated timer usage to continue to work (for example,
in nand_base.c)

Signed-off-by: Nick Thompson <nick.thompson@ge.com>
Tested-by: Ben Gardiner <bengardiner@nanometrics.ca>
Tested-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Tested-by: Sandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
arch/arm/cpu/arm926ejs/davinci/timer.c

index 9da7443f30b5fea4df134a932ac49739f6c9e1ee..1c6fa4ae8715ef20f428853e739a1a7234ed3744 100644 (file)
@@ -40,6 +40,8 @@
 #include <common.h>
 #include <asm/io.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 struct davinci_timer {
        u_int32_t       pid12;
        u_int32_t       emumgt;
@@ -57,11 +59,9 @@ struct davinci_timer {
 static struct davinci_timer * const timer =
        (struct davinci_timer *)CONFIG_SYS_TIMERBASE;
 
-#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
-#define TIM_CLK_DIV    16
+#define TIMER_LOAD_VAL 0xffffffff
 
-static ulong timestamp;
-static ulong lastinc;
+#define TIM_CLK_DIV    16
 
 int timer_init(void)
 {
@@ -71,72 +71,51 @@ int timer_init(void)
        writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
        writel(0x0, &timer->tim34);
        writel(TIMER_LOAD_VAL, &timer->prd34);
-       lastinc = 0;
-       timestamp = 0;
        writel(2 << 22, &timer->tcr);
+       gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
+       gd->timer_reset_value = 0;
 
        return(0);
 }
 
 void reset_timer(void)
 {
-       writel(0x0, &timer->tcr);
-       writel(0x0, &timer->tim34);
-       lastinc = 0;
-       timestamp = 0;
-       writel(2 << 22, &timer->tcr);
+       gd->timer_reset_value = get_ticks();
 }
 
-static ulong get_timer_raw(void)
+/*
+ * Get the current 64 bit timer tick count
+ */
+unsigned long long get_ticks(void)
 {
-       ulong now = readl(&timer->tim34);
-
-       if (now >= lastinc) {
-               /* normal mode */
-               timestamp += now - lastinc;
-       } else {
-               /* overflow ... */
-               timestamp += now + TIMER_LOAD_VAL - lastinc;
-       }
-       lastinc = now;
-       return timestamp;
+       unsigned long now = readl(&timer->tim34);
+
+       /* increment tbu if tbl has rolled over */
+       if (now < gd->tbl)
+               gd->tbu++;
+       gd->tbl = now;
+
+       return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
 }
 
 ulong get_timer(ulong base)
 {
-       return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base);
-}
+       unsigned long long timer_diff;
 
-void set_timer(ulong t)
-{
-       timestamp = t;
+       timer_diff = get_ticks() - gd->timer_reset_value;
+
+       return (timer_diff / (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
 }
 
 void __udelay(unsigned long usec)
 {
-       ulong tmo;
-       ulong endtime;
-       signed long diff;
-
-       tmo = CONFIG_SYS_HZ_CLOCK / 1000;
-       tmo *= usec;
-       tmo /= (1000 * TIM_CLK_DIV);
-
-       endtime = get_timer_raw() + tmo;
+       unsigned long long endtime;
 
-       do {
-               ulong now = get_timer_raw();
-               diff = endtime - now;
-       } while (diff >= 0);
-}
+       endtime = ((unsigned long long)usec * gd->timer_rate_hz) / 1000000UL;
+       endtime += get_ticks();
 
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-unsigned long long get_ticks(void)
-{
-       return(get_timer(0));
+       while (get_ticks() < endtime)
+               ;
 }
 
 /*