]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/omap-common/timer.c
use default fdtaddr if not set
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / omap-common / timer.c
1 /*
2  * (C) Copyright 2008
3  * Texas Instruments
4  *
5  * Richard Woodruff <r-woodruff2@ti.com>
6  * Syed Moahmmed Khasim <khasim@ti.com>
7  *
8  * (C) Copyright 2002
9  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
10  * Marius Groeger <mgroeger@sysgo.de>
11  * Alex Zuepke <azu@sysgo.de>
12  *
13  * (C) Copyright 2002
14  * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
15  *
16  * See file CREDITS for list of people who contributed to this
17  * project.
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License as
21  * published by the Free Software Foundation; either version 2 of
22  * the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32  * MA 02111-1307 USA
33  */
34
35 #include <common.h>
36 #include <div64.h>
37 #include <asm/io.h>
38 #include <asm/arch/cpu.h>
39
40 DECLARE_GLOBAL_DATA_PTR;
41
42 static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
43
44 /*
45  * Nothing really to do with interrupts, just starts up a counter.
46  */
47
48 #if CONFIG_SYS_PTV > 7
49 #error Invalid CONFIG_SYS_PTV value
50 #elif CONFIG_SYS_PTV >= 0
51 #define TIMER_CLOCK             (V_SCLK / (2 << CONFIG_SYS_PTV))
52 #define TCLR_VAL                ((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST)
53 #else
54 #define TIMER_CLOCK             V_SCLK
55 #define TCLR_VAL                (TCLR_AR | TCLR_ST)
56 #endif
57 #define TIMER_LOAD_VAL          0
58
59 #if TIMER_CLOCK < CONFIG_SYS_HZ
60 #error TIMER_CLOCK must be > CONFIG_SYS_HZ
61 #endif
62
63 /*
64  * Start timer so that it will overflow 15 sec after boot,
65  * to catch misbehaving timer code early on!
66 */
67 #define TIMER_START             (-time_to_tick(15 * CONFIG_SYS_HZ))
68
69 static inline unsigned long tick_to_time(unsigned long tick)
70 {
71         return tick / (TIMER_CLOCK / CONFIG_SYS_HZ);
72 }
73
74 static inline unsigned long time_to_tick(unsigned long time)
75 {
76         return time * (TIMER_CLOCK / CONFIG_SYS_HZ);
77 }
78
79 static inline unsigned long us_to_ticks(unsigned long usec)
80 {
81         return usec * (TIMER_CLOCK / CONFIG_SYS_HZ / 1000);
82 }
83
84 int timer_init(void)
85 {
86 #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
87         /* Reset the Timer */
88         writel(0x2, &timer_base->tscir);
89
90         /* Wait until the reset is done */
91         while (readl(&timer_base->tiocp_cfg) & 1)
92                 ;
93
94         /* preload the counter to make overflow occur early */
95         writel(TIMER_START, &timer_base->tldr);
96         writel(~0, &timer_base->ttgr);
97
98         /* start the counter ticking up, reload value on overflow */
99         writel(TIMER_LOAD_VAL, &timer_base->tldr);
100         /* enable timer */
101         writel(TCLR_VAL, &timer_base->tclr);
102 #endif
103 #ifndef CONFIG_SPL_BUILD
104         gd->lastinc = -30 * TIMER_CLOCK;
105         gd->tbl = TIMER_START;
106         gd->timer_rate_hz = TIMER_CLOCK;
107 #endif
108         return 0;
109 }
110
111 /*
112  * timer without interrupts
113  */
114 ulong get_timer(ulong base)
115 {
116         return tick_to_time(get_ticks() - time_to_tick(base));
117 }
118
119 /* delay x useconds */
120 void __udelay(unsigned long usec)
121 {
122         unsigned long start = readl(&timer_base->tcrr);
123         unsigned long ticks = us_to_ticks(usec);
124
125         if (usec == 0)
126                 return;
127
128         if (ticks == 0)
129                 ticks++;
130
131         while (readl(&timer_base->tcrr) - start < ticks)
132                 /* NOP */ ;
133 }
134
135 ulong get_timer_masked(void)
136 {
137         /* current tick value */
138         return tick_to_time(get_ticks());
139 }
140
141 /*
142  * This function is derived from PowerPC code (read timebase as long long).
143  * On ARM it just returns the timer value.
144  */
145 unsigned long long get_ticks(void)
146 {
147         ulong now = readl(&timer_base->tcrr);
148         ulong inc = now - gd->lastinc;
149
150         gd->tbl += inc;
151         gd->lastinc = now;
152         return gd->tbl;
153 }
154
155 /*
156  * This function is derived from PowerPC code (timebase clock frequency).
157  * On ARM it returns the number of timer ticks per second.
158  */
159 ulong get_tbclk(void)
160 {
161         return gd->timer_rate_hz;
162 }