]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-uniphier/lowlevel_init.S
Merge branch 'master' of git://git.denx.de/u-boot-fdt
[u-boot] / arch / arm / mach-uniphier / lowlevel_init.S
1 /*
2  * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <config.h>
8 #include <linux/linkage.h>
9 #include <linux/sizes.h>
10 #include <asm/system.h>
11 #include <mach/arm-mpcore.h>
12 #include <mach/sbc-regs.h>
13 #include <mach/ssc-regs.h>
14
15 ENTRY(lowlevel_init)
16         mov     r8, lr                  @ persevere link reg across call
17
18         /*
19          * The UniPhier Boot ROM loads SPL code to the L2 cache.
20          * But CPUs can only do instruction fetch now because start.S has
21          * cleared C and M bits.
22          * First we need to turn on MMU and Dcache again to get back
23          * data access to L2.
24          */
25         mrc     p15, 0, r0, c1, c0, 0   @ SCTLR (System Control Register)
26         orr     r0, r0, #(CR_C | CR_M)  @ enable MMU and Dcache
27         mcr     p15, 0, r0, c1, c0, 0
28
29 #ifdef CONFIG_DEBUG_LL
30         bl      debug_ll_init
31 #endif
32
33         /*
34          * Now we are using the page table embedded in the Boot ROM.
35          * It is not handy since it is not a straight mapped table for sLD3.
36          * What we need to do next is to switch over to the page table in SPL.
37          */
38         ldr     r3, =init_page_table    @ page table must be 16KB aligned
39
40         /* Disable MMU and Dcache before switching Page Table */
41         mrc     p15, 0, r0, c1, c0, 0   @ SCTLR (System Control Register)
42         bic     r0, r0, #(CR_C | CR_M)  @ disable MMU and Dcache
43         mcr     p15, 0, r0, c1, c0, 0
44
45         bl      enable_mmu
46
47 #ifdef CONFIG_UNIPHIER_SMP
48 secondary_startup:
49         /*
50          * Entry point for secondary CPUs
51          *
52          * The Boot ROM has already enabled MMU for the secondary CPUs as well
53          * as for the primary one.  The MMU table embedded in the Boot ROM
54          * prohibits the DRAM access, so it is impossible to bring the
55          * secondary CPUs into DRAM directly.  They must jump here into SPL,
56          * which is run on L2 cache.
57          *
58          * Boot Sequence
59          *  [primary CPU]                    [secondary CPUs]
60          *  start from Boot ROM             start from Boot ROM
61          *     jump to SPL                    sleep in Boot ROM
62          *  kick secondaries   ---(sev)--->    jump to SPL
63          *  jump to U-Boot main               sleep in SPL
64          *  jump to Linux
65          *  kick secondaries   ---(sev)--->    jump to Linux
66          */
67
68         /* branch by CPU ID */
69         mrc     p15, 0, r0, c0, c0, 5   @ MPIDR (Multiprocessor Affinity Register)
70         and     r0, r0, #0x3
71         cmp     r0, #0x0
72         beq     primary_cpu
73         /* only for secondary CPUs */
74         ldr     r1, =ROM_BOOT_ROMRSV2   @ The last data access to L2 cache
75         mrc     p15, 0, r0, c1, c0, 0   @ SCTLR (System Control Register)
76         orr     r0, r0, #CR_I           @ Enable ICache
77         bic     r0, r0, #(CR_C | CR_M)  @ MMU and Dcache must be disabled
78         mcr     p15, 0, r0, c1, c0, 0   @ before jumping to Linux
79         mov     r0, #0
80         str     r0, [r1]
81         b       1f
82         /*
83          * L2 cache is shared among all the CPUs and it might be disabled by
84          * the primary one.  Before that, the following 5 lines must be cached
85          * on the Icaches of the secondary CPUs.
86          */
87 0:      wfe                             @ kicked by Linux
88 1:      ldr     r0, [r1]
89         cmp     r0, #0
90         bxne    r0                      @ r0: Linux entry for secondary CPUs
91         b       0b
92 primary_cpu:
93         ldr     r1, =ROM_BOOT_ROMRSV2
94         ldr     r0, =secondary_startup
95         str     r0, [r1]
96         ldr     r0, [r1]                @ make sure str is complete before sev
97         sev                             @ kick the secondary CPU
98 #endif
99
100         bl      setup_init_ram          @ RAM area for temporary stack pointer
101
102         mov     lr, r8                  @ restore link
103         mov     pc, lr                  @ back to my caller
104 ENDPROC(lowlevel_init)
105
106 ENTRY(enable_mmu)
107         mrc     p15, 0, r0, c2, c0, 2   @ TTBCR (Translation Table Base Control Register)
108         bic     r0, r0, #0x37
109         orr     r0, r0, #0x20           @ disable TTBR1
110         mcr     p15, 0, r0, c2, c0, 2
111
112         orr     r0, r3, #0x8            @ Outer Cacheability for table walks: WBWA
113         mcr     p15, 0, r0, c2, c0, 0   @ TTBR0
114
115         mov     r0, #0
116         mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
117
118         mov     r0, #-1                 @ manager for all domains (No permission check)
119         mcr     p15, 0, r0, c3, c0, 0   @ DACR (Domain Access Control Register)
120
121         dsb
122         isb
123         /*
124          * MMU on:
125          * TLBs was already invalidated in "../start.S"
126          * So, we don't need to invalidate it here.
127          */
128         mrc     p15, 0, r0, c1, c0, 0   @ SCTLR (System Control Register)
129         orr     r0, r0, #(CR_C | CR_M)  @ MMU and Dcache enable
130         mcr     p15, 0, r0, c1, c0, 0
131
132         mov     pc, lr
133 ENDPROC(enable_mmu)
134
135 /*
136  * For PH1-Pro4 or older SoCs, the size of WAY is 32KB.
137  * It is large enough for tmp RAM.
138  */
139 #define BOOT_RAM_SIZE    (SZ_32K)
140 #define BOOT_WAY_BITS    (0x00000100)   /* way 8 */
141
142 ENTRY(setup_init_ram)
143         /*
144          * Touch to zero for the boot way
145          */
146 0:
147         /*
148          * set SSCOQM, SSCOQAD, SSCOQSZ, SSCOQWN in this order
149          */
150         ldr     r0, = 0x00408006        @ touch to zero with address range
151         ldr     r1, = SSCOQM
152         str     r0, [r1]
153         ldr     r0, = (CONFIG_SPL_STACK - BOOT_RAM_SIZE)        @ base address
154         ldr     r1, = SSCOQAD
155         str     r0, [r1]
156         ldr     r0, = BOOT_RAM_SIZE
157         ldr     r1, = SSCOQSZ
158         str     r0, [r1]
159         ldr     r0, = BOOT_WAY_BITS
160         ldr     r1, = SSCOQWN
161         str     r0, [r1]
162         ldr     r1, = SSCOPPQSEF
163         ldr     r0, [r1]
164         cmp     r0, #0                  @ check if the command is successfully set
165         bne     0b                      @ try again if an error occurs
166
167         ldr     r1, = SSCOLPQS
168 1:
169         ldr     r0, [r1]
170         cmp     r0, #0x4
171         bne     1b                      @ wait until the operation is completed
172         str     r0, [r1]                @ clear the complete notification flag
173
174         mov     pc, lr
175 ENDPROC(setup_init_ram)