1
2
3
4
5
6
7
8#include <common.h>
9#include <div64.h>
10#include <asm/io.h>
11#include <faraday/ftpmu010.h>
12#include <faraday/fttmr010.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
16#define TIMER_CLOCK 32768
17#define TIMER_LOAD_VAL 0xffffffff
18
19static inline unsigned long long tick_to_time(unsigned long long tick)
20{
21 tick *= CONFIG_SYS_HZ;
22 do_div(tick, gd->arch.timer_rate_hz);
23
24 return tick;
25}
26
27static inline unsigned long long usec_to_tick(unsigned long long usec)
28{
29 usec *= gd->arch.timer_rate_hz;
30 do_div(usec, 1000000);
31
32 return usec;
33}
34
35int timer_init(void)
36{
37 struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
38 unsigned int cr;
39
40 debug("%s()\n", __func__);
41
42
43 writel(0, &tmr->cr);
44
45
46 ftpmu010_32768osc_enable();
47
48
49 writel(TIMER_LOAD_VAL, &tmr->timer3_load);
50 writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
51 writel(0, &tmr->timer3_match1);
52 writel(0, &tmr->timer3_match2);
53
54
55 writel(FTTMR010_TM3_MATCH1 |
56 FTTMR010_TM3_MATCH2 |
57 FTTMR010_TM3_OVERFLOW,
58 &tmr->interrupt_mask);
59
60 cr = readl(&tmr->cr);
61 cr |= FTTMR010_TM3_CLOCK;
62 cr |= FTTMR010_TM3_ENABLE;
63 writel(cr, &tmr->cr);
64
65 gd->arch.timer_rate_hz = TIMER_CLOCK;
66 gd->arch.tbu = gd->arch.tbl = 0;
67
68 return 0;
69}
70
71
72
73
74unsigned long long get_ticks(void)
75{
76 struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
77 ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
78
79
80 if (now < gd->arch.tbl)
81 gd->arch.tbu++;
82 gd->arch.tbl = now;
83 return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
84}
85
86void __udelay(unsigned long usec)
87{
88 unsigned long long start;
89 ulong tmo;
90
91 start = get_ticks();
92 tmo = usec_to_tick(usec);
93 while ((get_ticks() - start) < tmo)
94 ;
95}
96
97
98
99
100
101
102
103
104
105
106
107ulong get_timer(ulong base)
108{
109 return tick_to_time(get_ticks()) - base;
110}
111
112
113
114
115ulong get_tbclk(void)
116{
117 return gd->arch.timer_rate_hz;
118}
119