]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/bf533/start.S
Coding Style cleanup
[karo-tx-uboot.git] / cpu / bf533 / start.S
1 /*
2  * U-boot - start.S Startup file of u-boot for BF533
3  *
4  * Copyright (c) 2005 blackfin.uclinux.org
5  *
6  * This file is based on head.S
7  * Copyright (c) 2003  Metrowerks/Motorola
8  * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
9  *                     Kenneth Albanowski <kjahds@kjahds.com>,
10  *                     The Silver Hammer Group, Ltd.
11  * (c) 1995, Dionne & Associates
12  * (c) 1995, DKG Display Tech.
13  *
14  * See file CREDITS for list of people who contributed to this
15  * project.
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License as
19  * published by the Free Software Foundation; either version 2 of
20  * the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30  * MA 02111-1307 USA
31  */
32
33 /*
34  * Note: A change in this file subsequently requires a change in
35  *       board/$(board_name)/config.mk for a valid u-boot.bin
36  */
37
38 #define ASSEMBLY
39
40 #include <linux/config.h>
41 #include <asm/blackfin.h>
42 #include <config.h>
43 #include <asm/mem_init.h>
44
45 #if (CONFIG_CCLK_DIV == 1)
46 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
47 #endif
48 #if (CONFIG_CCLK_DIV == 2)
49 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
50 #endif
51 #if (CONFIG_CCLK_DIV == 4)
52 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
53 #endif
54 #if (CONFIG_CCLK_DIV == 8)
55 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
56 #endif
57 #ifndef CONFIG_CCLK_ACT_DIV
58 #define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
59 #endif
60
61 .global _stext;
62 .global __bss_start;
63 .global start;
64 .global _start;
65 .global _rambase;
66 .global _ramstart;
67 .global _ramend;
68 .global _bf533_data_dest;
69 .global _bf533_data_size;
70 .global edata;
71 .global _initialize;
72 .global _exit;
73 .global flashdataend;
74
75 .text
76 _start:
77 start:
78 _stext:
79
80         R0 = 0x30;
81         SYSCFG = R0;
82         SSYNC;
83
84         /* As per HW reference manual DAG registers,
85          * DATA and Address resgister shall be zero'd
86          * in initialization, after a reset state
87          */
88         r1 = 0; /* Data registers zero'd */
89         r2 = 0;
90         r3 = 0;
91         r4 = 0;
92         r5 = 0;
93         r6 = 0;
94         r7 = 0;
95
96         p0 = 0; /* Address registers zero'd */
97         p1 = 0;
98         p2 = 0;
99         p3 = 0;
100         p4 = 0;
101         p5 = 0;
102
103         i0 = 0; /* DAG Registers zero'd */
104         i1 = 0;
105         i2 = 0;
106         i3 = 0;
107         m0 = 0;
108         m1 = 0;
109         m3 = 0;
110         m3 = 0;
111         l0 = 0;
112         l1 = 0;
113         l2 = 0;
114         l3 = 0;
115         b0 = 0;
116         b1 = 0;
117         b2 = 0;
118         b3 = 0;
119
120         /* Set loop counters to zero, to make sure that
121          * hw loops are disabled.
122          */
123         lc0 = 0;
124         lc1 = 0;
125
126         SSYNC;
127
128         /* Check soft reset status */
129         p0.h = SWRST >> 16;
130         p0.l = SWRST & 0xFFFF;
131         r0.l = w[p0];
132
133         cc = bittst(r0, 15);
134         if !cc jump no_soft_reset;
135
136         /* Clear Soft reset */
137         r0 = 0x0000;
138         w[p0] = r0;
139         ssync;
140
141 no_soft_reset:
142         nop;
143
144         /* Clear EVT registers */
145         p0.h = (EVT_EMULATION_ADDR >> 16);
146         p0.l = (EVT_EMULATION_ADDR & 0xFFFF);
147         p0 += 8;
148         p1 = 14;
149         r1 = 0;
150         LSETUP(4,4) lc0 = p1;
151         [ p0 ++ ] = r1;
152
153         /*
154          *  Set PLL_CTL
155          *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
156          *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
157          *   - [7]     = output delay (add 200ps of delay to mem signals)
158          *   - [6]     = input delay (add 200ps of input delay to mem signals)
159          *   - [5]     = PDWN      : 1=All Clocks off
160          *   - [3]     = STOPCK    : 1=Core Clock off
161          *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
162          *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
163          *   all other bits set to zero
164          */
165
166         r0 = CONFIG_VCO_MULT;   /* Load the VCO multiplier */
167         r0 = r0 << 9;           /* Shift it over */
168         r1 =  CONFIG_CLKIN_HALF;        /* Do we need to divide CLKIN by 2? */
169         r0 = r1 | r0;
170         r1 = CONFIG_PLL_BYPASS; /* Bypass the PLL?                 */
171         r1 = r1 << 8;   /* Shift it over */
172         r0 = r1 | r0;   /* add them all together */
173
174         p0.h = (PLL_CTL >> 16);
175         p0.l = (PLL_CTL & 0xFFFF);      /* Load the address */
176         cli r2;                         /* Disable interrupts */
177         w[p0] = r0;                     /* Set the value */
178         idle;                           /* Wait for the PLL to stablize */
179         sti r2;                         /* Enable interrupts */
180         ssync;
181
182         /*
183          * Turn on the CYCLES COUNTER
184          */
185         r2 = SYSCFG;
186         BITSET (r2,1);
187         SYSCFG = r2;
188
189         /* Configure SCLK & CCLK Dividers */
190         r0 = CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV;
191         p0.h = (PLL_DIV >> 16);
192         p0.l = (PLL_DIV & 0xFFFF);
193         w[p0] = r0;
194         ssync;
195
196 wait_for_pll_stab:
197         p0.h = (PLL_STAT >> 16);
198         p0.l = (PLL_STAT & 0xFFFF);
199         r0.l = w[p0];
200         cc = bittst(r0,5);
201         if !cc jump wait_for_pll_stab;
202
203         /* Configure SDRAM if SDRAM is already not enabled */
204         p0.l = (EBIU_SDSTAT & 0xFFFF);
205         p0.h = (EBIU_SDSTAT >> 16);
206         r0.l = w[p0];
207         cc = bittst(r0, 3);
208         if !cc jump skip_sdram_enable;
209
210         /* SDRAM initialization */
211         p0.l = (EBIU_SDGCTL & 0xFFFF);
212         p0.h = (EBIU_SDGCTL >> 16);     /* SDRAM Memory Global Control Register */
213         r0.h = (mem_SDGCTL >> 16);
214         r0.l = (mem_SDGCTL & 0xFFFF);
215         [p0] = r0;
216         ssync;
217
218         p0.l = (EBIU_SDBCTL & 0xFFFF);
219         p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
220         r0 = mem_SDBCTL;
221         w[p0] = r0.l;
222         ssync;
223
224         p0.l = (EBIU_SDRRC & 0xFFFF);
225         p0.h = (EBIU_SDRRC >> 16);      /* SDRAM Refresh Rate Control Register */
226         r0 = mem_SDRRC;
227         w[p0] = r0.l;
228         ssync;
229
230 skip_sdram_enable:
231         nop;
232
233 #ifndef CFG_NO_FLASH
234         /* relocate into to RAM */
235         p1.l = (CFG_FLASH_BASE & 0xffff);
236         p1.h = (CFG_FLASH_BASE >> 16);
237         p2.l = (CFG_MONITOR_BASE & 0xffff);
238         p2.h = (CFG_MONITOR_BASE >> 16);
239         r0.l = (CFG_MONITOR_LEN & 0xffff);
240         r0.h = (CFG_MONITOR_LEN >> 16);
241 loop1:
242         r1 = [p1];
243         [p2] = r1;
244         p3=0x4;
245         p1=p1+p3;
246         p2=p2+p3;
247         r2=0x4;
248         r0=r0-r2;
249         cc=r0==0x0;
250         if !cc jump loop1;
251 #endif
252         /*
253          * configure STACK
254          */
255         r0.h = (CONFIG_STACKBASE >> 16);
256         r0.l = (CONFIG_STACKBASE & 0xFFFF);
257         sp = r0;
258         fp = sp;
259
260         /*
261          * This next section keeps the processor in supervisor mode
262          * during kernel boot.  Switches to user mode at end of boot.
263          * See page 3-9 of Hardware Reference manual for documentation.
264          */
265
266         /* To keep ourselves in the supervisor mode */
267         p0.l = (EVT_IVG15_ADDR & 0xFFFF);
268         p0.h = (EVT_IVG15_ADDR >> 16);
269
270         p1.l = _real_start;
271         p1.h = _real_start;
272         [p0] = p1;
273
274         p0.l = (IMASK & 0xFFFF);
275         p0.h = (IMASK >> 16);
276         r0 = IVG15_POS;
277         [p0] = r0;
278         raise 15;
279         p0.l = WAIT_HERE;
280         p0.h = WAIT_HERE;
281         reti = p0;
282         rti;
283
284 WAIT_HERE:
285         jump WAIT_HERE;
286
287 .global _real_start;
288 _real_start:
289         [ -- sp ] = reti;
290
291 #ifdef CONFIG_EZKIT533
292         p0.l = (WDOG_CTL & 0xFFFF);
293         p0.h = (WDOG_CTL >> 16);
294         r0 = WATCHDOG_DISABLE(z);
295         w[p0] = r0;
296 #endif
297
298         /* Code for initializing Async mem banks */
299         p2.h = (EBIU_AMBCTL1 >> 16);
300         p2.l = (EBIU_AMBCTL1 & 0xFFFF);
301         r0.h = (AMBCTL1VAL >> 16);
302         r0.l = (AMBCTL1VAL & 0xFFFF);
303         [p2] = r0;
304         ssync;
305
306         p2.h = (EBIU_AMBCTL0 >> 16);
307         p2.l = (EBIU_AMBCTL0 & 0xFFFF);
308         r0.h = (AMBCTL0VAL >> 16);
309         r0.l = (AMBCTL0VAL & 0xFFFF);
310         [p2] = r0;
311         ssync;
312
313         p2.h = (EBIU_AMGCTL >> 16);
314         p2.l = (EBIU_AMGCTL & 0xffff);
315         r0 = AMGCTLVAL;
316         w[p2] = r0;
317         ssync;
318
319         /* DMA reset code to Hi of L1 SRAM */
320 copy:
321         P1.H = hi(SYSMMR_BASE); /* P1 Points to the beginning of SYSTEM MMR Space */
322         P1.L = lo(SYSMMR_BASE);
323
324         R0.H = reset_start;     /* Source Address (high) */
325         R0.L = reset_start;     /* Source Address (low) */
326         R1.H = reset_end;
327         R1.L = reset_end;
328         R2 = R1 - R0;           /* Count */
329         R1.H = hi(L1_ISRAM);    /* Destination Address (high) */
330         R1.L = lo(L1_ISRAM);    /* Destination Address (low) */
331         R3.L = DMAEN;           /* Source DMAConfig Value (8-bit words) */
332         R4.L = (DI_EN | WNR | DMAEN);   /* Destination DMAConfig Value (8-bit words) */
333
334 DMA:
335         R6 = 0x1 (Z);
336         W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6;   /* Source Modify = 1 */
337         W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6;   /* Destination Modify = 1 */
338
339         [P1+OFFSET_(MDMA_S0_START_ADDR)] = R0;  /* Set Source Base Address */
340         W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2;    /* Set Source Count */
341         /* Set Source  DMAConfig = DMA Enable,
342         Memory Read,  8-Bit Transfers, 1-D DMA, Flow - Stop */
343         W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3;
344
345         [P1+OFFSET_(MDMA_D0_START_ADDR)] = R1;  /* Set Destination Base Address */
346         W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2;    /* Set Destination Count */
347         /* Set Destination DMAConfig = DMA Enable,
348         Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */
349         W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4;
350
351         IDLE;   /* Wait for DMA to Complete */
352
353         R0 = 0x1;
354         W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */
355
356         /* DMA reset code to DATA BANK A which uses this port
357          * to avoid following problem
358          * " Data from a Data Cache fill can be corrupoted after or during
359          *   instruction DMA if certain core stalls exist"
360          */
361
362 copy_as_data:
363         R0.H = reset_start;     /* Source Address (high) */
364         R0.L = reset_start;     /* Source Address (low) */
365         R1.H = reset_end;
366         R1.L = reset_end;
367         R2 = R1 - R0;   /* Count */
368         R1.H = hi(DATA_BANKA_SRAM);     /* Destination Address (high) */
369         R1.L = lo(DATA_BANKA_SRAM);     /* Destination Address (low) */
370         R3.L = DMAEN;   /* Source DMAConfig Value (8-bit words) */
371         R4.L = (DI_EN | WNR | DMAEN);   /* Destination DMAConfig Value (8-bit words) */
372
373 DMA_DATA:
374         R6 = 0x1 (Z);
375         W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6;   /* Source Modify = 1 */
376         W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6;   /* Destination Modify = 1 */
377
378         [P1+OFFSET_(MDMA_S0_START_ADDR)] = R0;  /* Set Source Base Address */
379         W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2;    /* Set Source Count */
380         /* Set Source      DMAConfig = DMA Enable,
381         Memory Read,  8-Bit Transfers, 1-D DMA, Flow - Stop */
382         W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3;
383
384         [P1+OFFSET_(MDMA_D0_START_ADDR)] = R1;  /* Set Destination Base Address */
385         W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2;    /* Set Destination Count */
386         /* Set Destination DMAConfig = DMA Enable,
387         Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */
388         W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4;
389
390         IDLE;   /* Wait for DMA to Complete */
391
392         R0 = 0x1;
393         W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */
394
395 copy_end: nop;
396
397         /* Initialize BSS Section with 0 s */
398         p1.l = __bss_start;
399         p1.h = __bss_start;
400         p2.l = _end;
401         p2.h = _end;
402         r1 = p1;
403         r2 = p2;
404         r3 = r2 - r1;
405         r3 = r3 >> 2;
406         p3 = r3;
407         lsetup (_clear_bss, _clear_bss_end ) lc1 = p3;
408         CC = p2<=p1;
409         if CC jump _clear_bss_skip;
410         r0 = 0;
411 _clear_bss:
412 _clear_bss_end:
413         [p1++] = r0;
414 _clear_bss_skip:
415
416         p0.l = _start1;
417         p0.h = _start1;
418         jump (p0);
419
420 reset_start:
421         p0.h = WDOG_CNT >> 16;
422         p0.l = WDOG_CNT & 0xffff;
423         r0 = 0x0010;
424         w[p0] = r0;
425         p0.h = WDOG_CTL >> 16;
426         p0.l = WDOG_CTL & 0xffff;
427         r0 = 0x0000;
428         w[p0] = r0;
429 reset_wait:
430         jump reset_wait;
431
432 reset_end: nop;
433
434 _exit:
435         jump.s  _exit;