S5L870x: Fix PCLK freq
[kugel-rb.git] / firmware / target / arm / s5l8700 / crt0.S
blob3cc376711c78b2aa6a32f97e60f1163e34485c36
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id: crt0.S 18776 2008-10-11 18:32:17Z gevaerts $
9  *
10  * Copyright (C) 2008 by Marcoen Hirschberg
11  * Copyright (C) 2008 by Denes Balatoni
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ****************************************************************************/
22 #include "config.h"
23 #include "cpu.h"
25     .section .intvect,"ax",%progbits
26     .global    start
27     .global    _newstart
28     /* Exception vectors */
29 start:
30 #if CONFIG_CPU==S5L8701 && defined(BOOTLOADER)
31     b newstart2
32 #else
33     b _newstart
34 #endif
35     ldr pc, =undef_instr_handler
36     ldr pc, =software_int_handler
37     ldr pc, =prefetch_abort_handler
38     ldr pc, =data_abort_handler
39     ldr pc, =reserved_handler
40     ldr pc, =irq_handler
41     ldr pc, =fiq_handler
42 #if CONFIG_CPU==S5L8700
43     .word 0x43554644 /* DFUC */
44 #endif
45     .ltorg
46 _newstart:
47     ldr pc, =newstart2 // we do not want to execute from 0x0 as iram will be mapped there
48     .section .init.text,"ax",%progbits
49 newstart2:
50     msr     cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
52 #ifdef ROCKBOX_BIG_ENDIAN
53     mov r1, #0x80
54     mrc 15, 0, r0, c1, c0, 0
55     orr r0, r0, r1
56     mcr 15, 0, r0, c1, c0, 0 // set bigendian
57 #endif
58                          
59     ldr r1, =0x3c800000 // disable watchdog
60     mov r0, #0xa5
61     str r0, [r1]
63     mov r0, #0
64     mov r1, #0x39c00000
65     str r0, [r1,#0x08] // mask all interrupts
66     str r0, [r1,#0x20] // mask all external interrupts
67     mvn r0, #0
68     str r0, [r1,#0x1c] // clear pending external interrupts
69     str r0, [r1] // irq priority
70     str r0, [r1,#0x10] // clear pending interrupts
72 //    ldr r1, =0x3cf00000
73 //    ldr r0, [r1]
74 //    mvn r2, #0x30
75 //    and r0, r0, r2
76 //    mov r2, #0x10
77 //    orr r0, r0, r2
78 //    str r0, [r1]
79 //    ldr r0, [r1,#0x04]
80 //    mov r2, #4
81 //    orr r0, r0, r2
82 //    str r0, [r1,#0x04] // switch backlight on
84 #if CONFIG_CPU==S5L8701
85     ldr r1, =0x38200000
86     ldr r2, [r1]
87     orr r2, r2, #1
88     bic r2, r2, #0x10000
89     str r2, [r1] // remap iram to address 0x0
91 #ifdef BOOTLOADER
92     /* Relocate ourself to IRAM - we have been loaded to DRAM */
93     mov    r0, #0x08000000   /* source (DRAM) */
94     mov    r1, #0x00000000   /* dest (IRAM) */
95     ldr    r2, =_dataend
97     cmp    r2, r1
98     ldrhi  r3, [r0], #4
99     strhi  r3, [r1], #4
100     bhi    1b
102     ldr    pc, =start_loc    /* jump to the relocated start_loc:  */
103 start_loc:
104 #endif /* BOOTLOADER */
105 #endif /* CONFIG_CPU==S5L8701 */
107     ldr r1, =0x3c500000 
108     ldr r0, =0x00800080
109     str r0, [r1]                // CLKCON
110     mov r0, #0
111     str r0, [r1,#0x24]  // PLLCON
112 #ifdef IPOD_NANO2G
113     ldr r0, =0x21200    // pdiv=2, mdiv=0x12 sdiv=0
114 #else
115     ldr r0, =0x1ad200   // pdiv=0x1a, mdiv=0xd2 sdiv=0
116 #endif
117     str r0, [r1,#0x04]  // PLL0PMS
118     ldr r0, =8100
119     str r0, [r1,#0x14]  // PLL0LCNT
120     mov r0, #1
121     str r0, [r1,#0x24]  // PLLCON
123     ldr r0, [r1,#0x20]  // PLLLOCK
124     tst r0, #1
125     beq 1b
126     mov r0, #0x280
127     str r0, [r1,#0x3c]  // CLKCON2
128     ldr r0, =0x20803180 // FCLK_CPU = 200MHz, HCLK = 100MHz, PCLK = 50MHz, other clocks off
129     str r0, [r1]        // CLKCON
131     ldr r2, =0xc0000078
132     mrc 15, 0, r0, c1, c0, 0
133     mvn r1, #0xc0000000
134     and r0, r0, r1
135     orr r0, r0, r2
136     mcr 15, 0, r0, c1, c0, 0 // asynchronous clocking mode
137     nop
138     nop                                         
139     nop
140     nop
141         
142 //    ldr r0, =0x10100000
143 //    ldr r1, =0x38200034
144 //    str r0, [r1] // SRAM0/1 data width 16 bit
145 //    ldr r0, =0x00220922
146 //    ldr r7, =0x38200038
147 //    str r0, [r7] // SRAM0/1 clocks
148 //    ldr r0, =0x00220922
149 //    ldr r9, =0x3820003c
150 //    str r0, [r9] // SRAM2/3 clocks
151 //    nop
152 //    nop
153 //    nop
154 //    nop
156 /* The following two sections of code (i.e. Nano2G and Meizus) should
157    be unified at some point. */
158 #ifdef IPOD_NANO2G
160     ldr r1, =0x3c500000 
161     ldr r0, =0xffdff7ff
162     str r0, [r1,#0x28]  // PWRCON
163     ldr r0, =0xffffef7e
164     str r0, [r1,#0x40]  // PWRCONEXT
166     mrc 15, 0, r0, c1, c0, 0
167     bic r0, r0, #0x1000
168     bic r0, r0, #0x5
169     mcr 15, 0, r0, c1, c0, 0 // disable caches and protection unit
171     mov r1, #0
173     mov r0, #0
175     orr r2, r1, r0
176     mcr 15, 0, r2, c7, c14, 2 // clean and flush dcache single entry
177     add r0, r0, #0x10
178     cmp r0, #0x40
179     bne 2b
180     add r1, r1, #0x4000000
181     cmp r1, #0x0
182     bne 1b
183     nop
184     nop
185     mov r0, #0
186     mcr 15, 0, r0, c7, c10, 4 // clean and flush whole dcache
187     mcr 15, 0, r0, c7, c5, 0 // flush icache
188     mcr 15, 0, r0, c7, c6, 0 // flush dcache
190     mov r0, #0x3f
191     mcr 15, 0, r0, c6, c0, 1 // CS0: 4GB at offset 0 - everything
192     mcr 15, 0, r0, c6, c0, 0 // DS0: 4GB at offset 0 - everything
193 #ifdef IPOD_NANO2G
194     mov r0, #0x31 // FIXME: calculate that from MEMORYSIZE
195 #else
196     mov r0, #0x2f // FIXME: calculate that from MEMORYSIZE
197 #endif
198     mcr 15, 0, r0, c6, c1, 1 // CS1: SRAM/SDRAM mirror
199     mcr 15, 0, r0, c6, c1, 0 // DS1: SRAM/SDRAM mirror
200     add r0, r0, #0x08000000
201     mcr 15, 0, r0, c6, c2, 1 // CS2: SDRAM
202     mcr 15, 0, r0, c6, c2, 0 // DS2: SDRAM
203     ldr r0, =0x22000023
204     mcr 15, 0, r0, c6, c3, 1 // CS3: SRAM
205     mcr 15, 0, r0, c6, c3, 0 // DS3: SRAM
206     ldr r0, =0x24000027
207     mcr 15, 0, r0, c6, c4, 1 // CS4: NOR flash
208     mcr 15, 0, r0, c6, c4, 0 // DS4: NOR flash
209     mov r0, #0
210     mcr 15, 0, r0, c6, c5, 1 // CS5: unused
211     mcr 15, 0, r0, c6, c5, 0 // DS5: unused
212     mcr 15, 0, r0, c6, c6, 1 // CS6: unused
213     mcr 15, 0, r0, c6, c6, 0 // DS6: unused
214     mcr 15, 0, r0, c6, c7, 1 // CS7: unused
215     mcr 15, 0, r0, c6, c7, 0 // DS7: unused
216     mov r0, #0x1e
217     mcr 15, 0, r0, c2, c0, 1 // CS1-4: cacheable
218     mcr 15, 0, r0, c2, c0, 0 // DS1-4: cacheable
219     mcr 15, 0, r0, c3, c0, 0 // DS1-4: write cacheable
220     ldr r0, =0x000003ff
221     mcr 15, 0, r0, c5, c0, 1 // CS0-4: full access
222     mcr 15, 0, r0, c5, c0, 0 // DS0-4: full access
224     mrc 15, 0, r0, c1, c0, 0
225     orr r0, r0, #0x5
226     orr r0, r0, #0x1000
227     mcr 15, 0, r0, c1, c0, 0 // re-enable protection unit and caches
229 #else
231     ldr r1, =0x3c500000
232     mov r0, #0  // 0x0
233     str r0, [r1, #40] // enable clock for all peripherals
234     mov r0, #0  // 0x0
235     str r0, [r1, #44] // do not enter any power saving mode
237     mov r1, #0x1
238     mrc 15, 0, r0, c1, c0, 0
239     bic r0, r0, r1
240     mcr 15, 0, r0, c1, c0, 0 // disable protection unit
242     mov r1, #0x4
243     mrc 15, 0, r0, c1, c0, 0
244     bic r0, r0, r1
245     mcr 15, 0, r0, c1, c0, 0 // dcache disable
247     mov r1, #0x1000
248     mrc 15, 0, r0, c1, c0, 0
249     bic r0, r0, r1
250     mcr 15, 0, r0, c1, c0, 0 // icache disable
252     mov r1, #0
254     mov r0, #0
256     orr r2, r1, r0
257     mcr 15, 0, r2, c7, c14, 2 // clean and flush dcache single entry
258     add r0, r0, #0x10
259     cmp r0, #0x40
260     bne 2b
261     add r1, r1, #0x4000000
262     cmp r1, #0x0
263     bne 1b
264     nop
265     nop
266     mov r0, #0
267     mcr 15, 0, r0, c7, c10, 4 // clean and flush whole dcache
269     mov r0, #0
270     mcr 15, 0, r0, c7, c5, 0 // flush icache
271     
272     mov r0, #0
273     mcr 15, 0, r0, c7, c6, 0 // flush dcache
275     mov r0, #0x3f
276     mcr 15, 0, r0, c6, c0, 1
277     mov r0, #0x2f
278     mcr 15, 0, r0, c6, c1, 1
279     ldr r0, =0x08000031
280     mcr 15, 0, r0, c6, c2, 1
281     ldr r0, =0x22000023
282     mcr 15, 0, r0, c6, c3, 1
283     ldr r0, =0x24000027
284     mcr 15, 0, r0, c6, c4, 1
285     mov r0, #0x3f
286     mcr 15, 0, r0, c6, c0, 0
287     mov r0, #0x2f
288     mcr 15, 0, r0, c6, c1, 0
289     ldr r0, =0x08000031
290     mcr 15, 0, r0, c6, c2, 0
291     ldr r0, =0x22000023
292     mcr 15, 0, r0, c6, c3, 0
293     ldr r0, =0x24000029
294     mcr 15, 0, r0, c6, c4, 0
295     mov r0, #0x1e
296     mcr 15, 0, r0, c2, c0, 1
297     mov r0, #0x1e
298     mcr 15, 0, r0, c2, c0, 0
299     mov r0, #0x1e
300     mcr 15, 0, r0, c3, c0, 0
301     ldr r0, =0x0000ffff
302     mcr 15, 0, r0, c5, c0, 1
303     ldr r0, =0x0000ffff
304     mcr 15, 0, r0, c5, c0, 0 // set up protection and caching
306     mov r1, #0x4
307     mrc 15, 0, r0, c1, c0, 0
308     orr r0, r0, r1
309     mcr 15, 0, r0, c1, c0, 0 // dcache enable
311     mov r1, #0x1000
312     mrc 15, 0, r0, c1, c0, 0
313     orr r0, r0, r1
314     mcr 15, 0, r0, c1, c0, 0 // icache enable
316     mov r1, #0x1
317     mrc 15, 0, r0, c1, c0, 0
318     orr r0, r0, r1
319     mcr 15, 0, r0, c1, c0, 0 // enable protection unit
320 #endif
322 #if CONFIG_CPU==S5L8700 || !defined(BOOTLOADER)
323     /* Copy interrupt vectors to iram */
324     ldr     r2, =_intvectstart
325     ldr     r3, =_intvectend
326     ldr     r4, =_intvectcopy
328     cmp     r3, r2
329     ldrhi   r1, [r4], #4
330     strhi   r1, [r2], #4
331     bhi     1b
332 #endif
334     /* Initialise bss section to zero */
335     ldr     r2, =_edata
336     ldr     r3, =_end
337     mov     r4, #0
339     cmp     r3, r2
340     strhi   r4, [r2], #4
341     bhi     1b
343 #if CONFIG_CPU==S5L8700 && defined(BOOTLOADER)
344     /* Copy icode and data to ram */
345     ldr     r2, =_datastart
346     ldr     r3, =_dataend
347     ldr     r4, =_datacopy
349     cmp     r3, r2
350     ldrhi   r1, [r4], #4
351     strhi   r1, [r2], #4
352     bhi     1b
353 #endif
355 #ifndef BOOTLOADER
356     /* Copy icode and data to ram */
357     ldr     r2, =_iramstart
358     ldr     r3, =_iramend
359     ldr     r4, =_iramcopy
361     cmp     r3, r2
362     ldrhi   r1, [r4], #4
363     strhi   r1, [r2], #4
364     bhi     1b
365         
366     /* Initialise ibss section to zero */
367     ldr     r2, =_iedata
368     ldr     r3, =_iend
369     mov     r4, #0
371     cmp     r3, r2
372     strhi   r4, [r2], #4
373     bhi     1b
374 #endif
376     /* Set up some stack and munge it with 0xdeadbeef */
377     ldr     sp, =stackend
378     ldr     r2, =stackbegin
379     ldr     r3, =0xdeadbeef
381     cmp     sp, r2
382     strhi   r3, [r2], #4
383     bhi     1b
385     /* Set up stack for IRQ mode */ 
386     msr     cpsr_c, #0xd2
387     ldr     sp, =_irqstackend
389     /* Set up stack for FIQ mode */ 
390     msr     cpsr_c, #0xd1
391     ldr     sp, =_fiqstackend
393     /* Let abort and undefined modes use IRQ stack */
394     msr     cpsr_c, #0xd7
395     ldr     sp, =_irqstackend
396     msr     cpsr_c, #0xdb
397     ldr     sp, =_irqstackend
399     /* Switch back to supervisor mode */
400     msr     cpsr_c, #0xd3
402 // if we did not switch remap on, device
403 // would crash when MENU is pressed,
404 // as that button is connected to BOOT_MODE pin
405 #if CONFIG_CPU==S5L8700
406     ldr r1, =0x38200000
407     ldr r0, [r1]
408     mvn r2, #0x10000
409     and r0, r0, r2
410     mov r2, #0x1
411     orr r0, r0, r2
412     str r0, [r1] // remap iram to address 0x0
413 #endif
415     bl      main
417     .text
418 /*    .global UIE*/
420 /* All illegal exceptions call into UIE with exception address as first
421  * parameter. This is calculated differently depending on which exception
422  * we're in. Second parameter is exception number, used for a string lookup
423  * in UIE. */
424 undef_instr_handler:
425     mov    r0, lr
426     mov    r1, #0
427     b      UIE
429 /* We run supervisor mode most of the time, and should never see a software
430  * exception being thrown. Perhaps make it illegal and call UIE? */
431 software_int_handler:
432 reserved_handler:
433     movs   pc, lr
435 prefetch_abort_handler:
436     sub    r0, lr, #4
437     mov    r1, #1
438     b      UIE
440 data_abort_handler:
441     sub    r0, lr, #8 
442     mov    r1, #2
443     b      UIE