]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/ixp/start.S
doc: SPI: Add qspi test details on AM43xx
[karo-tx-uboot.git] / arch / arm / cpu / ixp / start.S
1 /* vi: set ts=8 sw=8 noet: */
2 /*
3  *  u-boot - Startup Code for XScale IXP
4  *
5  * Copyright (C) 2003   Kyle Harris <kharris@nexus-tech.net>
6  *
7  * Based on startup code example contained in the
8  * Intel IXP4xx Programmer's Guide and past u-boot Start.S
9  * samples.
10  *
11  * SPDX-License-Identifier:     GPL-2.0+
12  */
13
14 #include <asm-offsets.h>
15 #include <config.h>
16 #include <version.h>
17 #include <asm/arch/ixp425.h>
18
19 #define MMU_Control_M  0x001    /* Enable MMU */
20 #define MMU_Control_A  0x002    /* Enable address alignment faults */
21 #define MMU_Control_C  0x004    /* Enable cache */
22 #define MMU_Control_W  0x008    /* Enable write-buffer */
23 #define MMU_Control_P  0x010    /* Compatability: 32 bit code */
24 #define MMU_Control_D  0x020    /* Compatability: 32 bit data */
25 #define MMU_Control_L  0x040    /* Compatability: */
26 #define MMU_Control_B  0x080    /* Enable Big-Endian */
27 #define MMU_Control_S  0x100    /* Enable system protection */
28 #define MMU_Control_R  0x200    /* Enable ROM protection */
29 #define MMU_Control_I  0x1000   /* Enable Instruction cache */
30 #define MMU_Control_X  0x2000   /* Set interrupt vectors at 0xFFFF0000 */
31 #define MMU_Control_Init (MMU_Control_P|MMU_Control_D|MMU_Control_L)
32
33
34 /*
35  * Macro definitions
36  */
37         /* Delay a bit */
38         .macro DELAY_FOR cycles, reg0
39         ldr     \reg0, =\cycles
40         subs    \reg0, \reg0, #1
41         subne   pc,  pc, #0xc
42         .endm
43
44         /* wait for coprocessor write complete */
45         .macro CPWAIT reg
46         mrc  p15,0,\reg,c2,c0,0
47         mov  \reg,\reg
48         sub  pc,pc,#4
49         .endm
50
51 .globl _start
52 _start:
53         ldr     pc, _reset
54         ldr     pc, _undefined_instruction
55         ldr     pc, _software_interrupt
56         ldr     pc, _prefetch_abort
57         ldr     pc, _data_abort
58         ldr     pc, _not_used
59         ldr     pc, _irq
60         ldr     pc, _fiq
61
62 _reset:                 .word reset
63 _undefined_instruction: .word undefined_instruction
64 _software_interrupt:    .word software_interrupt
65 _prefetch_abort:        .word prefetch_abort
66 _data_abort:            .word data_abort
67 _not_used:              .word not_used
68 _irq:                   .word irq
69 _fiq:                   .word fiq
70
71         .balignl 16,0xdeadbeef
72
73
74 /*
75  * Startup Code (reset vector)
76  *
77  * do important init only if we don't start from memory!
78  * - relocate armboot to ram
79  * - setup stack
80  * - jump to second stage
81  */
82
83 .globl _TEXT_BASE
84 _TEXT_BASE:
85 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
86         .word   CONFIG_SPL_TEXT_BASE
87 #else
88         .word   CONFIG_SYS_TEXT_BASE
89 #endif
90
91 /*
92  * These are defined in the board-specific linker script.
93  * Subtracting _start from them lets the linker put their
94  * relative position in the executable instead of leaving
95  * them null.
96  */
97 .globl _bss_start_ofs
98 _bss_start_ofs:
99         .word __bss_start - _start
100
101 .globl _bss_end_ofs
102 _bss_end_ofs:
103         .word __bss_end - _start
104
105 .globl _end_ofs
106 _end_ofs:
107         .word _end - _start
108
109 #ifdef CONFIG_USE_IRQ
110 /* IRQ stack memory (calculated at run-time) */
111 .globl IRQ_STACK_START
112 IRQ_STACK_START:
113         .word   0x0badc0de
114
115 /* IRQ stack memory (calculated at run-time) */
116 .globl FIQ_STACK_START
117 FIQ_STACK_START:
118         .word 0x0badc0de
119 #endif
120
121 /* IRQ stack memory (calculated at run-time) + 8 bytes */
122 .globl IRQ_STACK_START_IN
123 IRQ_STACK_START_IN:
124         .word   0x0badc0de
125
126 /*
127  * the actual reset code
128  */
129
130 reset:
131         /* disable mmu, set big-endian */
132         mov     r0, #0xf8
133         mcr     p15, 0, r0, c1, c0, 0
134         CPWAIT  r0
135
136         /* invalidate I & D caches & BTB */
137         mcr     p15, 0, r0, c7, c7, 0
138         CPWAIT  r0
139
140         /* invalidate I & Data TLB */
141         mcr     p15, 0, r0, c8, c7, 0
142         CPWAIT r0
143
144         /* drain write and fill buffers */
145         mcr     p15, 0, r0, c7, c10, 4
146         CPWAIT  r0
147
148         /* disable write buffer coalescing */
149         mrc     p15, 0, r0, c1, c0, 1
150         orr     r0, r0, #1
151         mcr     p15, 0, r0, c1, c0, 1
152         CPWAIT  r0
153
154         /* set EXP CS0 to the optimum timing */
155         ldr     r1, =CONFIG_SYS_EXP_CS0
156         ldr     r2, =IXP425_EXP_CS0
157         str     r1, [r2]
158
159         /* make sure flash is visible at 0 */
160         mov     r1, #CONFIG_SYS_SDR_CONFIG
161         ldr     r2, =IXP425_SDR_CONFIG
162         str     r1, [r2]
163
164         /* disable refresh cycles */
165         mov     r1, #0
166         ldr     r3, =IXP425_SDR_REFRESH
167         str     r1, [r3]
168
169         /* send nop command */
170         mov     r1, #3
171         ldr     r4, =IXP425_SDR_IR
172         str     r1, [r4]
173         DELAY_FOR 0x4000, r0
174
175         /* set SDRAM internal refresh val */
176         ldr     r1, =CONFIG_SYS_SDRAM_REFRESH_CNT
177         str     r1, [r3]
178         DELAY_FOR 0x4000, r0
179
180         /* send precharge-all command to close all open banks */
181         mov     r1, #2
182         str     r1, [r4]
183         DELAY_FOR 0x4000, r0
184
185         /* provide 8 auto-refresh cycles */
186         mov     r1, #4
187         mov     r5, #8
188 111:    str     r1, [r4]
189         DELAY_FOR 0x100, r0
190         subs    r5, r5, #1
191         bne     111b
192
193         /* set mode register in sdram */
194         mov     r1, #CONFIG_SYS_SDR_MODE_CONFIG
195         str     r1, [r4]
196         DELAY_FOR 0x4000, r0
197
198         /* send normal operation command */
199         mov     r1, #6
200         str     r1, [r4]
201         DELAY_FOR 0x4000, r0
202
203         /* invalidate I & D caches & BTB */
204         mcr     p15, 0, r0, c7, c7, 0
205         CPWAIT  r0
206
207         /* invalidate I & Data TLB */
208         mcr     p15, 0, r0, c8, c7, 0
209         CPWAIT r0
210
211         /* drain write and fill buffers */
212         mcr     p15, 0, r0, c7, c10, 4
213         CPWAIT  r0
214
215         /* remove flash mirror at 0x00000000 */
216         ldr     r2, =IXP425_EXP_CFG0
217         ldr     r1, [r2]
218         bic     r1, r1, #0x80000000
219         str     r1, [r2]
220
221         /* invalidate I & Data TLB */
222         mcr     p15, 0, r0, c8, c7, 0
223         CPWAIT r0
224
225         /* enable I cache */
226         mrc     p15, 0, r0, c1, c0, 0
227         orr     r0, r0, #MMU_Control_I
228         mcr     p15, 0, r0, c1, c0, 0
229         CPWAIT  r0
230
231         mrs     r0,cpsr                 /* set the cpu to SVC32 mode        */
232         bic     r0,r0,#0x1f             /* (superviser mode, M=10011)       */
233         orr     r0,r0,#0x13
234         msr     cpsr,r0
235
236         bl      _main
237
238 /*------------------------------------------------------------------------------*/
239
240         .globl  c_runtime_cpu_setup
241 c_runtime_cpu_setup:
242
243         bx      lr
244
245 /****************************************************************************/
246 /*                                                                          */
247 /* Interrupt handling                                                       */
248 /*                                                                          */
249 /****************************************************************************/
250
251 /* IRQ stack frame                                                          */
252
253 #define S_FRAME_SIZE    72
254
255 #define S_OLD_R0        68
256 #define S_PSR           64
257 #define S_PC            60
258 #define S_LR            56
259 #define S_SP            52
260
261 #define S_IP            48
262 #define S_FP            44
263 #define S_R10           40
264 #define S_R9            36
265 #define S_R8            32
266 #define S_R7            28
267 #define S_R6            24
268 #define S_R5            20
269 #define S_R4            16
270 #define S_R3            12
271 #define S_R2            8
272 #define S_R1            4
273 #define S_R0            0
274
275 #define MODE_SVC 0x13
276
277         /* use bad_save_user_regs for abort/prefetch/undef/swi ...          */
278
279         .macro  bad_save_user_regs
280         sub     sp, sp, #S_FRAME_SIZE
281         stmia   sp, {r0 - r12}                  /* Calling r0-r12           */
282         add     r8, sp, #S_PC
283
284         ldr     r2, IRQ_STACK_START_IN
285         ldmia   r2, {r2 - r4}                   /* get pc, cpsr, old_r0     */
286         add     r0, sp, #S_FRAME_SIZE           /* restore sp_SVC           */
287
288         add     r5, sp, #S_SP
289         mov     r1, lr
290         stmia   r5, {r0 - r4}                   /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
291         mov     r0, sp
292         .endm
293
294
295         /* use irq_save_user_regs / irq_restore_user_regs for                */
296         /* IRQ/FIQ handling                                                  */
297
298         .macro  irq_save_user_regs
299         sub     sp, sp, #S_FRAME_SIZE
300         stmia   sp, {r0 - r12}                  /* Calling r0-r12            */
301         add     r8, sp, #S_PC
302         stmdb   r8, {sp, lr}^                   /* Calling SP, LR            */
303         str     lr, [r8, #0]                    /* Save calling PC           */
304         mrs     r6, spsr
305         str     r6, [r8, #4]                    /* Save CPSR                 */
306         str     r0, [r8, #8]                    /* Save OLD_R0               */
307         mov     r0, sp
308         .endm
309
310         .macro  irq_restore_user_regs
311         ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
312         mov     r0, r0
313         ldr     lr, [sp, #S_PC]                 @ Get PC
314         add     sp, sp, #S_FRAME_SIZE
315         subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
316         .endm
317
318         .macro get_bad_stack
319         ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
320
321         str     lr, [r13]                       @ save caller lr / spsr
322         mrs     lr, spsr
323         str     lr, [r13, #4]
324
325         mov     r13, #MODE_SVC                  @ prepare SVC-Mode
326         msr     spsr_c, r13
327         mov     lr, pc
328         movs    pc, lr
329         .endm
330
331         .macro get_irq_stack                    @ setup IRQ stack
332         ldr     sp, IRQ_STACK_START
333         .endm
334
335         .macro get_fiq_stack                    @ setup FIQ stack
336         ldr     sp, FIQ_STACK_START
337         .endm
338
339
340 /****************************************************************************/
341 /*                                                                          */
342 /* exception handlers                                                       */
343 /*                                                                          */
344 /****************************************************************************/
345
346         .align  5
347 undefined_instruction:
348         get_bad_stack
349         bad_save_user_regs
350         bl      do_undefined_instruction
351
352         .align  5
353 software_interrupt:
354         get_bad_stack
355         bad_save_user_regs
356         bl      do_software_interrupt
357
358         .align  5
359 prefetch_abort:
360         get_bad_stack
361         bad_save_user_regs
362         bl      do_prefetch_abort
363
364         .align  5
365 data_abort:
366         get_bad_stack
367         bad_save_user_regs
368         bl      do_data_abort
369
370         .align  5
371 not_used:
372         get_bad_stack
373         bad_save_user_regs
374         bl      do_not_used
375
376 #ifdef CONFIG_USE_IRQ
377
378         .align  5
379 irq:
380         get_irq_stack
381         irq_save_user_regs
382         bl      do_irq
383         irq_restore_user_regs
384
385         .align  5
386 fiq:
387         get_fiq_stack
388         irq_save_user_regs              /* someone ought to write a more    */
389         bl      do_fiq                  /* effiction fiq_save_user_regs     */
390         irq_restore_user_regs
391
392 #else
393
394         .align  5
395 irq:
396         get_bad_stack
397         bad_save_user_regs
398         bl      do_irq
399
400         .align  5
401 fiq:
402         get_bad_stack
403         bad_save_user_regs
404         bl      do_fiq
405
406 #endif
407
408 /****************************************************************************/
409 /*                                                                          */
410 /* Reset function: Use Watchdog to reset                                    */
411 /*                                                                          */
412 /****************************************************************************/
413
414         .align  5
415 .globl reset_cpu
416
417 reset_cpu:
418         ldr     r1, =0x482e
419         ldr     r2, =IXP425_OSWK
420         str     r1, [r2]
421         ldr     r1, =0x0fff
422         ldr     r2, =IXP425_OSWT
423         str     r1, [r2]
424         ldr     r1, =0x5
425         ldr     r2, =IXP425_OSWE
426         str     r1, [r2]
427         b       reset_endless
428
429 reset_endless:
430         b       reset_endless