ARM: use BX when branch to an address in register
[kugel-rb.git] / firmware / target / arm / s3c2440 / crt0.S
blobfaa54313e7687436c3bbee7b775ed02fc3c1cd93
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2008 by Karl Kurbjun
11  *
12  * Arm bootloader and startup code based on startup.s from the iPodLinux
13  * loader
14  *  Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
15  *  Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
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
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23  * KIND, either express or implied.
24  *
25  ****************************************************************************/
26 #include "config.h"
27 #include "cpu.h"
29 #define CACHE_NONE  0
30 #define CACHE_ALL   0x0C
31 #define BUFFERED    0x04
32 /****************************************************************************/
33 #ifdef TOSHIBA_GIGABEAT_F
35 /* Clock and Power Management setup values */
36 #define VAL_CLKDIV  0x7
37 #define VAL_UPLLCON 0x0003C042
38 #define VAL_MPLLCON 0x000C9042
40 /* Memory Controller setup */
41     /* Memory setup (taken from 0x5070) */
42     /* BWSCON
43      *      Reserved 0
44      * Bank 0:
45      *      Bus width 01 (16 bit)
46      * Bank 1:
47      *      Buswidth 00 (8 bit)
48      *      Disable wait 0
49      *      Not using UB/LB 0
50      * Bank 2:
51      *      Buswidth 10 (32 bit)
52      *      Disable wait 0
53      *      Not using UB/LB 0
54      * Bank 3:
55      *      Buswidth 10 (32 bit)
56      *      Disable wait 0
57      *      Use UB/LB 1
58      * Bank 4:
59      *      Buswidth 10 (32 bit)
60      *      Disable wait 0
61      *      Use UB/LB 1
62      * Bank 5: 
63      *      Buswidth 00 (8 bit)
64      *      Disable wait 0
65      *      Not using UB/LB 0
66      * Bank 6:
67      *      Buswidth 10 (32 bit)
68      *      Disable wait 0
69      *      Not using UB/LB 0
70      * Bank 7:
71      *      Buswidth 00 (8 bit)
72      *      Disable wait 0
73      *      Not using UB/LB 0
74      */
75 #define VAL_BWSCON    0x01055102    
76     /* BANKCON0 
77      *      Pagemode: normal (1 data) 00
78      *      Pagemode access cycle: 2 clocks 00
79      *      Address hold: 2 clocks 10
80      *      Chip selection hold time: 1 clock 10
81      *      Access cycle: 8 clocks 101
82      *      Chip select setup time: 1 clock 01
83      *      Address setup time: 0 clock 00
84      */
85 #define VAL_BANKCON0  0x00000D60
86     /* BANKCON1 
87      *      Pagemode: normal (1 data) 00
88      *      Pagemode access cycle: 2 clocks 00
89      *      Address hold: 0 clocks 00
90      *      Chip selection hold time: 0 clock 00
91      *      Access cycle: 1 clocks 000
92      *      Chip select setup time: 0 clocks 00
93      *      Address setup time: 0 clocks 00
94      */
95 #define VAL_BANKCON1  0x00000000
96     /* BANKCON2 
97      *      Pagemode: normal (1 data) 00
98      *      Pagemode access cycle: 2 clocks 00
99      *      Address hold: 2 clocks 10
100      *      Chip selection hold time: 2 clocks 10
101      *      Access cycle: 14 clocks 111
102      *      Chip select setup time: 4 clocks 11
103      *      Address setup time: 0 clocks 00
104      */
105 #define VAL_BANKCON2  0x00001FA0
106 #define VAL_BANKCON3  0x00001D80
107 #define VAL_BANKCON4  0x00001D80
108 #define VAL_BANKCON5  0x00000000
109     /* BANKCON6/7
110      *      SCAN:   9 bit       01
111      *      Trcd:   3 clocks    01
112      *      Tcah:   0 clock     00
113      *      Tcoh:   0 clock     00
114      *      Tacc:   1 clock     000
115      *      Tcos:   0 clock     00
116      *      Tacs:   0 clock     00
117      *      MT:     Sync DRAM   11
118      */
119 #define VAL_BANKCON6  0x00018005
120 #define VAL_BANKCON7  0x00018005
122 #define VAL_REFRESH   0x00980501
123     /* BANKSIZE
124      *      BK76MAP: 32M/32M    000
125      *      Reserved: 0         0 (was 1)
126      *      SCLK_EN: always     1 (was 0)
127      *      SCKE_EN: disable    0
128      *      Reserved: 0         0
129      *      BURST_EN: enabled   1
130      */
131 #define VAL_BANKSIZE  0x00000090
132 #define VAL_MRSRB6    0x00000030
133 #define VAL_MRSRB7    0x00000030
134 #define VAL_GPACON    0x00FFFFFF
136 /****************************************************************************/
137 #elif defined (MINI2440)
139 /* For Mini2440 board or compatible */
140 /* Clock and Power Management setup values */
141 /* NB: clock settings must match values in s3c2440/system-target.h */
142 #define VAL_CLKDIV    0x5         /* HCLK = FCLK/4, PCLK = HCLK/2 */
143 #define VAL_UPLLCON   0x00038022  /* UCLK = 48 MHz */
144 #define VAL_MPLLCON   0x000C3041  /* FCLK = 406 MHz */
147 /* Memory Controller setup */
148 #define VAL_BWSCON    0x22111112    
149 #define VAL_BANKCON0  0x00002F50  
150 #define VAL_BANKCON1  0x00000700
151 #define VAL_BANKCON2  0x00000700
152 #define VAL_BANKCON3  0x00000700
153 #define VAL_BANKCON4  0x00000700
154 #define VAL_BANKCON5  0x0007FFFC
155 #define VAL_BANKCON6  0x00018009
156 #define VAL_BANKCON7  0x00018009
158 #define VAL_REFRESH   0x008E04EB
159 #define VAL_BANKSIZE  0x000000B2
160 #define VAL_MRSRB6    0x00000030
161 #define VAL_MRSRB7    0x00000030
163 #define VAL_GPACON    0x00FFFFFF
164 #define VAL_GPFCON    0x000055AA
165 #define VAL_GPGCON    0xAA2A0128
166 #define VAL_GPGDAT    0x0000
168 #else
169 #error Unknown target
170 #endif
171 /****************************************************************************/
173 /* Exception Handlers */
174 .section .vectors,"ax",%progbits
175 .code 32
177 .global vectors
178 vectors:
179     b   start
180     b   undef_instr_handler
181     b   software_int_handler
182     b   prefetch_abort_handler
183     b   data_abort_handler
184     b   reserved_handler
185     b   irq_handler
186     b   fiq_handler
188 /* This branch is used to make sure that we know where the shutdown routine
189  *  is located in flash (0x040A0020)
190  */
191     b   rom_shutdown
193 /* Add some strings to detect the bootloader in flash and give it a version
194  * number.  (0x040A0028, 0x040A002C)
195  */
196 .string "ROCKBOX\0"
197 .string "R 03.00\0"
200  * Function: word_copy
201  *  Variables:
202  *      r0 = from
203  *      r1 = to
204  *      r2 = length
205  */
207 .section    .init.text, "ax", %progbits
208 .align      0x04
209 .global     word_copy
210 .type       word_copy, %function
211 word_copy: 
212     subs    r2, r2, #0x04
213     ldrge   r3, [r0], #4
214     strge   r3, [r1], #4
215     bgt     word_copy
216     bx lr
217 .ltorg  
218 .size       word_copy, .-word_copy
222  * Entry: start
223  *  Variables:
224  *      none
225  */
227 .section    .init.text,"ax",%progbits
228 .code       32
229 .align      0x04 
230 .global     start
231 start:
233     /* Get the execute address; R0 is used to store the address and it should
234      * not be written to till the rest of the execution checks are done below.
235      * This is done first thing since we have to check if the code was started
236      * with the old rockbox bootloader that offset the image by 100 bytes.
237      */
238     ldr     r0, =0xffffff00
239     and     r0, pc, r0
241     /************************** DO NOT WRITE TO R0 ***************************/
243 #ifdef TOSHIBA_GIGABEAT_F
244     /* Check if the code is running from flash. If not skip all these checks */
245     cmp     r0, #0xA0000
246     bne     poweron
248     /* Point LCDSADDR1 to the boot logo for lcd_init_device in lcd-meg-fx.c */
249     mov     r2, #0x4D000000
250     ldr     r1, =0x020200A8
251     str     r1, [r2, #0x14]
252     
253     /* Did an RTC event wake the player up? */ 
254     mov     r2, #0x4A000000
255     ldr     r1, [r2]
256     ands    r1, r1, #0x40000000
258     /* Store a flag in GSTATUS3 to indicate that the bootloader is flashed */
259     ldr     r2, =0x560000b8
260     mov     r1, #0x02
261     
262     /* Woke up with the alarm? - store a flag in GSTATUS3 */
263     orrne   r1, r1, #0x01
264     str     r1, [r2]
265     bne     poweron
267     /* Set GPG up to read power and menu status */
268     ldr     r2, =0x56000050
269     ldr     r1, [r2, #0x18]
270     orr     r1, r1, #0x03
271     str     r1, [r2, #0x18]
273     /* Check if menu is held down */
274     ldr     r1, [r2, #0x14]
275     ands    r3, r1, #0x02
276     bne     bootOF
278     /* Check if power is held down  */
279     ands    r3, r1, #0x01
280     bne     poweron
282     /* Set GPF up to read charger connection if power is not held down */
283     ldr     r1, [r2, #0x08]
284     orr     r1, r1, #0x10
285     str     r1, [r2, #0x08]
287     /* Check if charger is connected */
288     ldr     r1, [r2, #0x04]
289     ands    r1, r1, #0x10
290     beq     poweron
292 bootOF:
293     /* power is not down || menu is held || the charger is not connected */
294     mov     pc, #0x70
295 #endif
297 poweron:
298     /* enter supervisor mode, disable IRQ */
299     msr     cpsr, #0xd3 
301     /* Disable the watchdog */
302     ldr     r2, =0x00000000
303     mov     r1, #0x53000000
304     str     r2, [r1]
306     /* Mask all Interupts to be safe */
307     ldr     r2, =0xFFFFFFFF
308     mov     r1, #0x4A000000
309     str     r2, [r1, #0x08]
311     /* Submask too */
312     ldr     r2, =0x00003FFF
313     str     r2, [r1, #0x1C]
315 #ifdef TOSHIBA_GIGABEAT_F
316     /* Check if loaded by the old bootloader or by the OF.  This copy routine
317      * cannot run/copy properly until the memory has been initialized, so the
318      * copy routine later is still necessary.  The old bootloader/OF will
319      * initialize the memory.
320      */
322     /* Calculate the length of the code needed to run/copy */
323     ldr     r1, = _vectorstart
324     ldr     r2, = _initdata_end
325     sub     r2, r2, r1
327     add     r3, r2, #0x30000000
329     /* Is there enough space to copy without overwriting? */
330     cmp     r0, r3
332     /* There's enough space, skip copying */
333     bgt     skipreset
335     /* Is this code running from 0xA0000?  If so skip copy. */
336     cmplt   r0, #0xA0000
337     beq     skipreset
339     /****************************** OK TO USE R0 *****************************/
340     
341     /* There's not enough space to copy without overwriting, copy to safe
342      * spot and reset
343      */
344     mov     r1, #0x31000000     /* copy location */
345     bl      word_copy
347     mov     pc, #0x31000000
348 #endif
350 skipreset:  
352     /* Initial Clock Setup */
353     /* set Bus to Asynchronous mode (full speed) */    
354     mov     r0, #0
355     mrc     p15, 0, r0, c1, c0, 0
356     ldr     r1,  =0xC0000000
357     orr     r0, r0, r1 
358     mcr     p15, 0, r0, c1, c0, 0
360     mov     r2, #VAL_CLKDIV
361     mov     r1, #0x4C000000
362     str     r2, [r1, #0x14]
364     mov     r2, #0x0
365     str     r2, [r1, #0x18]
367     ldr     r2, =0xFFFFFFFF
368     str     r2, [r1]
370     ldr     r2, =VAL_UPLLCON
371     str     r2, [r1, #0x08]
373     nop
374     nop
375     nop
376     nop
377     nop
378     nop
379     nop
380     nop
382     ldr     r2, =VAL_MPLLCON
383     str     r2, [r1, #0x04]
385     nop
386     nop
387     nop
388     nop
389     nop
390     nop
391     nop
392     nop
394     /* Setup MISCCR */
395     ldr     r2, =0x00613020
396     mov     r1, #0x56000000
397     str     r2, [r1, #0x80]
399     /* Memory setup */
401     ldr     r2, =VAL_BWSCON
402     mov     r1, #0x48000000
403     str     r2, [r1]
405     /* BANKCON0 */
406     ldr     r2, =VAL_BANKCON0
407     str     r2, [r1, #0x04]
409     /* BANKCON1 */
410     ldr     r2, =VAL_BANKCON1
411     str     r2, [r1, #0x08]
413     /* BANKCON2 */
414     ldr     r2, =VAL_BANKCON2
415     str     r2, [r1, #0xC]
417     /* BANKCON3 */
418     ldr     r2, =VAL_BANKCON3
419     str     r2, [r1, #0x10]
420     /* BANKCON4 */
421     str     r2, [r1, #0x14]
423     /* BANKCON5 */
424     ldr     r2, =VAL_BANKCON5
425     str     r2, [r1, #0x18]
427     /* BANKCON6/7 */
428     ldr     r2, =VAL_BANKCON6
429     str     r2, [r1, #0x1C]
430     /* BANKCON7 */
431     str     r2, [r1, #0x20]
433     /* REFRESH */
434     ldr     r2, =VAL_REFRESH
435     str     r2, [r1, #0x24]
437     /* BANKSIZE */
438     ldr     r2, =VAL_BANKSIZE
439     str     r2, [r1, #0x28]
441     /* MRSRB6 */
442     ldr     r2, =VAL_MRSRB6
443     str     r2, [r1, #0x2C]
444     /* MRSRB7 */
445     str     r2, [r1, #0x30]
446     
447     /* RMC: I guess this is some notes about Gigabeat */ 
448     /*
449         0x56000000 0x1FFFCFF
450                  4 0x1FFFEFF
451         0X4800002C 0X0
452         0X560000
453     */
455     /* GPACON */
456     mov     r1, #0x56000000 
457     ldr     r2, =VAL_GPACON
458     str     r2, [r1]
460 #if 0
461     /* GPGCON */
462     ldr     r2, =VAL_GPGCON
463     str     r2, [r1, #0x60]
464     ldr     r2, =VAL_GPGDAT
465     str     r2, [r1, #0x64]
466 #endif
468     /* Copy from current location (from NOR Flash if bootloader, load buffer if
469         firmware) to RAM */
470     
471     /* Gigabeat: The builds have two potential load addresses, one being from flash, 
472      * and the other from some "unknown" location right now the assumption
473      * is that the code is not at 0x3000000.
474      */   
475     /* get the high part of our execute address (where am I) */
476     ldr     r0, =0xfffff000
477     and     r0, pc, r0           /* copy from address */
479     /* SDRAM starts at 0x30000000 (physical address) */
480     ldr     r1, =0x30000000      /* copy To address */   
481     ldr     r2, = _vectorstart
482     ldr     r3, = _initdata_end
483     sub     r2, r3, r2           /* length of loader */
484     bl      word_copy
486     ldr     r1, =donecopy
487     ldr     r2, =0x30000000
488     add     r1, r1, r2
489     bx      r1               /* The code is located where we want it so jump */
491 donecopy: 
493     /* Setup the MMU, start by disabling */
495     mrc     p15, 0, r0, c1, c0, 0  
496     bic     r0, r0, #0x5           /* disable mmu and dcache */
497     bic     r0, r0, #0x1000        /* disable icache */
498     mcr     p15, 0, r0, c1, c0, 0
500     bl      ttb_init
501     
502     ldr     r0, =0x0
503     ldr     r1, =0x0
504     ldr     r2, =0x1000
505     mov     r3, #CACHE_NONE
506     bl      map_section
508     ldr     r0, =0x30000000
509     ldr     r1, =0x0
510     mov     r2, #MEMORYSIZE
511     mov     r3, #CACHE_ALL
512     bl      map_section
514     ldr     r0, =LCD_FRAME_ADDR    /* LCD Frame buffer */
515     mov     r1, r0
516     mov     r2, #1
517     mov     r3, #BUFFERED
518     bl      map_section        
519     
520     bl      enable_mmu   
522     /* Initialise bss section to zero */
523     ldr     r2, =_edata
524     ldr     r3, =_end
525     mov     r4, #0
526 bsszero:
527     cmp     r3, r2
528     strhi   r4, [r2], #4
529     bhi     bsszero
530     
531     /* Set up some stack and munge it with 0xdeadbeef */
532     ldr     sp, =stackend
533     mov     r3, sp
534     ldr     r2, =stackbegin
535     ldr     r4, =0xdeadbeef
536 stackmunge:
537     cmp     r3, r2
538     strhi   r4, [r2], #4
539     bhi     stackmunge
541      /* Set up stack for IRQ mode */
542     msr     cpsr_c, #0xd2
543     ldr     sp, =irq_stack
544     /* Set up stack for FIQ mode */ 
545     msr     cpsr_c, #0xd1
546     ldr     sp, =fiq_stack
548     /* Let abort and undefined modes use IRQ stack */
549     msr     cpsr_c, #0xd7
550     ldr     sp, =irq_stack
551     msr     cpsr_c, #0xdb
552     ldr     sp, =irq_stack
553     /* Switch to supervisor mode */
554     msr     cpsr_c, #0xd3
555     ldr     sp, =stackend
557     /* Start the main function */
558     ldr     lr, =vectors
559     ldr     pc, =main
561     /* Should never get here, but let's restart in case (also needed for
562      * linking)
563      */
564     b       vectors
566 /* All illegal exceptions call into UIE with exception address as first
567    parameter. This is calculated differently depending on which exception
568    we're in. Second parameter is exception number, used for a string lookup
569    in UIE.
570  */
571 undef_instr_handler:
572     sub    r0, lr, #4
573     mov    r1, #0
574     b      UIE
576 /* We run supervisor mode most of the time, and should never see a software
577    exception being thrown. Perhaps make it illegal and call UIE?
578  */
579 software_int_handler:
580 reserved_handler:
581     movs   pc, lr
583 prefetch_abort_handler:
584     sub    r0, lr, #4
585     mov    r1, #1
586     b      UIE
588 data_abort_handler:
589     sub    r0, lr, #8 
590     mov    r1, #2
591     b      UIE
593 #if defined(BOOTLOADER)
594 fiq_handler:
595     b UIE
596 #endif
598 UIE:
599     b UIE
601 /* TODO: Review this function - is it target dependent? */
603  * Function: rom_shutdown
604  *  Variables:
605  *      none
606  */
608 .section    .init.text, "ax", %progbits
609 .align      0x04
610 .global     rom_shutdown
611 .type       rom_shutdown, %function
612 rom_shutdown:
613     /* Turn off the MMU */
614     mrc     p15, 0, r1, c1, c0, 0
615     bic     r1, r1, #0x0001
616     mcr     p15, 0, r1, c1, c0, 0
618     /* Taken from 0x10010 */
619     ldr     r2, =0x56000014 //GPBDAT     
620     ldr     r1, =0x56000010 //GPBCON     
621     ldr     r3, =0x00015450 
622     ldr     r8, =0x56000024 //GPCDAT     
623     ldr     r10, =0x56000020 //GPCCON    
624     ldr     r5, =0xAAA054A8 
625     ldr     r6, =0x56000024 //GPDDAT     
626     ldr     r7, =0x56000030 //GPDCON     
627     ldr     r12, =0x56000044 //GPEDAT    
628     ldr     lr, =0x56000040 //GPECON     
629     ldr     r0, =0x56000054 //GPFDAT     
630     mov     r4, #0          
631     str     r4, [r2]        
632     str     r3, [r1]        
633     ldr     r1, =0xAAA0AAA5 
634     ldr     r2, =0xAA8002AA 
635     mov     r3, #0x80       
636     str     r3, [r8]        
637     add     r3, r3, #0x980  
638     str     r5, [r10]       
639     mov     r5, #4          
640     str     r4, [r6]        
641     str     r1, [r7]        
642     str     r4, [r12]       
643     str     r2, [lr]        
644     str     r4, [r0],#(0x56000064-0x56000054) //(GPGDAT - GPFDAT) 
645     add     r12, r12, #(0x56000060-0x56000044)//(GPGCON - GPEDAT) 
646     ldr     r1, =0x56000050 //GPFCON     
647     ldr     r2, =0x01401002 
648     mov    lr, #0xFFFFFFFF
649     str     r3, [r1],#(0x56000074-0x56000050)// (GPHDAT - GPFCON) 
650     str     r4, [r0],#(0x56000060-0x56000054)// (GPGCON - GPFDAT) 
651 //    str     r2, [r12]
652     ldr     r2, =0x140A5    
653     mov     r3, #0x81       
654     str     r3, [r1]        
655     ldr     r12, =0x4A000008 //INTMSK    
657 //    mov     r3, #0x200000   // disable EINT13
658     ldr     r3, =0xFFFFFECF
660     str     r2, [r0]        // GPFDAT=0x140A5
661     ldr     r2, =0x56000088 //EXTINT0    
662     ldr     r0, =0x4A000010 //INTPND 
664     add     r1, r1, #(0x56000068 - 0x56000050) // (GPGUP - GPFCON) (0x18)
665     str     lr, [r12]       /* INTMSK = 0xFFFFFFFF */
666     str     r3, [r2],#(0x560000A4 - 0x56000088) // (EINTMASK - EXTINT0) disable EINT13 (0x1C)
667 //    mov    r3, #0xFFFFFECF
668     mov    r3, #0xFFFFFEFF
669     str     r5, [r1],#(0x56000074-0x56000058) //(GPHDAT - GPFUP) (0x1C) DCLKCON
670     str     r3, [r2]
672     ldr     r11, =0x56000060
673     ldr     r6, =0x01401002
674     str     r6, [r11]
676 //    add     r3, r3, #0x00000100 
677     ldr     r3, =0xFFFFFFDF;
678     str     r3, [r12]       // disable INT_TICK
680     mov     r3, #0x4A000000     
681     add     r2, r2, #(0x560000B0-0x56000088) //(GSTATUS1 - EXTINT0) //; 0x600 (0x28)
682     str     lr, [r1]        
683     str     lr, [r3]        
684     mov     r3, #0x600      
685     str     lr, [r0]        
686     str     r3, [r2]        // GSTATUS1 = 0x600 /* what for ??? */
688     ldr     r12, =0x56000080 //MISCCr    
689     mov     r2, #0x58000000 //ADCCON     
690     str     r5, [r2]        
691     add     r2, r2, #(0x4D000000-0x58000000) //(LCDCON1 - ADCCON) // LCDCON1 (0xF5000000)
692     ldr     r3, [r12]       
693     ldr     r0, =0x48000024 // REFRESH   
694     bic     r3, r3, #0x700000 
695     bic     r3, r3, #0x3000
696     orr     r3, r3, #0x600000
697     orr     r3, r3, #0x3000 
698     str     r3, [r12]       // MISCCR = (MISCCR & ~0x100000) | 0x603000;
699     /* clear [20] BATTFLT_FUNC - BATT_FLT function On/Off.
700      *            0, Battery fault function will be turned on.
701      * set [21] BATTFLT_INTR - BATT_FLT Interrupt On/Off.
702      *            1, Battery fault interrupt will be masked by hardware.
703      * set [13] SEL_SUSPND1 - USB Port 1 Suspend mode
704      *            1= suspend mode
705      * set [12] SEL_SUSPND0 - USB Port 0 Suspend mode
706      *            1= suspend mode
707     */
708     mov     r3, #0x4C000000 // LOCKTIME   
709     str     r4, [r2]     
710   
711     str     lr, [r3]        
712     ldr     r1, [r0]        
713     ldr     lr, =0x4C00000C // CLKCON     
714 //    str     r1, [r11,#-0x28] 
715     ldr     r2, [lr]        
716 //    str     r2, [r11,#-0x28] 
717     ldr     r3, [r0]        
718     orr     r3, r3, #0x00C00000
719     /* REFRESH
720      * [22] TREFMD - SDRAM Refresh Mode
721      */
722     str     r3, [r0]        
723     ldr     r2, [r12]       
725     ldr     r3, =0x00004018
726     /* [3] SLEEP - Control SLEEP mode of S3C2440X.
727      * [4] NAND - Control HCLK into NAND Flash Controller block.
728      * [14] RTC - Control PCLK into RTC control block.
729      */
730     orr     r2, r2, #0x000E0000 
731     /* [17] nEN_SCLK0 - SCLK0 output enable (1: SCLK 0 = 0)
732      * [18] nEN_SCLK1 - SCLK1 output enable (1: SCLK 1 = 0)
733      * [19] OFFREFRESH - Self refresh retain enable after wake-up from sleep
734      */
736     str     r2, [r12]       
737     str     r3, [lr]
738     
739     1:
740     b 1b
741 .ltorg  
742 .size       rom_shutdown, .-rom_shutdown
744 .section .text
745 /* 256 words of IRQ stack */
746     .space 256*4
747 irq_stack:
749 /* 256 words of FIQ stack */
750     .space 256*4
751 fiq_stack: