Blackfin arch: dont clear status register bits in SWRST so we can actually use it
[linux-2.6.git] / arch / blackfin / mach-bf537 / head.S
1 /*
2  * File:         arch/blackfin/mach-bf537/head.S
3  * Based on:     arch/blackfin/mach-bf533/head.S
4  * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
5  *
6  * Created:      1998
7  * Description:  Startup code for Blackfin BF537
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
47 ENTRY(__start)
48 ENTRY(__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
130         /* Initialise General-Purpose I/O Modules on BF537 */
131         /* Rev 0.0 Anomaly 05000212 - PORTx_FER,
132          * PORT_MUX Registers Do Not accept "writes" correctly:
133          */
134         p0.h = hi(BFIN_PORT_MUX);
135         p0.l = lo(BFIN_PORT_MUX);
136 #ifdef ANOMALY_05000212
137         R0.L = W[P0]; /* Read */
138         SSYNC;
139 #endif
140         R0 = (PGDE_UART | PFTE_UART)(Z);
141 #ifdef ANOMALY_05000212
142         W[P0] = R0.L; /* Write */
143         SSYNC;
144 #endif
145         W[P0] = R0.L; /* Enable both UARTS */
146         SSYNC;
147
148         p0.h = hi(PORTF_FER);
149         p0.l = lo(PORTF_FER);
150 #ifdef ANOMALY_05000212
151         R0.L = W[P0]; /* Read */
152         SSYNC;
153 #endif
154         R0 = 0x000F(Z);
155 #ifdef ANOMALY_05000212
156         W[P0] = R0.L; /* Write */
157         SSYNC;
158 #endif
159         /* Enable peripheral function of PORTF for UART0 and UART1 */
160         W[P0] = R0.L;
161         SSYNC;
162
163 #if !defined(CONFIG_BF534)
164         p0.h = hi(EMAC_SYSTAT);
165         p0.l = lo(EMAC_SYSTAT);
166         R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
167         R0.l = 0xFFFF;
168         [P0] = R0;
169         SSYNC;
170 #endif
171
172 #ifdef CONFIG_BF537_PORT_H
173         p0.h = hi(PORTH_FER);
174         p0.l = lo(PORTH_FER);
175         R0.L = W[P0]; /* Read */
176         SSYNC;
177         R0 = 0x0000;
178         W[P0] = R0.L; /* Write */
179         SSYNC;
180         W[P0] = R0.L; /* Disable peripheral function of PORTH */
181         SSYNC;
182 #endif
183
184         /*Initialise UART*/
185         p0.h = hi(UART_LCR);
186         p0.l = lo(UART_LCR);
187         r0 = 0x0(Z);
188         w[p0] = r0.L;   /* To enable DLL writes */
189         ssync;
190
191         p0.h = hi(UART_DLL);
192         p0.l = lo(UART_DLL);
193         r0 = 0x00(Z);
194         w[p0] = r0.L;
195         ssync;
196
197         p0.h = hi(UART_DLH);
198         p0.l = lo(UART_DLH);
199         r0 = 0x00(Z);
200         w[p0] = r0.L;
201         ssync;
202
203         p0.h = hi(UART_GCTL);
204         p0.l = lo(UART_GCTL);
205         r0 = 0x0(Z);
206         w[p0] = r0.L;   /* To enable UART clock */
207         ssync;
208
209         /* Initialize stack pointer */
210         sp.l = lo(INITIAL_STACK);
211         sp.h = hi(INITIAL_STACK);
212         fp = sp;
213         usp = sp;
214
215         /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
216         call _bf53x_relocate_l1_mem;
217 #if CONFIG_BFIN_KERNEL_CLOCK
218         call _start_dma_code;
219 #endif
220         /* Code for initializing Async memory banks */
221
222         p2.h = hi(EBIU_AMBCTL1);
223         p2.l = lo(EBIU_AMBCTL1);
224         r0.h = hi(AMBCTL1VAL);
225         r0.l = lo(AMBCTL1VAL);
226         [p2] = r0;
227         ssync;
228
229         p2.h = hi(EBIU_AMBCTL0);
230         p2.l = lo(EBIU_AMBCTL0);
231         r0.h = hi(AMBCTL0VAL);
232         r0.l = lo(AMBCTL0VAL);
233         [p2] = r0;
234         ssync;
235
236         p2.h = hi(EBIU_AMGCTL);
237         p2.l = lo(EBIU_AMGCTL);
238         r0 = AMGCTLVAL;
239         w[p2] = r0;
240         ssync;
241
242         /* This section keeps the processor in supervisor mode
243          * during kernel boot.  Switches to user mode at end of boot.
244          * See page 3-9 of Hardware Reference manual for documentation.
245          */
246
247         /* EVT15 = _real_start */
248
249         p0.l = lo(EVT15);
250         p0.h = hi(EVT15);
251         p1.l = _real_start;
252         p1.h = _real_start;
253         [p0] = p1;
254         csync;
255
256         p0.l = lo(IMASK);
257         p0.h = hi(IMASK);
258         p1.l = IMASK_IVG15;
259         p1.h = 0x0;
260         [p0] = p1;
261         csync;
262
263         raise 15;
264         p0.l = .LWAIT_HERE;
265         p0.h = .LWAIT_HERE;
266         reti = p0;
267 #if defined(ANOMALY_05000281)
268         nop; nop; nop;
269 #endif
270         rti;
271
272 .LWAIT_HERE:
273         jump .LWAIT_HERE;
274
275 ENTRY(_real_start)
276         [ -- sp ] = reti;
277         p0.l = lo(WDOG_CTL);
278         p0.h = hi(WDOG_CTL);
279         r0 = 0xAD6(z);
280         w[p0] = r0;     /* watchdog off for now */
281         ssync;
282
283         /* Code update for BSS size == 0
284          * Zero out the bss region.
285          */
286
287         p1.l = ___bss_start;
288         p1.h = ___bss_start;
289         p2.l = ___bss_stop;
290         p2.h = ___bss_stop;
291         r0 = 0;
292         p2 -= p1;
293         lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
294 .L_clear_bss:
295         B[p1++] = r0;
296
297         /* In case there is a NULL pointer reference
298          * Zero out region before stext
299          */
300
301         p1.l = 0x0;
302         p1.h = 0x0;
303         r0.l = __stext;
304         r0.h = __stext;
305         r0 = r0 >> 1;
306         p2 = r0;
307         r0 = 0;
308         lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
309 .L_clear_zero:
310         W[p1++] = r0;
311
312         /* pass the uboot arguments to the global value command line */
313         R0 = R7;
314         call _cmdline_init;
315
316         p1.l = __rambase;
317         p1.h = __rambase;
318         r0.l = __sdata;
319         r0.h = __sdata;
320         [p1] = r0;
321
322         p1.l = __ramstart;
323         p1.h = __ramstart;
324         p3.l = ___bss_stop;
325         p3.h = ___bss_stop;
326
327         r1 = p3;
328         [p1] = r1;
329
330
331         /*
332          *  load the current thread pointer and stack
333          */
334         r1.l = _init_thread_union;
335         r1.h = _init_thread_union;
336
337         r2.l = 0x2000;
338         r2.h = 0x0000;
339         r1 = r1 + r2;
340         sp = r1;
341         usp = sp;
342         fp = sp;
343         call _start_kernel;
344 .L_exit:
345         jump.s  .L_exit;
346
347 .section .l1.text
348 #if CONFIG_BFIN_KERNEL_CLOCK
349 ENTRY(_start_dma_code)
350
351         /* Enable PHY CLK buffer output */
352         p0.h = hi(VR_CTL);
353         p0.l = lo(VR_CTL);
354         r0.l = w[p0];
355         bitset(r0, 14);
356         w[p0] = r0.l;
357         ssync;
358
359         p0.h = hi(SIC_IWR);
360         p0.l = lo(SIC_IWR);
361         r0.l = 0x1;
362         r0.h = 0x0;
363         [p0] = r0;
364         SSYNC;
365
366         /*
367          *  Set PLL_CTL
368          *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
369          *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
370          *   - [7]     = output delay (add 200ps of delay to mem signals)
371          *   - [6]     = input delay (add 200ps of input delay to mem signals)
372          *   - [5]     = PDWN      : 1=All Clocks off
373          *   - [3]     = STOPCK    : 1=Core Clock off
374          *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
375          *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
376          *   all other bits set to zero
377          */
378
379         p0.h = hi(PLL_LOCKCNT);
380         p0.l = lo(PLL_LOCKCNT);
381         r0 = 0x300(Z);
382         w[p0] = r0.l;
383         ssync;
384
385         P2.H = hi(EBIU_SDGCTL);
386         P2.L = lo(EBIU_SDGCTL);
387         R0 = [P2];
388         BITSET (R0, 24);
389         [P2] = R0;
390         SSYNC;
391
392         r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
393         r0 = r0 << 9;                    /* Shift it over,                  */
394         r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
395         r0 = r1 | r0;
396         r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
397         r1 = r1 << 8;                    /* Shift it over                   */
398         r0 = r1 | r0;                    /* add them all together           */
399
400         p0.h = hi(PLL_CTL);
401         p0.l = lo(PLL_CTL);              /* Load the address                */
402         cli r2;                          /* Disable interrupts              */
403         ssync;
404         w[p0] = r0.l;                    /* Set the value                   */
405         idle;                            /* Wait for the PLL to stablize    */
406         sti r2;                          /* Enable interrupts               */
407
408 .Lcheck_again:
409         p0.h = hi(PLL_STAT);
410         p0.l = lo(PLL_STAT);
411         R0 = W[P0](Z);
412         CC = BITTST(R0,5);
413         if ! CC jump .Lcheck_again;
414
415         /* Configure SCLK & CCLK Dividers */
416         r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
417         p0.h = hi(PLL_DIV);
418         p0.l = lo(PLL_DIV);
419         w[p0] = r0.l;
420         ssync;
421
422         p0.l = lo(EBIU_SDRRC);
423         p0.h = hi(EBIU_SDRRC);
424         r0 = mem_SDRRC;
425         w[p0] = r0.l;
426         ssync;
427
428         p0.l = (EBIU_SDBCTL & 0xFFFF);
429         p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
430         r0 = mem_SDBCTL;
431         w[p0] = r0.l;
432         ssync;
433
434         P2.H = hi(EBIU_SDGCTL);
435         P2.L = lo(EBIU_SDGCTL);
436         R0 = [P2];
437         BITCLR (R0, 24);
438         p0.h = hi(EBIU_SDSTAT);
439         p0.l = lo(EBIU_SDSTAT);
440         r2.l = w[p0];
441         cc = bittst(r2,3);
442         if !cc jump .Lskip;
443         NOP;
444         BITSET (R0, 23);
445 .Lskip:
446         [P2] = R0;
447         SSYNC;
448
449         R0.L = lo(mem_SDGCTL);
450         R0.H = hi(mem_SDGCTL);
451         R1 = [p2];
452         R1 = R1 | R0;
453         [P2] = R1;
454         SSYNC;
455
456         p0.h = hi(SIC_IWR);
457         p0.l = lo(SIC_IWR);
458         r0.l = lo(IWR_ENABLE_ALL);
459         r0.h = hi(IWR_ENABLE_ALL);
460         [p0] = r0;
461         SSYNC;
462
463         RTS;
464 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
465
466 ENTRY(_bfin_reset)
467         /* No more interrupts to be handled*/
468         CLI R6;
469         SSYNC;
470
471 #if defined(CONFIG_MTD_M25P80)
472 /*
473  * The following code fix the SPI flash reboot issue,
474  * /CS signal of the chip which is using PF10 return to GPIO mode
475  */
476         p0.h = hi(PORTF_FER);
477         p0.l = lo(PORTF_FER);
478         r0.l = 0x0000;
479         w[p0] = r0.l;
480         SSYNC;
481
482 /* /CS return to high */
483         p0.h = hi(PORTFIO);
484         p0.l = lo(PORTFIO);
485         r0.l = 0xFFFF;
486         w[p0] = r0.l;
487         SSYNC;
488
489 /* Delay some time, This is necessary */
490         r1.h = 0;
491         r1.l = 0x400;
492         p1   = r1;
493         lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
494 _delay_lab1:
495         r0.h = 0;
496         r0.l = 0x8000;
497         p0   = r0;
498         lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
499 _delay_lab0:
500         nop;
501 _delay_lab0_end:
502         nop;
503 _delay_lab1_end:
504         nop;
505 #endif
506
507         /* Clear the IMASK register */
508         p0.h = hi(IMASK);
509         p0.l = lo(IMASK);
510         r0 = 0x0;
511         [p0] = r0;
512
513         /* Clear the ILAT register */
514         p0.h = hi(ILAT);
515         p0.l = lo(ILAT);
516         r0 = [p0];
517         [p0] = r0;
518         SSYNC;
519
520         /* Disable the WDOG TIMER */
521         p0.h = hi(WDOG_CTL);
522         p0.l = lo(WDOG_CTL);
523         r0.l = 0xAD6;
524         w[p0] = r0.l;
525         SSYNC;
526
527         /* Clear the sticky bit incase it is already set */
528         p0.h = hi(WDOG_CTL);
529         p0.l = lo(WDOG_CTL);
530         r0.l = 0x8AD6;
531         w[p0] = r0.l;
532         SSYNC;
533
534         /* Program the count value */
535         R0.l = 0x100;
536         R0.h = 0x0;
537         P0.h = hi(WDOG_CNT);
538         P0.l = lo(WDOG_CNT);
539         [P0] = R0;
540         SSYNC;
541
542         /* Program WDOG_STAT if necessary */
543         P0.h = hi(WDOG_CTL);
544         P0.l = lo(WDOG_CTL);
545         R0 = W[P0](Z);
546         CC = BITTST(R0,1);
547         if !CC JUMP .LWRITESTAT;
548         CC = BITTST(R0,2);
549         if !CC JUMP .LWRITESTAT;
550         JUMP .LSKIP_WRITE;
551
552 .LWRITESTAT:
553         /* When watch dog timer is enabled,
554          * a write to STAT will load the contents of CNT to STAT
555          */
556         R0 = 0x0000(z);
557         P0.h = hi(WDOG_STAT);
558         P0.l = lo(WDOG_STAT)
559         [P0] = R0;
560         SSYNC;
561
562 .LSKIP_WRITE:
563         /* Enable the reset event */
564         P0.h = hi(WDOG_CTL);
565         P0.l = lo(WDOG_CTL);
566         R0 = W[P0](Z);
567         BITCLR(R0,1);
568         BITCLR(R0,2);
569         W[P0] = R0.L;
570         SSYNC;
571         NOP;
572
573         /* Enable the wdog counter */
574         R0 = W[P0](Z);
575         BITCLR(R0,4);
576         W[P0] = R0.L;
577         SSYNC;
578
579         IDLE;
580
581         RTS;
582
583 .data
584
585 /*
586  * Set up the usable of RAM stuff. Size of RAM is determined then
587  * an initial stack set up at the end.
588  */
589
590 .align 4
591 __rambase:
592 .long   0
593 __ramstart:
594 .long   0
595 __ramend:
596 .long   0