blob: 9c8e6885f4e7f1dea40353cb7620fa4b59dd31d8 [file] [log] [blame]
Bryan Wu1394f032007-05-06 14:50:22 -07001/*
2 * File: arch/blackfin/mach-bf561/head.S
3 * Based on: arch/blackfin/mach-bf533/head.S
4 * Author:
5 *
6 * Created:
7 * Description: BF561 startup file
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/linkage.h>
31#include <asm/blackfin.h>
32#if CONFIG_BFIN_KERNEL_CLOCK
33#include <asm/mach/mem_init.h>
34#endif
35
36.global __rambase
37.global __ramstart
38.global __ramend
39.extern ___bss_stop
40.extern ___bss_start
41.extern _bf53x_relocate_l1_mem
42
43#define INITIAL_STACK 0xFFB01000
44
45.text
46
47ENTRY(__start)
48ENTRY(__stext)
49 /* R0: argument of command line string, passed from uboot, save it */
50 R7 = R0;
51 /* Set the SYSCFG register */
52 R0 = 0x36;
53 SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
54 R0 = 0;
55
56 /*Clear Out All the data and pointer Registers*/
57 R1 = R0;
58 R2 = R0;
59 R3 = R0;
60 R4 = R0;
61 R5 = R0;
62 R6 = R0;
63
64 P0 = R0;
65 P1 = R0;
66 P2 = R0;
67 P3 = R0;
68 P4 = R0;
69 P5 = R0;
70
71 LC0 = r0;
72 LC1 = r0;
73 L0 = r0;
74 L1 = r0;
75 L2 = r0;
76 L3 = r0;
77
78 /* Clear Out All the DAG Registers*/
79 B0 = r0;
80 B1 = r0;
81 B2 = r0;
82 B3 = r0;
83
84 I0 = r0;
85 I1 = r0;
86 I2 = r0;
87 I3 = r0;
88
89 M0 = r0;
90 M1 = r0;
91 M2 = r0;
92 M3 = r0;
93
94 /* Turn off the icache */
95 p0.l = (IMEM_CONTROL & 0xFFFF);
96 p0.h = (IMEM_CONTROL >> 16);
97 R1 = [p0];
98 R0 = ~ENICPLB;
99 R0 = R0 & R1;
100
101 /* Anomaly 05000125 */
102#ifdef ANOMALY_05000125
103 CLI R2;
104 SSYNC;
105#endif
106 [p0] = R0;
107 SSYNC;
108#ifdef ANOMALY_05000125
109 STI R2;
110#endif
111
112 /* Turn off the dcache */
113 p0.l = (DMEM_CONTROL & 0xFFFF);
114 p0.h = (DMEM_CONTROL >> 16);
115 R1 = [p0];
116 R0 = ~ENDCPLB;
117 R0 = R0 & R1;
118
119 /* Anomaly 05000125 */
120#ifdef ANOMALY_05000125
121 CLI R2;
122 SSYNC;
123#endif
124 [p0] = R0;
125 SSYNC;
126#ifdef ANOMALY_05000125
127 STI R2;
128#endif
129
Mike Frysinger5079df92007-05-21 18:09:27 +0800130 /* Initialise UART - when booting from u-boot, the UART is not disabled
131 * so if we dont initalize here, our serial console gets hosed */
Bryan Wu1394f032007-05-06 14:50:22 -0700132 p0.h = hi(UART_LCR);
133 p0.l = lo(UART_LCR);
134 r0 = 0x0(Z);
135 w[p0] = r0.L; /* To enable DLL writes */
136 ssync;
137
138 p0.h = hi(UART_DLL);
139 p0.l = lo(UART_DLL);
140 r0 = 0x0(Z);
141 w[p0] = r0.L;
142 ssync;
143
144 p0.h = hi(UART_DLH);
145 p0.l = lo(UART_DLH);
146 r0 = 0x00(Z);
147 w[p0] = r0.L;
148 ssync;
149
150 p0.h = hi(UART_GCTL);
151 p0.l = lo(UART_GCTL);
152 r0 = 0x0(Z);
153 w[p0] = r0.L; /* To enable UART clock */
154 ssync;
155
156 /* Initialize stack pointer */
157 sp.l = lo(INITIAL_STACK);
158 sp.h = hi(INITIAL_STACK);
159 fp = sp;
160 usp = sp;
161
162 /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
163 call _bf53x_relocate_l1_mem;
164#if CONFIG_BFIN_KERNEL_CLOCK
165 call _start_dma_code;
166#endif
167
168 /* Code for initializing Async memory banks */
169
170 p2.h = hi(EBIU_AMBCTL1);
171 p2.l = lo(EBIU_AMBCTL1);
172 r0.h = hi(AMBCTL1VAL);
173 r0.l = lo(AMBCTL1VAL);
174 [p2] = r0;
175 ssync;
176
177 p2.h = hi(EBIU_AMBCTL0);
178 p2.l = lo(EBIU_AMBCTL0);
179 r0.h = hi(AMBCTL0VAL);
180 r0.l = lo(AMBCTL0VAL);
181 [p2] = r0;
182 ssync;
183
184 p2.h = hi(EBIU_AMGCTL);
185 p2.l = lo(EBIU_AMGCTL);
186 r0 = AMGCTLVAL;
187 w[p2] = r0;
188 ssync;
189
190 /* This section keeps the processor in supervisor mode
191 * during kernel boot. Switches to user mode at end of boot.
192 * See page 3-9 of Hardware Reference manual for documentation.
193 */
194
195 /* EVT15 = _real_start */
196
197 p0.l = lo(EVT15);
198 p0.h = hi(EVT15);
199 p1.l = _real_start;
200 p1.h = _real_start;
201 [p0] = p1;
202 csync;
203
204 p0.l = lo(IMASK);
205 p0.h = hi(IMASK);
206 p1.l = IMASK_IVG15;
207 p1.h = 0x0;
208 [p0] = p1;
209 csync;
210
211 raise 15;
212 p0.l = .LWAIT_HERE;
213 p0.h = .LWAIT_HERE;
214 reti = p0;
215#if defined(ANOMALY_05000281)
216 nop; nop; nop;
217#endif
218 rti;
219
220.LWAIT_HERE:
221 jump .LWAIT_HERE;
222
223ENTRY(_real_start)
224 [ -- sp ] = reti;
225 p0.l = lo(WDOGA_CTL);
226 p0.h = hi(WDOGA_CTL);
227 r0 = 0xAD6(z);
228 w[p0] = r0; /* watchdog off for now */
229 ssync;
230
231 /* Code update for BSS size == 0
232 * Zero out the bss region.
233 */
234
235 p1.l = ___bss_start;
236 p1.h = ___bss_start;
237 p2.l = ___bss_stop;
238 p2.h = ___bss_stop;
239 r0 = 0;
240 p2 -= p1;
241 lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
242.L_clear_bss:
243 B[p1++] = r0;
244
245 /* In case there is a NULL pointer reference
246 * Zero out region before stext
247 */
248
249 p1.l = 0x0;
250 p1.h = 0x0;
251 r0.l = __stext;
252 r0.h = __stext;
253 r0 = r0 >> 1;
254 p2 = r0;
255 r0 = 0;
256 lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
257.L_clear_zero:
258 W[p1++] = r0;
259
260/* pass the uboot arguments to the global value command line */
261 R0 = R7;
262 call _cmdline_init;
263
264 p1.l = __rambase;
265 p1.h = __rambase;
266 r0.l = __sdata;
267 r0.h = __sdata;
268 [p1] = r0;
269
270 p1.l = __ramstart;
271 p1.h = __ramstart;
272 p3.l = ___bss_stop;
273 p3.h = ___bss_stop;
274
275 r1 = p3;
276 [p1] = r1;
277
278 /*
279 * load the current thread pointer and stack
280 */
281 r1.l = _init_thread_union;
282 r1.h = _init_thread_union;
283
284 r2.l = 0x2000;
285 r2.h = 0x0000;
286 r1 = r1 + r2;
287 sp = r1;
288 usp = sp;
289 fp = sp;
290 call _start_kernel;
291.L_exit:
292 jump.s .L_exit;
293
294.section .l1.text
295#if CONFIG_BFIN_KERNEL_CLOCK
296ENTRY(_start_dma_code)
297 p0.h = hi(SICA_IWR0);
298 p0.l = lo(SICA_IWR0);
299 r0.l = 0x1;
300 [p0] = r0;
301 SSYNC;
302
303 /*
304 * Set PLL_CTL
305 * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
306 * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
307 * - [7] = output delay (add 200ps of delay to mem signals)
308 * - [6] = input delay (add 200ps of input delay to mem signals)
309 * - [5] = PDWN : 1=All Clocks off
310 * - [3] = STOPCK : 1=Core Clock off
311 * - [1] = PLL_OFF : 1=Disable Power to PLL
312 * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
313 * all other bits set to zero
314 */
315
316 p0.h = hi(PLL_LOCKCNT);
317 p0.l = lo(PLL_LOCKCNT);
318 r0 = 0x300(Z);
319 w[p0] = r0.l;
320 ssync;
321
322 P2.H = hi(EBIU_SDGCTL);
323 P2.L = lo(EBIU_SDGCTL);
324 R0 = [P2];
325 BITSET (R0, 24);
326 [P2] = R0;
327 SSYNC;
328
329 r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
330 r0 = r0 << 9; /* Shift it over, */
331 r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
332 r0 = r1 | r0;
333 r1 = PLL_BYPASS; /* Bypass the PLL? */
334 r1 = r1 << 8; /* Shift it over */
335 r0 = r1 | r0; /* add them all together */
336
337 p0.h = hi(PLL_CTL);
338 p0.l = lo(PLL_CTL); /* Load the address */
339 cli r2; /* Disable interrupts */
340 ssync;
341 w[p0] = r0.l; /* Set the value */
342 idle; /* Wait for the PLL to stablize */
343 sti r2; /* Enable interrupts */
344
345.Lcheck_again:
346 p0.h = hi(PLL_STAT);
347 p0.l = lo(PLL_STAT);
348 R0 = W[P0](Z);
349 CC = BITTST(R0,5);
350 if ! CC jump .Lcheck_again;
351
352 /* Configure SCLK & CCLK Dividers */
353 r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
354 p0.h = hi(PLL_DIV);
355 p0.l = lo(PLL_DIV);
356 w[p0] = r0.l;
357 ssync;
358
359 p0.l = lo(EBIU_SDRRC);
360 p0.h = hi(EBIU_SDRRC);
361 r0 = mem_SDRRC;
362 w[p0] = r0.l;
363 ssync;
364
365 p0.l = (EBIU_SDBCTL & 0xFFFF);
366 p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
367 r0 = mem_SDBCTL;
368 w[p0] = r0.l;
369 ssync;
370
371 P2.H = hi(EBIU_SDGCTL);
372 P2.L = lo(EBIU_SDGCTL);
373 R0 = [P2];
374 BITCLR (R0, 24);
375 p0.h = hi(EBIU_SDSTAT);
376 p0.l = lo(EBIU_SDSTAT);
377 r2.l = w[p0];
378 cc = bittst(r2,3);
379 if !cc jump .Lskip;
380 NOP;
381 BITSET (R0, 23);
382.Lskip:
383 [P2] = R0;
384 SSYNC;
385
386 R0.L = lo(mem_SDGCTL);
387 R0.H = hi(mem_SDGCTL);
388 R1 = [p2];
389 R1 = R1 | R0;
390 [P2] = R1;
391 SSYNC;
392
393 RTS;
394#endif /* CONFIG_BFIN_KERNEL_CLOCK */
395
396ENTRY(_bfin_reset)
397 /* No more interrupts to be handled*/
398 CLI R6;
399 SSYNC;
400
401#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
402 p0.h = hi(FIO_INEN);
403 p0.l = lo(FIO_INEN);
404 r0.l = ~(PF1 | PF0);
405 w[p0] = r0.l;
406
407 p0.h = hi(FIO_DIR);
408 p0.l = lo(FIO_DIR);
409 r0.l = (PF1 | PF0);
410 w[p0] = r0.l;
411
412 p0.h = hi(FIO_FLAG_C);
413 p0.l = lo(FIO_FLAG_C);
414 r0.l = (PF1 | PF0);
415 w[p0] = r0.l;
416#endif
417
Bryan Wu1394f032007-05-06 14:50:22 -0700418 /* Clear the IMASK register */
419 p0.h = hi(IMASK);
420 p0.l = lo(IMASK);
421 r0 = 0x0;
422 [p0] = r0;
423
424 /* Clear the ILAT register */
425 p0.h = hi(ILAT);
426 p0.l = lo(ILAT);
427 r0 = [p0];
428 [p0] = r0;
429 SSYNC;
430
Mike Frysingeref9256d2007-05-21 18:09:26 +0800431 /* make sure SYSCR is set to use BMODE */
432 P0.h = hi(SICA_SYSCR);
433 P0.l = lo(SICA_SYSCR);
434 R0.l = 0x0;
435 W[P0] = R0.l;
Bryan Wu1394f032007-05-06 14:50:22 -0700436 SSYNC;
437
Mike Frysingeref9256d2007-05-21 18:09:26 +0800438 /* issue a system soft reset */
439 P1.h = hi(SICA_SWRST);
440 P1.l = lo(SICA_SWRST);
441 R1.l = 0x0007;
442 W[P1] = R1;
Bryan Wu1394f032007-05-06 14:50:22 -0700443 SSYNC;
444
Mike Frysingeref9256d2007-05-21 18:09:26 +0800445 /* clear system soft reset */
446 R0.l = 0x0000;
447 W[P0] = R0;
Bryan Wu1394f032007-05-06 14:50:22 -0700448 SSYNC;
449
Mike Frysingeref9256d2007-05-21 18:09:26 +0800450 /* issue core reset */
451 raise 1;
Bryan Wu1394f032007-05-06 14:50:22 -0700452
453 RTS;
Mike Frysingeref9256d2007-05-21 18:09:26 +0800454ENDPROC(_bfin_reset)
Bryan Wu1394f032007-05-06 14:50:22 -0700455
456.data
457
458/*
459 * Set up the usable of RAM stuff. Size of RAM is determined then
460 * an initial stack set up at the end.
461 */
462
463.align 4
464__rambase:
465.long 0
466__ramstart:
467.long 0
468__ramend:
469.long 0