]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
net/fm: fix MDIO controller base on FMAN2
[people/ms/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / lowlevel.S
1 /*
2 * (C) Copyright 2014-2015 Freescale Semiconductor
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 *
6 * Extracted from armv8/start.S
7 */
8
9 #include <config.h>
10 #include <linux/linkage.h>
11 #include <asm/gic.h>
12 #include <asm/macro.h>
13 #ifdef CONFIG_MP
14 #include <asm/arch/mp.h>
15 #endif
16
17 ENTRY(lowlevel_init)
18 mov x29, lr /* Save LR */
19
20 #ifdef CONFIG_FSL_LSCH3
21 /* Add fully-coherent masters to DVM domain */
22 ldr x0, =CCI_MN_BASE
23 ldr x1, =CCI_MN_RNF_NODEID_LIST
24 ldr x2, =CCI_MN_DVM_DOMAIN_CTL_SET
25 bl ccn504_add_masters_to_dvm
26
27 /* Set all RN-I ports to QoS of 15 */
28 ldr x0, =CCI_S0_QOS_CONTROL_BASE(0)
29 ldr x1, =0x00FF000C
30 bl ccn504_set_qos
31 ldr x0, =CCI_S1_QOS_CONTROL_BASE(0)
32 ldr x1, =0x00FF000C
33 bl ccn504_set_qos
34 ldr x0, =CCI_S2_QOS_CONTROL_BASE(0)
35 ldr x1, =0x00FF000C
36 bl ccn504_set_qos
37
38 ldr x0, =CCI_S0_QOS_CONTROL_BASE(2)
39 ldr x1, =0x00FF000C
40 bl ccn504_set_qos
41 ldr x0, =CCI_S1_QOS_CONTROL_BASE(2)
42 ldr x1, =0x00FF000C
43 bl ccn504_set_qos
44 ldr x0, =CCI_S2_QOS_CONTROL_BASE(2)
45 ldr x1, =0x00FF000C
46 bl ccn504_set_qos
47
48 ldr x0, =CCI_S0_QOS_CONTROL_BASE(6)
49 ldr x1, =0x00FF000C
50 bl ccn504_set_qos
51 ldr x0, =CCI_S1_QOS_CONTROL_BASE(6)
52 ldr x1, =0x00FF000C
53 bl ccn504_set_qos
54 ldr x0, =CCI_S2_QOS_CONTROL_BASE(6)
55 ldr x1, =0x00FF000C
56 bl ccn504_set_qos
57
58 ldr x0, =CCI_S0_QOS_CONTROL_BASE(12)
59 ldr x1, =0x00FF000C
60 bl ccn504_set_qos
61 ldr x0, =CCI_S1_QOS_CONTROL_BASE(12)
62 ldr x1, =0x00FF000C
63 bl ccn504_set_qos
64 ldr x0, =CCI_S2_QOS_CONTROL_BASE(12)
65 ldr x1, =0x00FF000C
66 bl ccn504_set_qos
67
68 ldr x0, =CCI_S0_QOS_CONTROL_BASE(16)
69 ldr x1, =0x00FF000C
70 bl ccn504_set_qos
71 ldr x0, =CCI_S1_QOS_CONTROL_BASE(16)
72 ldr x1, =0x00FF000C
73 bl ccn504_set_qos
74 ldr x0, =CCI_S2_QOS_CONTROL_BASE(16)
75 ldr x1, =0x00FF000C
76 bl ccn504_set_qos
77
78 ldr x0, =CCI_S0_QOS_CONTROL_BASE(20)
79 ldr x1, =0x00FF000C
80 bl ccn504_set_qos
81 ldr x0, =CCI_S1_QOS_CONTROL_BASE(20)
82 ldr x1, =0x00FF000C
83 bl ccn504_set_qos
84 ldr x0, =CCI_S2_QOS_CONTROL_BASE(20)
85 ldr x1, =0x00FF000C
86 bl ccn504_set_qos
87 #endif
88
89 /* Set the SMMU page size in the sACR register */
90 ldr x1, =SMMU_BASE
91 ldr w0, [x1, #0x10]
92 orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */
93 str w0, [x1, #0x10]
94
95 /* Initialize GIC Secure Bank Status */
96 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
97 branch_if_slave x0, 1f
98 ldr x0, =GICD_BASE
99 bl gic_init_secure
100 1:
101 #ifdef CONFIG_GICV3
102 ldr x0, =GICR_BASE
103 bl gic_init_secure_percpu
104 #elif defined(CONFIG_GICV2)
105 ldr x0, =GICD_BASE
106 ldr x1, =GICC_BASE
107 bl gic_init_secure_percpu
108 #endif
109 #endif
110
111 branch_if_master x0, x1, 2f
112
113 #if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
114 ldr x0, =secondary_boot_func
115 blr x0
116 #endif
117
118 2:
119 #ifdef CONFIG_FSL_TZPC_BP147
120 /* Set Non Secure access for all devices protected via TZPC */
121 ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
122 orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
123 str w0, [x1]
124
125 isb
126 dsb sy
127 #endif
128
129 #ifdef CONFIG_FSL_TZASC_400
130 /* Set TZASC so that:
131 * a. We use only Region0 whose global secure write/read is EN
132 * b. We use only Region0 whose NSAID write/read is EN
133 *
134 * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
135 * placeholders.
136 */
137 ldr x1, =TZASC_GATE_KEEPER(0)
138 ldr x0, [x1] /* Filter 0 Gate Keeper Register */
139 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
140 str x0, [x1]
141
142 ldr x1, =TZASC_GATE_KEEPER(1)
143 ldr x0, [x1] /* Filter 0 Gate Keeper Register */
144 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
145 str x0, [x1]
146
147 ldr x1, =TZASC_REGION_ATTRIBUTES_0(0)
148 ldr x0, [x1] /* Region-0 Attributes Register */
149 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
150 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
151 str x0, [x1]
152
153 ldr x1, =TZASC_REGION_ATTRIBUTES_0(1)
154 ldr x0, [x1] /* Region-1 Attributes Register */
155 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
156 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
157 str x0, [x1]
158
159 ldr x1, =TZASC_REGION_ID_ACCESS_0(0)
160 ldr w0, [x1] /* Region-0 Access Register */
161 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
162 str w0, [x1]
163
164 ldr x1, =TZASC_REGION_ID_ACCESS_0(1)
165 ldr w0, [x1] /* Region-1 Attributes Register */
166 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
167 str w0, [x1]
168
169 isb
170 dsb sy
171 #endif
172 mov lr, x29 /* Restore LR */
173 ret
174 ENDPROC(lowlevel_init)
175
176 hnf_pstate_poll:
177 /* x0 has the desired status, return 0 for success, 1 for timeout
178 * clobber x1, x2, x3, x4, x6, x7
179 */
180 mov x1, x0
181 mov x7, #0 /* flag for timeout */
182 mrs x3, cntpct_el0 /* read timer */
183 add x3, x3, #1200 /* timeout after 100 microseconds */
184 mov x0, #0x18
185 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */
186 mov w6, #8 /* HN-F node count */
187 1:
188 ldr x2, [x0]
189 cmp x2, x1 /* check status */
190 b.eq 2f
191 mrs x4, cntpct_el0
192 cmp x4, x3
193 b.ls 1b
194 mov x7, #1 /* timeout */
195 b 3f
196 2:
197 add x0, x0, #0x10000 /* move to next node */
198 subs w6, w6, #1
199 cbnz w6, 1b
200 3:
201 mov x0, x7
202 ret
203
204 hnf_set_pstate:
205 /* x0 has the desired state, clobber x1, x2, x6 */
206 mov x1, x0
207 /* power state to SFONLY */
208 mov w6, #8 /* HN-F node count */
209 mov x0, #0x10
210 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */
211 1: /* set pstate to sfonly */
212 ldr x2, [x0]
213 and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
214 orr x2, x2, x1
215 str x2, [x0]
216 add x0, x0, #0x10000 /* move to next node */
217 subs w6, w6, #1
218 cbnz w6, 1b
219
220 ret
221
222 ENTRY(__asm_flush_l3_cache)
223 /*
224 * Return status in x0
225 * success 0
226 * tmeout 1 for setting SFONLY, 2 for FAM, 3 for both
227 */
228 mov x29, lr
229 mov x8, #0
230
231 dsb sy
232 mov x0, #0x1 /* HNFPSTAT_SFONLY */
233 bl hnf_set_pstate
234
235 mov x0, #0x4 /* SFONLY status */
236 bl hnf_pstate_poll
237 cbz x0, 1f
238 mov x8, #1 /* timeout */
239 1:
240 dsb sy
241 mov x0, #0x3 /* HNFPSTAT_FAM */
242 bl hnf_set_pstate
243
244 mov x0, #0xc /* FAM status */
245 bl hnf_pstate_poll
246 cbz x0, 1f
247 add x8, x8, #0x2
248 1:
249 mov x0, x8
250 mov lr, x29
251 ret
252 ENDPROC(__asm_flush_l3_cache)
253
254 #ifdef CONFIG_MP
255 /* Keep literals not used by the secondary boot code outside it */
256 .ltorg
257
258 /* Using 64 bit alignment since the spin table is accessed as data */
259 .align 4
260 .global secondary_boot_code
261 /* Secondary Boot Code starts here */
262 secondary_boot_code:
263 .global __spin_table
264 __spin_table:
265 .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
266
267 .align 2
268 ENTRY(secondary_boot_func)
269 /*
270 * MPIDR_EL1 Fields:
271 * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
272 * MPIDR[7:2] = AFF0_RES
273 * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
274 * MPIDR[23:16] = AFF2_CLUSTERID
275 * MPIDR[24] = MT
276 * MPIDR[29:25] = RES0
277 * MPIDR[30] = U
278 * MPIDR[31] = ME
279 * MPIDR[39:32] = AFF3
280 *
281 * Linear Processor ID (LPID) calculation from MPIDR_EL1:
282 * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
283 * until AFF2_CLUSTERID and AFF3 have non-zero values)
284 *
285 * LPID = MPIDR[15:8] | MPIDR[1:0]
286 */
287 mrs x0, mpidr_el1
288 ubfm x1, x0, #8, #15
289 ubfm x2, x0, #0, #1
290 orr x10, x2, x1, lsl #2 /* x10 has LPID */
291 ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */
292 /*
293 * offset of the spin table element for this core from start of spin
294 * table (each elem is padded to 64 bytes)
295 */
296 lsl x1, x10, #6
297 ldr x0, =__spin_table
298 /* physical address of this cpus spin table element */
299 add x11, x1, x0
300
301 ldr x0, =__real_cntfrq
302 ldr x0, [x0]
303 msr cntfrq_el0, x0 /* set with real frequency */
304 str x9, [x11, #16] /* LPID */
305 mov x4, #1
306 str x4, [x11, #8] /* STATUS */
307 dsb sy
308 #if defined(CONFIG_GICV3)
309 gic_wait_for_interrupt_m x0
310 #elif defined(CONFIG_GICV2)
311 ldr x0, =GICC_BASE
312 gic_wait_for_interrupt_m x0, w1
313 #endif
314
315 bl secondary_switch_to_el2
316 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
317 bl secondary_switch_to_el1
318 #endif
319
320 slave_cpu:
321 wfe
322 ldr x0, [x11]
323 cbz x0, slave_cpu
324 #ifndef CONFIG_ARMV8_SWITCH_TO_EL1
325 mrs x1, sctlr_el2
326 #else
327 mrs x1, sctlr_el1
328 #endif
329 tbz x1, #25, cpu_is_le
330 rev x0, x0 /* BE to LE conversion */
331 cpu_is_le:
332 br x0 /* branch to the given address */
333 ENDPROC(secondary_boot_func)
334
335 ENTRY(secondary_switch_to_el2)
336 switch_el x0, 1f, 0f, 0f
337 0: ret
338 1: armv8_switch_to_el2_m x0
339 ENDPROC(secondary_switch_to_el2)
340
341 ENTRY(secondary_switch_to_el1)
342 switch_el x0, 0f, 1f, 0f
343 0: ret
344 1: armv8_switch_to_el1_m x0, x1
345 ENDPROC(secondary_switch_to_el1)
346
347 /* Ensure that the literals used by the secondary boot code are
348 * assembled within it (this is required so that we can protect
349 * this area with a single memreserve region
350 */
351 .ltorg
352
353 /* 64 bit alignment for elements accessed as data */
354 .align 4
355 .global __real_cntfrq
356 __real_cntfrq:
357 .quad COUNTER_FREQUENCY
358 .globl __secondary_boot_code_size
359 .type __secondary_boot_code_size, %object
360 /* Secondary Boot Code ends here */
361 __secondary_boot_code_size:
362 .quad .-secondary_boot_code
363 #endif