]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/armltd/integratorcp/integratorcp.c
arm: timer and interrupt init rework
[people/ms/u-boot.git] / board / armltd / integratorcp / integratorcp.c
CommitLineData
3d3befa7
WD
1/*
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 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
8 *
9 * (C) Copyright 2003
10 * Texas Instruments, <www.ti.com>
11 * Kshitij Gupta <Kshitij@ti.com>
12 *
13 * (C) Copyright 2004
14 * ARM Ltd.
15 * Philippe Robin, <philippe.robin@arm.com>
16 *
17 * See file CREDITS for list of people who contributed to this
18 * project.
19 *
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License as
22 * published by the Free Software Foundation; either version 2 of
23 * the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
fe7eb5d8 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3d3befa7
WD
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33 * MA 02111-1307 USA
34 */
35
36#include <common.h>
4265c35f 37#include <div64.h>
3d3befa7 38
d87080b7
WD
39DECLARE_GLOBAL_DATA_PTR;
40
3d3befa7
WD
41void flash__init (void);
42void ether__init (void);
43void peripheral_power_enable (void);
44
45#if defined(CONFIG_SHOW_BOOT_PROGRESS)
46void show_boot_progress(int progress)
47{
74f4304e 48 printf("Boot reached stage %d\n", progress);
3d3befa7
WD
49}
50#endif
51
52#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
53
3d3befa7
WD
54/*
55 * Miscellaneous platform dependent initialisations
56 */
57
58int board_init (void)
59{
3d3befa7 60 /* arch number of Integrator Board */
731215eb 61 gd->bd->bi_arch_number = MACH_TYPE_CINTEGRATOR;
3d3befa7
WD
62
63 /* adress of boot parameters */
64 gd->bd->bi_boot_params = 0x00000100;
65
bc54f309
WD
66 gd->flags = 0;
67
74f4304e
WD
68#ifdef CONFIG_CM_REMAP
69extern void cm_remap(void);
70 cm_remap(); /* remaps writeable memory to 0x00000000 */
71#endif
72
3d3befa7
WD
73 icache_enable ();
74
75 flash__init ();
76 ether__init ();
77 return 0;
78}
79
80
81int misc_init_r (void)
82{
83 setenv("verify", "n");
84 return (0);
85}
86
87/******************************
88 Routine:
89 Description:
90******************************/
91void flash__init (void)
92{
93}
94/*************************************************************
95 Routine:ether__init
96 Description: take the Ethernet controller out of reset and wait
74f4304e 97 for the EEPROM load to complete.
3d3befa7
WD
98*************************************************************/
99void ether__init (void)
100{
101}
102
103/******************************
104 Routine:
105 Description:
106******************************/
107int dram_init (void)
108{
74f4304e 109 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
fe7eb5d8 110 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
74f4304e
WD
111
112#ifdef CONFIG_CM_SPD_DETECT
fe7eb5d8 113 {
74f4304e
WD
114extern void dram_query(void);
115 unsigned long cm_reg_sdram;
116 unsigned long sdram_shift;
117
118 dram_query(); /* Assembler accesses to CM registers */
fe7eb5d8 119 /* Queries the SPD values */
74f4304e
WD
120
121 /* Obtain the SDRAM size from the CM SDRAM register */
122
123 cm_reg_sdram = *(volatile ulong *)(CM_BASE + OS_SDRAM);
fe7eb5d8
WD
124 /* Register SDRAM size
125 *
126 * 0xXXXXXXbbb000bb 16 MB
127 * 0xXXXXXXbbb001bb 32 MB
128 * 0xXXXXXXbbb010bb 64 MB
129 * 0xXXXXXXbbb011bb 128 MB
130 * 0xXXXXXXbbb100bb 256 MB
131 *
74f4304e 132 */
fe7eb5d8
WD
133 sdram_shift = ((cm_reg_sdram & 0x0000001C)/4)%4;
134 gd->bd->bi_dram[0].size = 0x01000000 << sdram_shift;
74f4304e 135
fe7eb5d8 136 }
74f4304e
WD
137#endif /* CM_SPD_DETECT */
138
3d3befa7
WD
139 return 0;
140}
74f4304e
WD
141
142/* The Integrator/CP timer1 is clocked at 1MHz
143 * can be divided by 16 or 256
144 * and can be set up as a 32-bit timer
145 */
6d0f6bcf 146/* U-Boot expects a 32 bit timer, running at CONFIG_SYS_HZ */
74f4304e
WD
147/* Keep total timer count to avoid losing decrements < div_timer */
148static unsigned long long total_count = 0;
fe7eb5d8 149static unsigned long long lastdec; /* Timer reading at last call */
74f4304e
WD
150static unsigned long long div_clock = 1; /* Divisor applied to timer clock */
151static unsigned long long div_timer = 1; /* Divisor to convert timer reading
152 * change to U-Boot ticks
153 */
6d0f6bcf 154/* CONFIG_SYS_HZ = CONFIG_SYS_HZ_CLOCK/(div_clock * div_timer) */
fe7eb5d8 155static ulong timestamp; /* U-Boot ticks since startup */
74f4304e
WD
156
157#define TIMER_LOAD_VAL ((ulong)0xFFFFFFFF)
6d0f6bcf 158#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+4))
74f4304e 159
6d0f6bcf 160/* all function return values in U-Boot ticks i.e. (1/CONFIG_SYS_HZ) sec
74f4304e
WD
161 * - unless otherwise stated
162 */
163
164/* starts up a counter
165 * - the Integrator/CP timer can be set up to issue an interrupt */
b54384e3 166int timer_init (void)
74f4304e
WD
167{
168 /* Load timer with initial value */
6d0f6bcf 169 *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL;
74f4304e 170 /* Set timer to be
fe7eb5d8
WD
171 * enabled 1
172 * periodic 1
173 * no interrupts 0
174 * X 0
175 * divider 1 00 == less rounding error
176 * 32 bit 1
177 * wrapping 0
74f4304e 178 */
6d0f6bcf 179 *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = 0x000000C2;
74f4304e
WD
180 /* init the timestamp */
181 total_count = 0ULL;
182 reset_timer_masked();
183
6d0f6bcf 184 div_timer = (unsigned long long)(CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ);
74f4304e
WD
185 div_timer /= div_clock;
186
187 return (0);
188}
189
190/*
191 * timer without interrupts
192 */
193void reset_timer (void)
194{
195 reset_timer_masked ();
196}
197
198ulong get_timer (ulong base_ticks)
199{
200 return get_timer_masked () - base_ticks;
201}
202
203void set_timer (ulong ticks)
204{
205 timestamp = ticks;
206 total_count = (unsigned long long)ticks * div_timer;
207}
208
209/* delay usec useconds */
210void udelay (unsigned long usec)
211{
212 ulong tmo, tmp;
213
214 /* Convert to U-Boot ticks */
6d0f6bcf 215 tmo = usec * CONFIG_SYS_HZ;
74f4304e
WD
216 tmo /= (1000000L);
217
218 tmp = get_timer_masked(); /* get current timestamp */
219 tmo += tmp; /* form target timestamp */
220
fe7eb5d8 221 while (get_timer_masked () < tmo) {/* loop till event */
74f4304e
WD
222 /*NOP*/;
223 }
224}
225
226void reset_timer_masked (void)
227{
228 /* capure current decrementer value */
fe7eb5d8 229 lastdec = (unsigned long long)READ_TIMER;
74f4304e 230 /* start "advancing" time stamp from 0 */
fe7eb5d8 231 timestamp = 0L;
74f4304e
WD
232}
233
fe7eb5d8 234/* converts the timer reading to U-Boot ticks */
74f4304e
WD
235/* the timestamp is the number of ticks since reset */
236ulong get_timer_masked (void)
237{
238 /* get current count */
239 unsigned long long now = (unsigned long long)READ_TIMER;
240
fe7eb5d8 241 if(now > lastdec) {
74f4304e 242 /* Must have wrapped */
fe7eb5d8 243 total_count += lastdec + TIMER_LOAD_VAL + 1 - now;
74f4304e
WD
244 } else {
245 total_count += lastdec - now;
246 }
fe7eb5d8 247 lastdec = now;
4265c35f
SP
248
249 /* Reuse "now" */
250 now = total_count;
251 do_div(now, div_timer);
252 timestamp = now;
74f4304e
WD
253
254 return timestamp;
255}
256
257/* waits specified delay value and resets timestamp */
258void udelay_masked (unsigned long usec)
259{
260 udelay(usec);
261}
262
263/*
264 * This function is derived from PowerPC code (read timebase as long long).
265 * On ARM it just returns the timer value.
266 */
267unsigned long long get_ticks(void)
268{
269 return (unsigned long long)get_timer(0);
270}
271
272/*
273 * Return the timebase clock frequency
274 * i.e. how often the timer decrements
275 */
276ulong get_tbclk (void)
277{
6d0f6bcf 278 return (ulong)(((unsigned long long)CONFIG_SYS_HZ_CLOCK)/div_clock);
74f4304e 279}