blob: a7a400d1e12b56f1656f52362a10d416f3c70e9f [file] [log] [blame]
Cyril Chemparathy692a7af2010-06-07 14:13:32 -04001/*
2 * TNETV107X: Timer implementation
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <common.h>
23#include <asm/io.h>
24#include <asm/arch/clock.h>
25
26struct timer_regs {
27 u_int32_t pid12;
28 u_int32_t pad[3];
29 u_int32_t tim12;
30 u_int32_t tim34;
31 u_int32_t prd12;
32 u_int32_t prd34;
33 u_int32_t tcr;
34 u_int32_t tgcr;
35 u_int32_t wdtcr;
36};
37
38#define regs ((struct timer_regs *)CONFIG_SYS_TIMERBASE)
39
40#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
41#define TIM_CLK_DIV 16
42
43static ulong timestamp;
44static ulong lastinc;
45
46int timer_init(void)
47{
48 clk_enable(TNETV107X_LPSC_TIMER0);
49
50 lastinc = timestamp = 0;
51
52 /* We are using timer34 in unchained 32-bit mode, full speed */
53 __raw_writel(0x0, &regs->tcr);
54 __raw_writel(0x0, &regs->tgcr);
55 __raw_writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &regs->tgcr);
56 __raw_writel(0x0, &regs->tim34);
57 __raw_writel(TIMER_LOAD_VAL, &regs->prd34);
58 __raw_writel(2 << 22, &regs->tcr);
59
60 return 0;
61}
62
63void reset_timer(void)
64{
65 lastinc = timestamp = 0;
66
67 __raw_writel(0, &regs->tcr);
68 __raw_writel(0, &regs->tim34);
69 __raw_writel(2 << 22, &regs->tcr);
70}
71
72static ulong get_timer_raw(void)
73{
74 ulong now = __raw_readl(&regs->tim34);
75
76 if (now >= lastinc)
77 timestamp += now - lastinc;
78 else
79 timestamp += now + TIMER_LOAD_VAL - lastinc;
80
81 lastinc = now;
82
83 return timestamp;
84}
85
86ulong get_timer(ulong base)
87{
88 return (get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base;
89}
90
91void set_timer(ulong t)
92{
93 timestamp = t;
94}
95
96unsigned long long get_ticks(void)
97{
98 return get_timer(0);
99}
100
101void __udelay(unsigned long usec)
102{
103 ulong tmo;
104 ulong endtime;
105 signed long diff;
106
107 tmo = CONFIG_SYS_HZ_CLOCK / 1000;
108 tmo *= usec;
109 tmo /= (1000 * TIM_CLK_DIV);
110
111 endtime = get_timer_raw() + tmo;
112
113 do {
114 ulong now = get_timer_raw();
115 diff = endtime - now;
116 } while (diff >= 0);
117}
118
119ulong get_tbclk(void)
120{
121 return CONFIG_SYS_HZ;
122}