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