Fix initramfs loading bug introduced in f407b0626f0160fa8cca67c548c8de38c8353e16
[qi.git] / src / start.S
1 /*
2  * (C) Copyright 2007 OpenMoko, Inc.
3  * 
4  * Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA
20  */
21
22 #define __ASM_MODE__
23 #include <neo_gta02.h>
24
25 .globl _start
26 _start: b       start_code
27 /* if we are injected by JTAG, the script sets _istag content to nonzero */
28 _is_jtag:
29         .word   0
30
31 /* it's at a fixed address (+0x8) so we can breakpoint it in the JTAG script
32  * we need to go through this hassle because before this moment, SDRAM is not
33  * working so we can't prep it from JTAG
34  */
35
36 _steppingstone_done:
37         ldr     pc, _start_armboot
38
39 _start_armboot:
40         .word   start_qi
41
42 _TEXT_BASE:
43         .word   TEXT_BASE
44
45 /*
46  * These are defined in the board-specific linker script.
47  */
48 .globl _bss_start
49 _bss_start:
50         .word __bss_start
51
52 .globl _bss_end
53 _bss_end:
54         .word _end
55
56 start_code:     
57         /*
58          * set the cpu to SVC32 mode
59          */
60         mrs     r0,cpsr
61         bic     r0,r0,#0x1f
62         orr     r0,r0,#0xd3
63         msr     cpsr,r0
64         
65 # define pWTCON         0x53000000
66
67         ldr     r0, =pWTCON
68         mov     r1, #0x0
69         str     r1, [r0]
70
71         /*
72          * mask all IRQs by setting all bits in the INTMR - default
73          */
74 # define INTMSK         0x4A000008      /* Interupt-Controller base addresses */
75 # define INTSUBMSK      0x4A00001C
76 # define INTSUBMSK_val  0x0000ffff
77
78         mov     r1, #0xffffffff
79         ldr     r0, =INTMSK
80         str     r1, [r0]
81
82         ldr     r1, =INTSUBMSK_val
83         ldr     r0, =INTSUBMSK
84         str     r1, [r0]
85
86
87         /* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */
88 # define CAMDIVN        0x4C000018
89
90         ldr     r0, =CAMDIVN
91         mov     r1, #0
92         str     r1, [r0]
93
94         /* Clock asynchronous mode */
95         mrc     p15, 0, r1, c1, c0, 0
96         orr     r1, r1, #0xc0000000
97         mcr     p15, 0, r1, c1, c0, 0
98
99 #define LOCKTIME        0x4c000000
100
101         ldr     r0, =LOCKTIME
102         mov     r1, #0xffffff
103         str     r1, [r0]
104         
105 # define UPLLCON        0x4c000008
106 # define MPLLCON_val    ((142 << 12) + (7 << 4) + 1)
107 # define UPLLCON_val    (( 88 << 12) + (8 << 4) + 2)
108         
109         ldr     r0, =UPLLCON
110         ldr     r1, =UPLLCON_val
111         str     r1, [r0]
112
113         /* Page 7-19, seven nops between UPLL and MPLL */
114         nop
115         nop
116         nop
117         nop
118         nop
119         nop
120         nop
121
122         ldr     r1, =MPLLCON_val
123         str     r1, [r0, #-4]           /* MPLLCON */
124
125 # define CLKDIVN        0x4C000014      /* clock divisor register */
126 # define CLKDIVN_val    7 /* FCLK:HCLK:PCLK = 1:3:6 */
127
128         /* FCLK:HCLK:PCLK = 1:3:6 */
129         ldr     r0, =CLKDIVN
130         mov     r1, #CLKDIVN_val
131         str     r1, [r0]
132
133         /* enable only CPU peripheral block clocks we actually use */
134         ldr     r0, =0x4c00000c         /* clkcon */
135         ldr     r1, =0x3d10             /* uart, pwm, gpio, nand clocks on */
136         str     r1, [r0]
137
138         /* gpio UART2 init, H port */
139         ldr     r0, =0x56000070
140         ldr     r1, =0x001AAAAA
141         str     r1, [r0]
142
143         /* enable KEEPACT(GPJ8) to make sure PMU keeps us alive */
144         ldr     r0, =0x56000000 /* GPJ base */
145         ldr     r1, [r0, #0xd0] /* GPJCON */
146         orr     r1, r1, #(1 << 16)
147         str     r1, [r0, #0xd0]
148
149         ldr     r1, [r0, #0xd4] /* GPJDAT */
150         orr     r1, r1, #(1 << 8)
151         str     r1, [r0, #0xd4]
152
153
154         /* init uart2 */
155         ldr     r0, =0x50008000
156         mov     r1, #0x03
157         str     r1, [r0]
158         ldr     r1, =0x245
159         str     r1, [r0, #0x04]
160         mov     r1, #0x00
161         str     r1, [r0, #0x08]
162         mov     r1, #0x00
163         str     r1, [r0, #0x0c] 
164         mov     r1, #0x11
165         str     r1, [r0, #0x28]
166
167         ldr     r0, =0x50008000
168         ldr     r1, =0x54
169         str     r1, [r0, #0x20]
170
171         bl      cpu_init_crit
172
173 /* reset nand controller, or it is dead to us */
174
175         mov     r1, #0x4E000000
176         ldr     r2, =0xfff0             @ initial value tacls=3,rph0=7,rph1=7
177         ldr     r3, [r1, #0]
178         orr     r3, r3, r2
179         str     r3, [r1, #0]
180
181         ldr     r3, [r1, #4]
182         orr     r3, r3, #1              @ enable nand controller
183         str     r3, [r1, #4]
184
185                                                                 /* >> CFG_VIDEO_LOGO_MAX_SIZE */
186 #define CFG_GBL_DATA_SIZE               128                     /* size in bytes reserved for initial data */
187
188 stack_setup:
189         ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
190         sub     r0, r0, #CFG_GBL_DATA_SIZE      /* bdinfo                        */
191         sub     sp, r0, #12             /* leave 3 words for abort-stack    */
192
193 clear_bss:
194         ldr     r0, _bss_start          /* find start of bss segment        */
195         ldr     r1, _bss_end            /* stop here                        */
196         mov     r2, #0x00000000 /* clear                            */
197
198 clbss_l:
199         str     r2, [r0]                        /* clear loop...                    */
200         add     r0, r0, #4
201         cmp     r0, r1
202         ble     clbss_l
203
204 /* we are going to jump into the C part of the init now */
205 spin:
206         b       _steppingstone_done
207
208 /*
209  *************************************************************************
210  *
211  * CPU_init_critical registers
212  *
213  * setup important registers
214  * setup memory timing
215  *
216  *************************************************************************
217  */
218
219 cpu_init_crit:
220
221         /*
222          * flush v4 I/D caches
223          */
224         mov     r0, #0
225         mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
226         mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
227
228         /*
229          * disable MMU stuff and caches
230          */
231         mrc     p15, 0, r0, c1, c0, 0
232         bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
233         bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
234         orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
235         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
236         mcr     p15, 0, r0, c1, c0, 0
237
238         /*
239          * before relocating, we have to setup RAM timing
240          * because memory timing is board-dependend, you will
241          * find a lowlevel_init.S in your board directory.
242          */
243         mov     ip, lr
244  
245         bl      lowlevel_init
246
247         mov     lr, ip
248         mov     pc, lr
249