Commit e465cf2377d15f1ca1fa22079c766e89ad0aaf29

Authored by Nick Thompson
Committed by Sandeep Paulraj
1 parent ac8983bcba

davinci: Rewrite timer.c to use tbl/tbu emulation variables in gd

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>

Showing 1 changed file with 28 additions and 49 deletions Side-by-side Diff

arch/arm/cpu/arm926ejs/davinci/timer.c
... ... @@ -40,6 +40,8 @@
40 40 #include <common.h>
41 41 #include <asm/io.h>
42 42  
  43 +DECLARE_GLOBAL_DATA_PTR;
  44 +
43 45 struct davinci_timer {
44 46 u_int32_t pid12;
45 47 u_int32_t emumgt;
46 48  
... ... @@ -57,12 +59,10 @@
57 59 static struct davinci_timer * const timer =
58 60 (struct davinci_timer *)CONFIG_SYS_TIMERBASE;
59 61  
60   -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
  62 +#define TIMER_LOAD_VAL 0xffffffff
  63 +
61 64 #define TIM_CLK_DIV 16
62 65  
63   -static ulong timestamp;
64   -static ulong lastinc;
65   -
66 66 int timer_init(void)
67 67 {
68 68 /* We are using timer34 in unchained 32-bit mode, full speed */
69 69  
70 70  
71 71  
72 72  
73 73  
74 74  
75 75  
76 76  
77 77  
78 78  
... ... @@ -71,72 +71,51 @@
71 71 writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
72 72 writel(0x0, &timer->tim34);
73 73 writel(TIMER_LOAD_VAL, &timer->prd34);
74   - lastinc = 0;
75   - timestamp = 0;
76 74 writel(2 << 22, &timer->tcr);
  75 + gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
  76 + gd->timer_reset_value = 0;
77 77  
78 78 return(0);
79 79 }
80 80  
81 81 void reset_timer(void)
82 82 {
83   - writel(0x0, &timer->tcr);
84   - writel(0x0, &timer->tim34);
85   - lastinc = 0;
86   - timestamp = 0;
87   - writel(2 << 22, &timer->tcr);
  83 + gd->timer_reset_value = get_ticks();
88 84 }
89 85  
90   -static ulong get_timer_raw(void)
  86 +/*
  87 + * Get the current 64 bit timer tick count
  88 + */
  89 +unsigned long long get_ticks(void)
91 90 {
92   - ulong now = readl(&timer->tim34);
  91 + unsigned long now = readl(&timer->tim34);
93 92  
94   - if (now >= lastinc) {
95   - /* normal mode */
96   - timestamp += now - lastinc;
97   - } else {
98   - /* overflow ... */
99   - timestamp += now + TIMER_LOAD_VAL - lastinc;
100   - }
101   - lastinc = now;
102   - return timestamp;
  93 + /* increment tbu if tbl has rolled over */
  94 + if (now < gd->tbl)
  95 + gd->tbu++;
  96 + gd->tbl = now;
  97 +
  98 + return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
103 99 }
104 100  
105 101 ulong get_timer(ulong base)
106 102 {
107   - return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base);
108   -}
  103 + unsigned long long timer_diff;
109 104  
110   -void set_timer(ulong t)
111   -{
112   - timestamp = t;
  105 + timer_diff = get_ticks() - gd->timer_reset_value;
  106 +
  107 + return (timer_diff / (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
113 108 }
114 109  
115 110 void __udelay(unsigned long usec)
116 111 {
117   - ulong tmo;
118   - ulong endtime;
119   - signed long diff;
  112 + unsigned long long endtime;
120 113  
121   - tmo = CONFIG_SYS_HZ_CLOCK / 1000;
122   - tmo *= usec;
123   - tmo /= (1000 * TIM_CLK_DIV);
  114 + endtime = ((unsigned long long)usec * gd->timer_rate_hz) / 1000000UL;
  115 + endtime += get_ticks();
124 116  
125   - endtime = get_timer_raw() + tmo;
126   -
127   - do {
128   - ulong now = get_timer_raw();
129   - diff = endtime - now;
130   - } while (diff >= 0);
131   -}
132   -
133   -/*
134   - * This function is derived from PowerPC code (read timebase as long long).
135   - * On ARM it just returns the timer value.
136   - */
137   -unsigned long long get_ticks(void)
138   -{
139   - return(get_timer(0));
  117 + while (get_ticks() < endtime)
  118 + ;
140 119 }
141 120  
142 121 /*