blob: c8c7cdb5202b6378cee90591d29b6008a6d83819 [file] [log] [blame]
wdenk281e00a2004-08-01 22:48:16 +00001/*
2 * (C) Copyright 2002
3 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4 * Marius Groeger <mgroeger@sysgo.de>
5 *
6 * (C) Copyright 2002
7 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
8 * Alex Zuepke <azu@sysgo.de>
9 *
10 * (C) Copyright 2002
Detlev Zundel792a09e2009-05-13 10:54:10 +020011 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
wdenk281e00a2004-08-01 22:48:16 +000012 *
13 * See file CREDITS for list of people who contributed to this
14 * project.
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 */
31
32#include <common.h>
33#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
34
wdenk281e00a2004-08-01 22:48:16 +000035#if defined(CONFIG_S3C2400)
36#include <s3c2400.h>
37#elif defined(CONFIG_S3C2410)
38#include <s3c2410.h>
39#endif
40
wdenk281e00a2004-08-01 22:48:16 +000041int timer_load_val = 0;
42
43/* macro to read the 16 bit timer */
44static inline ulong READ_TIMER(void)
45{
46 S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
47
48 return (timers->TCNTO4 & 0xffff);
49}
50
51static ulong timestamp;
52static ulong lastdec;
53
Jean-Christophe PLAGNIOL-VILLARDb54384e2009-05-15 23:47:02 +020054int timer_init (void)
wdenk281e00a2004-08-01 22:48:16 +000055{
56 S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
57
58 /* use PWM Timer 4 because it has no output */
59 /* prescaler for Timer 4 is 16 */
60 timers->TCFG0 = 0x0f00;
61 if (timer_load_val == 0)
62 {
63 /*
64 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
65 * (default) and prescaler = 16. Should be 10390
66 * @33.25MHz and 15625 @ 50 MHz
67 */
68 timer_load_val = get_PCLK()/(2 * 16 * 100);
69 }
70 /* load value for 10 ms timeout */
71 lastdec = timers->TCNTB4 = timer_load_val;
72 /* auto load, manual update of Timer 4 */
73 timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;
74 /* auto load, start Timer 4 */
75 timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;
76 timestamp = 0;
77
78 return (0);
79}
80
81/*
82 * timer without interrupts
83 */
84
85void reset_timer (void)
86{
87 reset_timer_masked ();
88}
89
90ulong get_timer (ulong base)
91{
92 return get_timer_masked () - base;
93}
94
95void set_timer (ulong t)
96{
97 timestamp = t;
98}
99
100void udelay (unsigned long usec)
101{
102 ulong tmo;
103 ulong start = get_timer(0);
104
105 tmo = usec / 1000;
106 tmo *= (timer_load_val * 100);
107 tmo /= 1000;
108
109 while ((ulong)(get_timer_masked () - start) < tmo)
110 /*NOP*/;
111}
112
113void reset_timer_masked (void)
114{
115 /* reset time */
116 lastdec = READ_TIMER();
117 timestamp = 0;
118}
119
120ulong get_timer_masked (void)
121{
122 ulong now = READ_TIMER();
123
124 if (lastdec >= now) {
125 /* normal mode */
126 timestamp += lastdec - now;
127 } else {
128 /* we have an overflow ... */
129 timestamp += lastdec + timer_load_val - now;
130 }
131 lastdec = now;
132
133 return timestamp;
134}
135
136void udelay_masked (unsigned long usec)
137{
138 ulong tmo;
wdenk101e8df2005-04-04 12:08:28 +0000139 ulong endtime;
140 signed long diff;
wdenk281e00a2004-08-01 22:48:16 +0000141
wdenk101e8df2005-04-04 12:08:28 +0000142 if (usec >= 1000) {
143 tmo = usec / 1000;
144 tmo *= (timer_load_val * 100);
145 tmo /= 1000;
146 } else {
147 tmo = usec * (timer_load_val * 100);
148 tmo /= (1000*1000);
149 }
wdenk281e00a2004-08-01 22:48:16 +0000150
wdenk101e8df2005-04-04 12:08:28 +0000151 endtime = get_timer_masked () + tmo;
wdenk281e00a2004-08-01 22:48:16 +0000152
wdenk101e8df2005-04-04 12:08:28 +0000153 do {
154 ulong now = get_timer_masked ();
155 diff = endtime - now;
156 } while (diff >= 0);
wdenk281e00a2004-08-01 22:48:16 +0000157}
158
159/*
160 * This function is derived from PowerPC code (read timebase as long long).
161 * On ARM it just returns the timer value.
162 */
163unsigned long long get_ticks(void)
164{
165 return get_timer(0);
166}
167
168/*
169 * This function is derived from PowerPC code (timebase clock frequency).
170 * On ARM it returns the number of timer ticks per second.
171 */
172ulong get_tbclk (void)
173{
174 ulong tbclk;
175
176#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
177 tbclk = timer_load_val * 100;
Wolfgang Denk32cb2c72006-07-21 11:31:42 +0200178#elif defined(CONFIG_SBC2410X) || \
179 defined(CONFIG_SMDK2410) || \
180 defined(CONFIG_VCMA9)
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200181 tbclk = CONFIG_SYS_HZ;
wdenk281e00a2004-08-01 22:48:16 +0000182#else
183# error "tbclk not configured"
184#endif
185
186 return tbclk;
187}
188
wdenkb304c962005-04-05 22:30:50 +0000189/*
190 * reset the cpu by setting up the watchdog timer and let him time out
191 */
192void reset_cpu (ulong ignored)
193{
wdenk3c2b3d42005-04-05 23:32:21 +0000194 volatile S3C24X0_WATCHDOG * watchdog;
wdenkb304c962005-04-05 22:30:50 +0000195
196#ifdef CONFIG_TRAB
wdenk3c2b3d42005-04-05 23:32:21 +0000197 extern void disable_vfd (void);
198
wdenkb304c962005-04-05 22:30:50 +0000199 disable_vfd();
200#endif
201
202 watchdog = S3C24X0_GetBase_WATCHDOG();
203
204 /* Disable watchdog */
205 watchdog->WTCON = 0x0000;
206
207 /* Initialize watchdog timer count register */
208 watchdog->WTCNT = 0x0001;
209
210 /* Enable watchdog timer; assert reset at timer timeout */
211 watchdog->WTCON = 0x0021;
212
213 while(1); /* loop forever and wait for reset to happen */
214
215 /*NOTREACHED*/
216}
217
wdenk281e00a2004-08-01 22:48:16 +0000218#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */