]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/blackfin/mach-bf548/head.S
832a8d7212ac44b7280bada889e795242cf0fb09
[linux-2.6-omap-h63xx.git] / arch / blackfin / mach-bf548 / head.S
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  */
29
30 #include <linux/linkage.h>
31 #include <linux/init.h>
32 #include <asm/blackfin.h>
33 #include <asm/trace.h>
34 #ifdef CONFIG_BFIN_KERNEL_CLOCK
35 #include <asm/mach-common/clocks.h>
36 #include <asm/mach/mem_init.h>
37 #endif
38
39 .extern ___bss_stop
40 .extern ___bss_start
41 .extern _bf53x_relocate_l1_mem
42
43 #define INITIAL_STACK   0xFFB01000
44
45 __INIT
46
47 ENTRY(__start)
48         /* R0: argument of command line string, passed from uboot, save it */
49         R7 = R0;
50         /* Enable Cycle Counter and Nesting Of Interrupts */
51 #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
52         R0 = SYSCFG_SNEN;
53 #else
54         R0 = SYSCFG_SNEN | SYSCFG_CCEN;
55 #endif
56         SYSCFG = R0;
57         R0 = 0;
58
59         /* Clear Out All the data and pointer  Registers*/
60         R1 = R0;
61         R2 = R0;
62         R3 = R0;
63         R4 = R0;
64         R5 = R0;
65         R6 = R0;
66
67         P0 = R0;
68         P1 = R0;
69         P2 = R0;
70         P3 = R0;
71         P4 = R0;
72         P5 = R0;
73
74         LC0 = r0;
75         LC1 = r0;
76         L0 = r0;
77         L1 = r0;
78         L2 = r0;
79         L3 = r0;
80
81         /* Clear Out All the DAG Registers*/
82         B0 = r0;
83         B1 = r0;
84         B2 = r0;
85         B3 = r0;
86
87         I0 = r0;
88         I1 = r0;
89         I2 = r0;
90         I3 = r0;
91
92         M0 = r0;
93         M1 = r0;
94         M2 = r0;
95         M3 = r0;
96
97         trace_buffer_init(p0,r0);
98         P0 = R1;
99         R0 = R1;
100
101         /* Turn off the icache */
102         p0.l = LO(IMEM_CONTROL);
103         p0.h = HI(IMEM_CONTROL);
104         R1 = [p0];
105         R0 = ~ENICPLB;
106         R0 = R0 & R1;
107         [p0] = R0;
108         SSYNC;
109
110         /* Turn off the dcache */
111         p0.l = LO(DMEM_CONTROL);
112         p0.h = HI(DMEM_CONTROL);
113         R1 = [p0];
114         R0 = ~ENDCPLB;
115         R0 = R0 & R1;
116         [p0] = R0;
117         SSYNC;
118
119         /* Initialize stack pointer */
120         SP.L = LO(INITIAL_STACK);
121         SP.H = HI(INITIAL_STACK);
122         FP = SP;
123         USP = SP;
124
125 #ifdef CONFIG_EARLY_PRINTK
126         SP += -12;
127         call _init_early_exception_vectors;
128         SP += 12;
129 #endif
130
131         /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
132         call _bf53x_relocate_l1_mem;
133 #ifdef CONFIG_BFIN_KERNEL_CLOCK
134         call _start_dma_code;
135 #endif
136
137         /* This section keeps the processor in supervisor mode
138          * during kernel boot.  Switches to user mode at end of boot.
139          * See page 3-9 of Hardware Reference manual for documentation.
140          */
141
142         /* EVT15 = _real_start */
143
144         p0.l = lo(EVT15);
145         p0.h = hi(EVT15);
146         p1.l = _real_start;
147         p1.h = _real_start;
148         [p0] = p1;
149         csync;
150
151         p0.l = lo(IMASK);
152         p0.h = hi(IMASK);
153         p1.l = IMASK_IVG15;
154         p1.h = 0x0;
155         [p0] = p1;
156         csync;
157
158         raise 15;
159         p0.l = .LWAIT_HERE;
160         p0.h = .LWAIT_HERE;
161         reti = p0;
162 #if ANOMALY_05000281
163         nop;
164         nop;
165         nop;
166 #endif
167         rti;
168
169 .LWAIT_HERE:
170         jump .LWAIT_HERE;
171 ENDPROC(__start)
172
173 __FINIT
174
175 .section .l1.text
176 #ifdef CONFIG_BFIN_KERNEL_CLOCK
177 ENTRY(_start_dma_code)
178
179         /* Enable PHY CLK buffer output */
180         p0.h = hi(VR_CTL);
181         p0.l = lo(VR_CTL);
182         r0.l = w[p0];
183         bitset(r0, 14);
184         w[p0] = r0.l;
185         ssync;
186
187         p0.h = hi(SIC_IWR0);
188         p0.l = lo(SIC_IWR0);
189         r0.l = 0x1;
190         r0.h = 0x0;
191         [p0] = r0;
192         SSYNC;
193
194         /*
195          *  Set PLL_CTL
196          *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
197          *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
198          *   - [7]     = output delay (add 200ps of delay to mem signals)
199          *   - [6]     = input delay (add 200ps of input delay to mem signals)
200          *   - [5]     = PDWN      : 1=All Clocks off
201          *   - [3]     = STOPCK    : 1=Core Clock off
202          *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
203          *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
204          *   all other bits set to zero
205          */
206
207         p0.h = hi(PLL_LOCKCNT);
208         p0.l = lo(PLL_LOCKCNT);
209         r0 = 0x300(Z);
210         w[p0] = r0.l;
211         ssync;
212
213 #if defined(CONFIG_BF54x)
214         P2.H = hi(EBIU_RSTCTL);
215         P2.L = lo(EBIU_RSTCTL);
216         R0 = [P2];
217         BITSET (R0, 3);
218 #else
219         P2.H = hi(EBIU_SDGCTL);
220         P2.L = lo(EBIU_SDGCTL);
221         R0 = [P2];
222         BITSET (R0, 24);
223 #endif
224         [P2] = R0;
225         SSYNC;
226 #if defined(CONFIG_BF54x)
227 .LSRR_MODE:
228         R0 = [P2];
229         CC = BITTST(R0, 4);
230         if !CC JUMP .LSRR_MODE;
231 #endif
232
233         r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
234         r0 = r0 << 9;                    /* Shift it over,                  */
235         r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
236         r0 = r1 | r0;
237         r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
238         r1 = r1 << 8;                    /* Shift it over                   */
239         r0 = r1 | r0;                    /* add them all together           */
240
241         p0.h = hi(PLL_CTL);
242         p0.l = lo(PLL_CTL);              /* Load the address                */
243         cli r2;                          /* Disable interrupts              */
244         ssync;
245         w[p0] = r0.l;                    /* Set the value                   */
246         idle;                            /* Wait for the PLL to stablize    */
247         sti r2;                          /* Enable interrupts               */
248
249 .Lcheck_again:
250         p0.h = hi(PLL_STAT);
251         p0.l = lo(PLL_STAT);
252         R0 = W[P0](Z);
253         CC = BITTST(R0,5);
254         if ! CC jump .Lcheck_again;
255
256         /* Configure SCLK & CCLK Dividers */
257         r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
258         p0.h = hi(PLL_DIV);
259         p0.l = lo(PLL_DIV);
260         w[p0] = r0.l;
261         ssync;
262
263 #if defined(CONFIG_BF54x)
264         P2.H = hi(EBIU_RSTCTL);
265         P2.L = lo(EBIU_RSTCTL);
266         R0 = [P2];
267         CC = BITTST(R0, 0);
268         if CC jump .Lskipddrrst;
269         BITSET (R0, 0);
270 .Lskipddrrst:
271         BITCLR (R0, 3);
272         [P2] = R0;
273         SSYNC;
274
275         p0.l = lo(EBIU_DDRCTL0);
276         p0.h = hi(EBIU_DDRCTL0);
277         r0.l = lo(mem_DDRCTL0);
278         r0.h = hi(mem_DDRCTL0);
279         [p0] = r0;
280         ssync;
281
282         p0.l = lo(EBIU_DDRCTL1);
283         p0.h = hi(EBIU_DDRCTL1);
284         r0.l = lo(mem_DDRCTL1);
285         r0.h = hi(mem_DDRCTL1);
286         [p0] = r0;
287         ssync;
288
289         p0.l = lo(EBIU_DDRCTL2);
290         p0.h = hi(EBIU_DDRCTL2);
291         r0.l = lo(mem_DDRCTL2);
292         r0.h = hi(mem_DDRCTL2);
293         [p0] = r0;
294         ssync;
295 #else
296         p0.l = lo(EBIU_SDRRC);
297         p0.h = hi(EBIU_SDRRC);
298         r0 = mem_SDRRC;
299         w[p0] = r0.l;
300         ssync;
301
302         p0.l = LO(EBIU_SDBCTL);
303         p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
304         r0 = mem_SDBCTL;
305         w[p0] = r0.l;
306         ssync;
307
308         P2.H = hi(EBIU_SDGCTL);
309         P2.L = lo(EBIU_SDGCTL);
310         R0 = [P2];
311         BITCLR (R0, 24);
312         p0.h = hi(EBIU_SDSTAT);
313         p0.l = lo(EBIU_SDSTAT);
314         r2.l = w[p0];
315         cc = bittst(r2,3);
316         if !cc jump .Lskip;
317         NOP;
318         BITSET (R0, 23);
319 .Lskip:
320         [P2] = R0;
321         SSYNC;
322
323         R0.L = lo(mem_SDGCTL);
324         R0.H = hi(mem_SDGCTL);
325         R1 = [p2];
326         R1 = R1 | R0;
327         [P2] = R1;
328         SSYNC;
329 #endif
330
331         p0.h = hi(SIC_IWR0);
332         p0.l = lo(SIC_IWR0);
333         r0.l = lo(IWR_ENABLE_ALL);
334         r0.h = hi(IWR_ENABLE_ALL);
335         [p0] = r0;
336         SSYNC;
337
338         RTS;
339 ENDPROC(_start_dma_code)
340 #endif /* CONFIG_BFIN_KERNEL_CLOCK */