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