1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <common.h>
21#include <asm/io.h>
22#include <asm/arch/ftpmu010.h>
23#include <asm/arch/fttmr010.h>
24
25static ulong timestamp;
26static ulong lastdec;
27
28static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
29static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
30
31#define TIMER_CLOCK 32768
32#define TIMER_LOAD_VAL 0xffffffff
33
34int timer_init(void)
35{
36 unsigned int oscc;
37 unsigned int cr;
38
39 debug("%s()\n", __func__);
40
41
42 writel(0, &tmr->cr);
43
44
45
46
47
48
49 oscc = readl(&pmu->OSCC);
50 oscc &= ~(FTPMU010_OSCC_OSCL_OFF | FTPMU010_OSCC_OSCL_TRI);
51 writel(oscc, &pmu->OSCC);
52
53
54 while (!(readl(&pmu->OSCC) & FTPMU010_OSCC_OSCL_STABLE))
55 ;
56
57
58 oscc = readl(&pmu->OSCC);
59 oscc |= FTPMU010_OSCC_OSCL_RTCLSEL;
60 writel(oscc, &pmu->OSCC);
61
62
63 writel(TIMER_LOAD_VAL, &tmr->timer3_load);
64 writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
65 writel(0, &tmr->timer3_match1);
66 writel(0, &tmr->timer3_match2);
67
68
69 writel(FTTMR010_TM3_MATCH1 |
70 FTTMR010_TM3_MATCH2 |
71 FTTMR010_TM3_OVERFLOW,
72 &tmr->interrupt_mask);
73
74 cr = readl(&tmr->cr);
75 cr |= FTTMR010_TM3_CLOCK;
76 cr |= FTTMR010_TM3_ENABLE;
77 writel(cr, &tmr->cr);
78
79
80 reset_timer_masked();
81
82 return 0;
83}
84
85
86
87
88
89
90
91
92void reset_timer_masked(void)
93{
94
95 lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
96 timestamp = 0;
97
98 debug("%s(): lastdec = %lx\n", __func__, lastdec);
99}
100
101void reset_timer(void)
102{
103 debug("%s()\n", __func__);
104 reset_timer_masked();
105}
106
107
108
109
110ulong get_timer_masked(void)
111{
112
113 ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
114
115 debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
116
117 if (lastdec >= now) {
118
119
120
121
122 timestamp += lastdec - now;
123 } else {
124
125
126
127
128
129
130
131
132
133 timestamp += lastdec + TIMER_LOAD_VAL - now;
134 }
135
136 lastdec = now;
137
138 debug("%s() returns %lx\n", __func__, timestamp);
139
140 return timestamp;
141}
142
143
144
145
146ulong get_timer(ulong base)
147{
148 debug("%s(%lx)\n", __func__, base);
149 return get_timer_masked() - base;
150}
151
152void set_timer(ulong t)
153{
154 debug("%s(%lx)\n", __func__, t);
155 timestamp = t;
156}
157
158
159void udelay(unsigned long usec)
160{
161 long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
162 unsigned long now, last = readl(&tmr->timer3_counter);
163
164 debug("%s(%lu)\n", __func__, usec);
165 while (tmo > 0) {
166 now = readl(&tmr->timer3_counter);
167 if (now > last)
168 tmo -= TIMER_LOAD_VAL + last - now;
169 else
170 tmo -= last - now;
171 last = now;
172 }
173}
174
175
176
177
178
179unsigned long long get_ticks(void)
180{
181 debug("%s()\n", __func__);
182 return get_timer(0);
183}
184
185
186
187
188
189ulong get_tbclk(void)
190{
191 debug("%s()\n", __func__);
192 return CONFIG_SYS_HZ;
193}
194