]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/arm926ejs/davinci/timer.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[u-boot] / arch / arm / cpu / arm926ejs / davinci / timer.c
1 /*
2  * (C) Copyright 2003
3  * Texas Instruments <www.ti.com>
4  *
5  * (C) Copyright 2002
6  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7  * Marius Groeger <mgroeger@sysgo.de>
8  *
9  * (C) Copyright 2002
10  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
11  * Alex Zuepke <azu@sysgo.de>
12  *
13  * (C) Copyright 2002-2004
14  * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
15  *
16  * (C) Copyright 2004
17  * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
18  *
19  * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
20  *
21  * See file CREDITS for list of people who contributed to this
22  * project.
23  *
24  * This program is free software; you can redistribute it and/or
25  * modify it under the terms of the GNU General Public License as
26  * published by the Free Software Foundation; either version 2 of
27  * the License, or (at your option) any later version.
28  *
29  * This program is distributed in the hope that it will be useful,
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  * GNU General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License
35  * along with this program; if not, write to the Free Software
36  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37  * MA 02111-1307 USA
38  */
39
40 #include <common.h>
41 #include <asm/io.h>
42 #include <asm/arch/timer_defs.h>
43 #include <div64.h>
44
45 DECLARE_GLOBAL_DATA_PTR;
46
47 static struct davinci_timer * const timer =
48         (struct davinci_timer *)CONFIG_SYS_TIMERBASE;
49
50 #define TIMER_LOAD_VAL  0xffffffff
51
52 #define TIM_CLK_DIV     16
53
54 int timer_init(void)
55 {
56         /* We are using timer34 in unchained 32-bit mode, full speed */
57         writel(0x0, &timer->tcr);
58         writel(0x0, &timer->tgcr);
59         writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
60         writel(0x0, &timer->tim34);
61         writel(TIMER_LOAD_VAL, &timer->prd34);
62         writel(2 << 22, &timer->tcr);
63         gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
64         gd->timer_reset_value = 0;
65
66         return(0);
67 }
68
69 /*
70  * Get the current 64 bit timer tick count
71  */
72 unsigned long long get_ticks(void)
73 {
74         unsigned long now = readl(&timer->tim34);
75
76         /* increment tbu if tbl has rolled over */
77         if (now < gd->tbl)
78                 gd->tbu++;
79         gd->tbl = now;
80
81         return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
82 }
83
84 ulong get_timer(ulong base)
85 {
86         unsigned long long timer_diff;
87
88         timer_diff = get_ticks() - gd->timer_reset_value;
89
90         return lldiv(timer_diff, (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
91 }
92
93 void __udelay(unsigned long usec)
94 {
95         unsigned long long endtime;
96
97         endtime = lldiv((unsigned long long)usec * gd->timer_rate_hz,
98                         1000000UL);
99         endtime += get_ticks();
100
101         while (get_ticks() < endtime)
102                 ;
103 }
104
105 /*
106  * This function is derived from PowerPC code (timebase clock frequency).
107  * On ARM it returns the number of timer ticks per second.
108  */
109 ulong get_tbclk(void)
110 {
111         return gd->timer_rate_hz;
112 }
113
114 #ifdef CONFIG_HW_WATCHDOG
115 static struct davinci_timer * const wdttimer =
116         (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE;
117
118 /*
119  * See prufw2.pdf for using Timer as a WDT
120  */
121 void davinci_hw_watchdog_enable(void)
122 {
123         writel(0x0, &wdttimer->tcr);
124         writel(0x0, &wdttimer->tgcr);
125         /* TIMMODE = 2h */
126         writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr);
127         writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12);
128         writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34);
129         writel(2 << 22, &wdttimer->tcr);
130         writel(0x0, &wdttimer->tim12);
131         writel(0x0, &wdttimer->tim34);
132         /* set WDEN bit, WDKEY 0xa5c6 */
133         writel(0xa5c64000, &wdttimer->wdtcr);
134         /* clear counter register */
135         writel(0xda7e4000, &wdttimer->wdtcr);
136 }
137
138 void davinci_hw_watchdog_reset(void)
139 {
140         writel(0xa5c64000, &wdttimer->wdtcr);
141         writel(0xda7e4000, &wdttimer->wdtcr);
142 }
143 #endif