blob: b3123c531fa4ab24ba930a17f3520a1340e004db [file] [log] [blame]
Cyril Chemparathy37123672010-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
Cyril Chemparathy37123672010-06-07 14:13:32 -040063static ulong get_timer_raw(void)
64{
65 ulong now = __raw_readl(&regs->tim34);
66
67 if (now >= lastinc)
68 timestamp += now - lastinc;
69 else
70 timestamp += now + TIMER_LOAD_VAL - lastinc;
71
72 lastinc = now;
73
74 return timestamp;
75}
76
77ulong get_timer(ulong base)
78{
79 return (get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base;
80}
81
Cyril Chemparathy37123672010-06-07 14:13:32 -040082unsigned long long get_ticks(void)
83{
84 return get_timer(0);
85}
86
87void __udelay(unsigned long usec)
88{
89 ulong tmo;
90 ulong endtime;
91 signed long diff;
92
93 tmo = CONFIG_SYS_HZ_CLOCK / 1000;
94 tmo *= usec;
95 tmo /= (1000 * TIM_CLK_DIV);
96
97 endtime = get_timer_raw() + tmo;
98
99 do {
100 ulong now = get_timer_raw();
101 diff = endtime - now;
102 } while (diff >= 0);
103}
104
105ulong get_tbclk(void)
106{
107 return CONFIG_SYS_HZ;
108}