Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / arch / blackfin / mach-bf548 / head.S
bloba2f295266dc6bd4dd97b48773341a7437d020c35
1 /*
2  * File:         arch/blackfin/mach-bf548/head.S
3  * Based on:     arch/blackfin/mach-bf537/head.S
4  * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
5  *
6  * Created:      1998
7  * Description:  Startup code for Blackfin BF548
8  *
9  * Modified:
10  *               Copyright 2004-2007 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  */
30 #include <linux/linkage.h>
31 <<<<<<< HEAD:arch/blackfin/mach-bf548/head.S
32 =======
33 #include <linux/init.h>
34 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/blackfin/mach-bf548/head.S
35 #include <asm/blackfin.h>
36 #include <asm/trace.h>
37 #if CONFIG_BFIN_KERNEL_CLOCK
38 #include <asm/mach-common/clocks.h>
39 #include <asm/mach/mem_init.h>
40 #endif
42 .global __rambase
43 .global __ramstart
44 .global __ramend
45 .extern ___bss_stop
46 .extern ___bss_start
47 .extern _bf53x_relocate_l1_mem
49 #define INITIAL_STACK   0xFFB01000
51 <<<<<<< HEAD:arch/blackfin/mach-bf548/head.S
52 .text
53 =======
54 __INIT
55 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/blackfin/mach-bf548/head.S
57 ENTRY(__start)
58 <<<<<<< HEAD:arch/blackfin/mach-bf548/head.S
59 ENTRY(__stext)
60 =======
61 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/blackfin/mach-bf548/head.S
62         /* R0: argument of command line string, passed from uboot, save it */
63         R7 = R0;
64         /* Enable Cycle Counter and Nesting Of Interrupts */
65 #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
66         R0 = SYSCFG_SNEN;
67 #else
68         R0 = SYSCFG_SNEN | SYSCFG_CCEN;
69 #endif
70         SYSCFG = R0;
71         R0 = 0;
73         /* Clear Out All the data and pointer  Registers*/
74         R1 = R0;
75         R2 = R0;
76         R3 = R0;
77         R4 = R0;
78         R5 = R0;
79         R6 = R0;
81         P0 = R0;
82         P1 = R0;
83         P2 = R0;
84         P3 = R0;
85         P4 = R0;
86         P5 = R0;
88         LC0 = r0;
89         LC1 = r0;
90         L0 = r0;
91         L1 = r0;
92         L2 = r0;
93         L3 = r0;
95         /* Clear Out All the DAG Registers*/
96         B0 = r0;
97         B1 = r0;
98         B2 = r0;
99         B3 = r0;
101         I0 = r0;
102         I1 = r0;
103         I2 = r0;
104         I3 = r0;
106         M0 = r0;
107         M1 = r0;
108         M2 = r0;
109         M3 = r0;
111         trace_buffer_init(p0,r0);
112         P0 = R1;
113         R0 = R1;
115         /* Turn off the icache */
116         p0.l = LO(IMEM_CONTROL);
117         p0.h = HI(IMEM_CONTROL);
118         R1 = [p0];
119         R0 = ~ENICPLB;
120         R0 = R0 & R1;
121         [p0] = R0;
122         SSYNC;
124         /* Turn off the dcache */
125         p0.l = LO(DMEM_CONTROL);
126         p0.h = HI(DMEM_CONTROL);
127         R1 = [p0];
128         R0 = ~ENDCPLB;
129         R0 = R0 & R1;
130         [p0] = R0;
131         SSYNC;
133         /* Initialize stack pointer */
134         SP.L = LO(INITIAL_STACK);
135         SP.H = HI(INITIAL_STACK);
136         FP = SP;
137         USP = SP;
139 #ifdef CONFIG_EARLY_PRINTK
140         SP += -12;
141         call _init_early_exception_vectors;
142         SP += 12;
143 #endif
145         /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
146         call _bf53x_relocate_l1_mem;
147 #if CONFIG_BFIN_KERNEL_CLOCK
148         call _start_dma_code;
149 #endif
150         /* Code for initializing Async memory banks */
152         p2.h = hi(EBIU_AMBCTL1);
153         p2.l = lo(EBIU_AMBCTL1);
154         r0.h = hi(AMBCTL1VAL);
155         r0.l = lo(AMBCTL1VAL);
156         [p2] = r0;
157         ssync;
159         p2.h = hi(EBIU_AMBCTL0);
160         p2.l = lo(EBIU_AMBCTL0);
161         r0.h = hi(AMBCTL0VAL);
162         r0.l = lo(AMBCTL0VAL);
163         [p2] = r0;
164         ssync;
166         p2.h = hi(EBIU_AMGCTL);
167         p2.l = lo(EBIU_AMGCTL);
168         r0 = AMGCTLVAL;
169         w[p2] = r0;
170         ssync;
172         p2.h = hi(EBIU_MBSCTL);
173         p2.l = lo(EBIU_MBSCTL);
174         r0.h = hi(CONFIG_EBIU_MBSCTLVAL);
175         r0.l = lo(CONFIG_EBIU_MBSCTLVAL);
176         [p2] = r0;
177         ssync;
179         p2.h = hi(EBIU_MODE);
180         p2.l = lo(EBIU_MODE);
181         r0.h = hi(CONFIG_EBIU_MODEVAL);
182         r0.l = lo(CONFIG_EBIU_MODEVAL);
183         [p2] = r0;
184         ssync;
186         p2.h = hi(EBIU_FCTL);
187         p2.l = lo(EBIU_FCTL);
188         r0.h = hi(CONFIG_EBIU_FCTLVAL);
189         r0.l = lo(CONFIG_EBIU_FCTLVAL);
190         [p2] = r0;
191         ssync;
193         /* This section keeps the processor in supervisor mode
194          * during kernel boot.  Switches to user mode at end of boot.
195          * See page 3-9 of Hardware Reference manual for documentation.
196          */
198         /* EVT15 = _real_start */
200         p0.l = lo(EVT15);
201         p0.h = hi(EVT15);
202         p1.l = _real_start;
203         p1.h = _real_start;
204         [p0] = p1;
205         csync;
207         p0.l = lo(IMASK);
208         p0.h = hi(IMASK);
209         p1.l = IMASK_IVG15;
210         p1.h = 0x0;
211         [p0] = p1;
212         csync;
214         raise 15;
215         p0.l = .LWAIT_HERE;
216         p0.h = .LWAIT_HERE;
217         reti = p0;
218 #if ANOMALY_05000281
219         nop;
220         nop;
221         nop;
222 #endif
223         rti;
225 .LWAIT_HERE:
226         jump .LWAIT_HERE;
227 <<<<<<< HEAD:arch/blackfin/mach-bf548/head.S
228 =======
229 ENDPROC(__start)
230 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/blackfin/mach-bf548/head.S
232 ENTRY(_real_start)
233         [ -- sp ] = reti;
234         p0.l = lo(WDOG_CTL);
235         p0.h = hi(WDOG_CTL);
236         r0 = 0xAD6(z);
237         w[p0] = r0;     /* watchdog off for now */
238         ssync;
240         /* Code update for BSS size == 0
241          * Zero out the bss region.
242          */
244         p1.l = ___bss_start;
245         p1.h = ___bss_start;
246         p2.l = ___bss_stop;
247         p2.h = ___bss_stop;
248         r0 = 0;
249         p2 -= p1;
250         lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
251 .L_clear_bss:
252         B[p1++] = r0;
254         /* In case there is a NULL pointer reference
255          * Zero out region before stext
256          */
258         p1.l = 0x0;
259         p1.h = 0x0;
260         r0.l = __stext;
261         r0.h = __stext;
262         r0 = r0 >> 1;
263         p2 = r0;
264         r0 = 0;
265         lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
266 .L_clear_zero:
267         W[p1++] = r0;
269         /* pass the uboot arguments to the global value command line */
270         R0 = R7;
271         call _cmdline_init;
273         p1.l = __rambase;
274         p1.h = __rambase;
275         r0.l = __sdata;
276         r0.h = __sdata;
277         [p1] = r0;
279         p1.l = __ramstart;
280         p1.h = __ramstart;
281         p3.l = ___bss_stop;
282         p3.h = ___bss_stop;
284         r1 = p3;
285         [p1] = r1;
288         /*
289          *  load the current thread pointer and stack
290          */
291         r1.l = _init_thread_union;
292         r1.h = _init_thread_union;
294         r2.l = 0x2000;
295         r2.h = 0x0000;
296         r1 = r1 + r2;
297         sp = r1;
298         usp = sp;
299         fp = sp;
300         call _start_kernel;
301 .L_exit:
302         jump.s  .L_exit;
303 <<<<<<< HEAD:arch/blackfin/mach-bf548/head.S
304 =======
305 ENDPROC(_real_start)
307 __FINIT
308 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/blackfin/mach-bf548/head.S
310 .section .l1.text
311 #if CONFIG_BFIN_KERNEL_CLOCK
312 ENTRY(_start_dma_code)
314         /* Enable PHY CLK buffer output */
315         p0.h = hi(VR_CTL);
316         p0.l = lo(VR_CTL);
317         r0.l = w[p0];
318         bitset(r0, 14);
319         w[p0] = r0.l;
320         ssync;
322         p0.h = hi(SIC_IWR0);
323         p0.l = lo(SIC_IWR0);
324         r0.l = 0x1;
325         r0.h = 0x0;
326         [p0] = r0;
327         SSYNC;
329         /*
330          *  Set PLL_CTL
331          *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
332          *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
333          *   - [7]     = output delay (add 200ps of delay to mem signals)
334          *   - [6]     = input delay (add 200ps of input delay to mem signals)
335          *   - [5]     = PDWN      : 1=All Clocks off
336          *   - [3]     = STOPCK    : 1=Core Clock off
337          *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
338          *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
339          *   all other bits set to zero
340          */
342         p0.h = hi(PLL_LOCKCNT);
343         p0.l = lo(PLL_LOCKCNT);
344         r0 = 0x300(Z);
345         w[p0] = r0.l;
346         ssync;
348 #if defined(CONFIG_BF54x)
349         P2.H = hi(EBIU_RSTCTL);
350         P2.L = lo(EBIU_RSTCTL);
351         R0 = [P2];
352         BITSET (R0, 3);
353 #else
354         P2.H = hi(EBIU_SDGCTL);
355         P2.L = lo(EBIU_SDGCTL);
356         R0 = [P2];
357         BITSET (R0, 24);
358 #endif
359         [P2] = R0;
360         SSYNC;
361 #if defined(CONFIG_BF54x)
362 .LSRR_MODE:
363         R0 = [P2];
364         CC = BITTST(R0, 4);
365         if !CC JUMP .LSRR_MODE;
366 #endif
368         r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
369         r0 = r0 << 9;                    /* Shift it over,                  */
370         r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
371         r0 = r1 | r0;
372         r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
373         r1 = r1 << 8;                    /* Shift it over                   */
374         r0 = r1 | r0;                    /* add them all together           */
376         p0.h = hi(PLL_CTL);
377         p0.l = lo(PLL_CTL);              /* Load the address                */
378         cli r2;                          /* Disable interrupts              */
379         ssync;
380         w[p0] = r0.l;                    /* Set the value                   */
381         idle;                            /* Wait for the PLL to stablize    */
382         sti r2;                          /* Enable interrupts               */
384 .Lcheck_again:
385         p0.h = hi(PLL_STAT);
386         p0.l = lo(PLL_STAT);
387         R0 = W[P0](Z);
388         CC = BITTST(R0,5);
389         if ! CC jump .Lcheck_again;
391         /* Configure SCLK & CCLK Dividers */
392         r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
393         p0.h = hi(PLL_DIV);
394         p0.l = lo(PLL_DIV);
395         w[p0] = r0.l;
396         ssync;
398 #if defined(CONFIG_BF54x)
399         P2.H = hi(EBIU_RSTCTL);
400         P2.L = lo(EBIU_RSTCTL);
401         R0 = [P2];
402         CC = BITTST(R0, 0);
403         if CC jump .Lskipddrrst;
404         BITSET (R0, 0);
405 .Lskipddrrst:
406         BITCLR (R0, 3);
407         [P2] = R0;
408         SSYNC;
410         p0.l = lo(EBIU_DDRCTL0);
411         p0.h = hi(EBIU_DDRCTL0);
412         r0.l = lo(mem_DDRCTL0);
413         r0.h = hi(mem_DDRCTL0);
414         [p0] = r0;
415         ssync;
417         p0.l = lo(EBIU_DDRCTL1);
418         p0.h = hi(EBIU_DDRCTL1);
419         r0.l = lo(mem_DDRCTL1);
420         r0.h = hi(mem_DDRCTL1);
421         [p0] = r0;
422         ssync;
424         p0.l = lo(EBIU_DDRCTL2);
425         p0.h = hi(EBIU_DDRCTL2);
426         r0.l = lo(mem_DDRCTL2);
427         r0.h = hi(mem_DDRCTL2);
428         [p0] = r0;
429         ssync;
430 #else
431         p0.l = lo(EBIU_SDRRC);
432         p0.h = hi(EBIU_SDRRC);
433         r0 = mem_SDRRC;
434         w[p0] = r0.l;
435         ssync;
437         p0.l = LO(EBIU_SDBCTL);
438         p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
439         r0 = mem_SDBCTL;
440         w[p0] = r0.l;
441         ssync;
443         P2.H = hi(EBIU_SDGCTL);
444         P2.L = lo(EBIU_SDGCTL);
445         R0 = [P2];
446         BITCLR (R0, 24);
447         p0.h = hi(EBIU_SDSTAT);
448         p0.l = lo(EBIU_SDSTAT);
449         r2.l = w[p0];
450         cc = bittst(r2,3);
451         if !cc jump .Lskip;
452         NOP;
453         BITSET (R0, 23);
454 .Lskip:
455         [P2] = R0;
456         SSYNC;
458         R0.L = lo(mem_SDGCTL);
459         R0.H = hi(mem_SDGCTL);
460         R1 = [p2];
461         R1 = R1 | R0;
462         [P2] = R1;
463         SSYNC;
464 #endif
466         p0.h = hi(SIC_IWR0);
467         p0.l = lo(SIC_IWR0);
468         r0.l = lo(IWR_ENABLE_ALL);
469         r0.h = hi(IWR_ENABLE_ALL);
470         [p0] = r0;
471         SSYNC;
473         RTS;
474 <<<<<<< HEAD:arch/blackfin/mach-bf548/head.S
475 =======
476 ENDPROC(_start_dma_code)
477 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/blackfin/mach-bf548/head.S
478 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
480 .data
483  * Set up the usable of RAM stuff. Size of RAM is determined then
484  * an initial stack set up at the end.
485  */
487 .align 4
488 __rambase:
489 .long   0
490 __ramstart:
491 .long   0
492 __ramend:
493 .long   0