armv8: layerscape: Avoid code duplication for TZASC Instantiation
[oweals/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / lowlevel.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * (C) Copyright 2014-2015 Freescale Semiconductor
4  *
5  * Extracted from armv8/start.S
6  */
7
8 #include <config.h>
9 #include <linux/linkage.h>
10 #include <asm/gic.h>
11 #include <asm/macro.h>
12 #include <asm/arch-fsl-layerscape/soc.h>
13 #ifdef CONFIG_MP
14 #include <asm/arch/mp.h>
15 #endif
16 #ifdef CONFIG_FSL_LSCH3
17 #include <asm/arch-fsl-layerscape/immap_lsch3.h>
18 #endif
19 #include <asm/u-boot.h>
20
21 /* Get GIC offset
22 * For LS1043a rev1.0, GIC base address align with 4k.
23 * For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
24 * is set, GIC base address align with 4K, or else align
25 * with 64k.
26 * output:
27 *       x0: the base address of GICD
28 *       x1: the base address of GICC
29 */
30 ENTRY(get_gic_offset)
31         ldr     x0, =GICD_BASE
32 #ifdef CONFIG_GICV2
33         ldr     x1, =GICC_BASE
34 #endif
35 #ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
36         ldr     x2, =DCFG_CCSR_SVR
37         ldr     w2, [x2]
38         rev     w2, w2
39         lsr     w3, w2, #16
40         ldr     w4, =SVR_DEV(SVR_LS1043A)
41         cmp     w3, w4
42         b.ne    1f
43         ands    w2, w2, #0xff
44         cmp     w2, #REV1_0
45         b.eq    1f
46         ldr     x2, =SCFG_GIC400_ALIGN
47         ldr     w2, [x2]
48         rev     w2, w2
49         tbnz    w2, #GIC_ADDR_BIT, 1f
50         ldr     x0, =GICD_BASE_64K
51 #ifdef CONFIG_GICV2
52         ldr     x1, =GICC_BASE_64K
53 #endif
54 1:
55 #endif
56         ret
57 ENDPROC(get_gic_offset)
58
59 ENTRY(smp_kick_all_cpus)
60         /* Kick secondary cpus up by SGI 0 interrupt */
61 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
62         mov     x29, lr                 /* Save LR */
63         bl      get_gic_offset
64         bl      gic_kick_secondary_cpus
65         mov     lr, x29                 /* Restore LR */
66 #endif
67         ret
68 ENDPROC(smp_kick_all_cpus)
69
70
71 ENTRY(lowlevel_init)
72         mov     x29, lr                 /* Save LR */
73
74         switch_el x1, 1f, 100f, 100f    /* skip if not in EL3 */
75 1:
76
77 #if defined (CONFIG_SYS_FSL_HAS_CCN504)
78
79         /* Set Wuo bit for RN-I 20 */
80 #ifdef CONFIG_ARCH_LS2080A
81         ldr     x0, =CCI_AUX_CONTROL_BASE(20)
82         ldr     x1, =0x00000010
83         bl      ccn504_set_aux
84
85         /*
86          * Set forced-order mode in RNI-6, RNI-20
87          * This is required for performance optimization on LS2088A
88          * LS2080A family does not support setting forced-order mode,
89          * so skip this operation for LS2080A family
90          */
91         bl      get_svr
92         lsr     w0, w0, #16
93         ldr     w1, =SVR_DEV(SVR_LS2080A)
94         cmp     w0, w1
95         b.eq    1f
96
97         ldr     x0, =CCI_AUX_CONTROL_BASE(6)
98         ldr     x1, =0x00000020
99         bl      ccn504_set_aux
100         ldr     x0, =CCI_AUX_CONTROL_BASE(20)
101         ldr     x1, =0x00000020
102         bl      ccn504_set_aux
103 1:
104 #endif
105
106         /* Add fully-coherent masters to DVM domain */
107         ldr     x0, =CCI_MN_BASE
108         ldr     x1, =CCI_MN_RNF_NODEID_LIST
109         ldr     x2, =CCI_MN_DVM_DOMAIN_CTL_SET
110         bl      ccn504_add_masters_to_dvm
111
112         /* Set all RN-I ports to QoS of 15 */
113         ldr     x0, =CCI_S0_QOS_CONTROL_BASE(0)
114         ldr     x1, =0x00FF000C
115         bl      ccn504_set_qos
116         ldr     x0, =CCI_S1_QOS_CONTROL_BASE(0)
117         ldr     x1, =0x00FF000C
118         bl      ccn504_set_qos
119         ldr     x0, =CCI_S2_QOS_CONTROL_BASE(0)
120         ldr     x1, =0x00FF000C
121         bl      ccn504_set_qos
122
123         ldr     x0, =CCI_S0_QOS_CONTROL_BASE(2)
124         ldr     x1, =0x00FF000C
125         bl      ccn504_set_qos
126         ldr     x0, =CCI_S1_QOS_CONTROL_BASE(2)
127         ldr     x1, =0x00FF000C
128         bl      ccn504_set_qos
129         ldr     x0, =CCI_S2_QOS_CONTROL_BASE(2)
130         ldr     x1, =0x00FF000C
131         bl      ccn504_set_qos
132
133         ldr     x0, =CCI_S0_QOS_CONTROL_BASE(6)
134         ldr     x1, =0x00FF000C
135         bl      ccn504_set_qos
136         ldr     x0, =CCI_S1_QOS_CONTROL_BASE(6)
137         ldr     x1, =0x00FF000C
138         bl      ccn504_set_qos
139         ldr     x0, =CCI_S2_QOS_CONTROL_BASE(6)
140         ldr     x1, =0x00FF000C
141         bl      ccn504_set_qos
142
143         ldr     x0, =CCI_S0_QOS_CONTROL_BASE(12)
144         ldr     x1, =0x00FF000C
145         bl      ccn504_set_qos
146         ldr     x0, =CCI_S1_QOS_CONTROL_BASE(12)
147         ldr     x1, =0x00FF000C
148         bl      ccn504_set_qos
149         ldr     x0, =CCI_S2_QOS_CONTROL_BASE(12)
150         ldr     x1, =0x00FF000C
151         bl      ccn504_set_qos
152
153         ldr     x0, =CCI_S0_QOS_CONTROL_BASE(16)
154         ldr     x1, =0x00FF000C
155         bl      ccn504_set_qos
156         ldr     x0, =CCI_S1_QOS_CONTROL_BASE(16)
157         ldr     x1, =0x00FF000C
158         bl      ccn504_set_qos
159         ldr     x0, =CCI_S2_QOS_CONTROL_BASE(16)
160         ldr     x1, =0x00FF000C
161         bl      ccn504_set_qos
162
163         ldr     x0, =CCI_S0_QOS_CONTROL_BASE(20)
164         ldr     x1, =0x00FF000C
165         bl      ccn504_set_qos
166         ldr     x0, =CCI_S1_QOS_CONTROL_BASE(20)
167         ldr     x1, =0x00FF000C
168         bl      ccn504_set_qos
169         ldr     x0, =CCI_S2_QOS_CONTROL_BASE(20)
170         ldr     x1, =0x00FF000C
171         bl      ccn504_set_qos
172 #endif /* CONFIG_SYS_FSL_HAS_CCN504 */
173
174 #ifdef SMMU_BASE
175         /* Set the SMMU page size in the sACR register */
176         ldr     x1, =SMMU_BASE
177         ldr     w0, [x1, #0x10]
178         orr     w0, w0, #1 << 16  /* set sACR.pagesize to indicate 64K page */
179         str     w0, [x1, #0x10]
180 #endif
181
182         /* Initialize GIC Secure Bank Status */
183 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
184         branch_if_slave x0, 1f
185         bl      get_gic_offset
186         bl      gic_init_secure
187 1:
188 #ifdef CONFIG_GICV3
189         ldr     x0, =GICR_BASE
190         bl      gic_init_secure_percpu
191 #elif defined(CONFIG_GICV2)
192         bl      get_gic_offset
193         bl      gic_init_secure_percpu
194 #endif
195 #endif
196
197 100:
198         branch_if_master x0, x1, 2f
199
200 #if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
201         ldr     x0, =secondary_boot_func
202         blr     x0
203 #endif
204
205 2:
206         switch_el x1, 1f, 100f, 100f    /* skip if not in EL3 */
207 1:
208 #ifdef CONFIG_FSL_TZPC_BP147
209         /* Set Non Secure access for all devices protected via TZPC */
210         ldr     x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
211         orr     w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
212         str     w0, [x1]
213
214         isb
215         dsb     sy
216 #endif
217
218 #ifdef CONFIG_FSL_TZASC_400
219         /*
220          * LS2080 and its personalities does not support TZASC
221          * So skip TZASC related operations
222          */
223         bl      get_svr
224         lsr     w0, w0, #16
225         ldr     w1, =SVR_DEV(SVR_LS2080A)
226         cmp     w0, w1
227         b.eq    1f
228
229         /* Set TZASC so that:
230          * a. We use only Region0 whose global secure write/read is EN
231          * b. We use only Region0 whose NSAID write/read is EN
232          *
233          * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
234          *       placeholders.
235          */
236
237 .macro tzasc_prog, xreg
238
239         mov     x12, TZASC1_BASE
240         mov     x16, #0x10000
241         mul     x14, \xreg, x16
242         add     x14, x14,x12
243         mov     x1, #0x8
244         add     x1, x1, x14
245
246         ldr     w0, [x1]                /* Filter 0 Gate Keeper Register */
247         orr     w0, w0, #1 << 0         /* Set open_request for Filter 0 */
248         str     w0, [x1]
249
250         mov     x1, #0x110
251         add     x1, x1, x14
252
253         ldr     w0, [x1]                /* Region-0 Attributes Register */
254         orr     w0, w0, #1 << 31        /* Set Sec global write en, Bit[31] */
255         orr     w0, w0, #1 << 30        /* Set Sec global read en, Bit[30] */
256         str     w0, [x1]
257
258         mov     x1, #0x114
259         add     x1, x1, x14
260
261         ldr     w0, [x1]                /* Region-0 Access Register */
262         mov     w0, #0xFFFFFFFF         /* Set nsaid_wr_en and nsaid_rd_en */
263         str     w0, [x1]
264 .endm
265
266 #ifdef CONFIG_FSL_TZASC_1
267         mov     x13, #0
268         tzasc_prog      x13
269
270 #endif
271 #ifdef CONFIG_FSL_TZASC_2
272         mov     x13, #1
273         tzasc_prog      x13
274
275 #endif
276         isb
277         dsb     sy
278 #endif
279 100:
280 1:
281 #ifdef CONFIG_ARCH_LS1046A
282         switch_el x1, 1f, 100f, 100f    /* skip if not in EL3 */
283 1:
284         /* Initialize the L2 RAM latency */
285         mrs   x1, S3_1_c11_c0_2
286         mov   x0, #0x1C7
287         /* Clear L2 Tag RAM latency and L2 Data RAM latency */
288         bic   x1, x1, x0
289         /* Set L2 data ram latency bits [2:0] */
290         orr   x1, x1, #0x2
291         /* set L2 tag ram latency bits [8:6] */
292         orr   x1,  x1, #0x80
293         msr   S3_1_c11_c0_2, x1
294         isb
295 100:
296 #endif
297
298 #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
299         bl      fsl_ocram_init
300 #endif
301
302         mov     lr, x29                 /* Restore LR */
303         ret
304 ENDPROC(lowlevel_init)
305
306 #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
307 ENTRY(fsl_ocram_init)
308         mov     x28, lr                 /* Save LR */
309         bl      fsl_clear_ocram
310         bl      fsl_ocram_clear_ecc_err
311         mov     lr, x28                 /* Restore LR */
312         ret
313 ENDPROC(fsl_ocram_init)
314
315 ENTRY(fsl_clear_ocram)
316 /* Clear OCRAM */
317         ldr     x0, =CONFIG_SYS_FSL_OCRAM_BASE
318         ldr     x1, =(CONFIG_SYS_FSL_OCRAM_BASE + CONFIG_SYS_FSL_OCRAM_SIZE)
319         mov     x2, #0
320 clear_loop:
321         str     x2, [x0]
322         add     x0, x0, #8
323         cmp     x0, x1
324         b.lo    clear_loop
325         ret
326 ENDPROC(fsl_clear_ocram)
327
328 ENTRY(fsl_ocram_clear_ecc_err)
329         /* OCRAM1/2 ECC status bit */
330         mov     w1, #0x60
331         ldr     x0, =DCSR_DCFG_SBEESR2
332         str     w1, [x0]
333         ldr     x0, =DCSR_DCFG_MBEESR2
334         str     w1, [x0]
335         ret
336 ENDPROC(fsl_ocram_init)
337 #endif
338
339 #ifdef CONFIG_FSL_LSCH3
340         .globl get_svr
341 get_svr:
342         ldr     x1, =FSL_LSCH3_SVR
343         ldr     w0, [x1]
344         ret
345 #endif
346
347 #ifdef CONFIG_SYS_FSL_HAS_CCN504
348 hnf_pstate_poll:
349         /* x0 has the desired status, return 0 for success, 1 for timeout
350          * clobber x1, x2, x3, x4, x6, x7
351          */
352         mov     x1, x0
353         mov     x7, #0                  /* flag for timeout */
354         mrs     x3, cntpct_el0          /* read timer */
355         add     x3, x3, #1200           /* timeout after 100 microseconds */
356         mov     x0, #0x18
357         movk    x0, #0x420, lsl #16     /* HNF0_PSTATE_STATUS */
358         mov     w6, #8                  /* HN-F node count */
359 1:
360         ldr     x2, [x0]
361         cmp     x2, x1                  /* check status */
362         b.eq    2f
363         mrs     x4, cntpct_el0
364         cmp     x4, x3
365         b.ls    1b
366         mov     x7, #1                  /* timeout */
367         b       3f
368 2:
369         add     x0, x0, #0x10000        /* move to next node */
370         subs    w6, w6, #1
371         cbnz    w6, 1b
372 3:
373         mov     x0, x7
374         ret
375
376 hnf_set_pstate:
377         /* x0 has the desired state, clobber x1, x2, x6 */
378         mov     x1, x0
379         /* power state to SFONLY */
380         mov     w6, #8                  /* HN-F node count */
381         mov     x0, #0x10
382         movk    x0, #0x420, lsl #16     /* HNF0_PSTATE_REQ */
383 1:      /* set pstate to sfonly */
384         ldr     x2, [x0]
385         and     x2, x2, #0xfffffffffffffffc     /* & HNFPSTAT_MASK */
386         orr     x2, x2, x1
387         str     x2, [x0]
388         add     x0, x0, #0x10000        /* move to next node */
389         subs    w6, w6, #1
390         cbnz    w6, 1b
391
392         ret
393
394 ENTRY(__asm_flush_l3_dcache)
395         /*
396          * Return status in x0
397          *    success 0
398          *    timeout 1 for setting SFONLY, 2 for FAM, 3 for both
399          */
400         mov     x29, lr
401         mov     x8, #0
402
403         dsb     sy
404         mov     x0, #0x1                /* HNFPSTAT_SFONLY */
405         bl      hnf_set_pstate
406
407         mov     x0, #0x4                /* SFONLY status */
408         bl      hnf_pstate_poll
409         cbz     x0, 1f
410         mov     x8, #1                  /* timeout */
411 1:
412         dsb     sy
413         mov     x0, #0x3                /* HNFPSTAT_FAM */
414         bl      hnf_set_pstate
415
416         mov     x0, #0xc                /* FAM status */
417         bl      hnf_pstate_poll
418         cbz     x0, 1f
419         add     x8, x8, #0x2
420 1:
421         mov     x0, x8
422         mov     lr, x29
423         ret
424 ENDPROC(__asm_flush_l3_dcache)
425 #endif /* CONFIG_SYS_FSL_HAS_CCN504 */
426
427 #ifdef CONFIG_MP
428         /* Keep literals not used by the secondary boot code outside it */
429         .ltorg
430
431         /* Using 64 bit alignment since the spin table is accessed as data */
432         .align 4
433         .global secondary_boot_code
434         /* Secondary Boot Code starts here */
435 secondary_boot_code:
436         .global __spin_table
437 __spin_table:
438         .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
439
440         .align 2
441 ENTRY(secondary_boot_func)
442         /*
443          * MPIDR_EL1 Fields:
444          * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
445          * MPIDR[7:2] = AFF0_RES
446          * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
447          * MPIDR[23:16] = AFF2_CLUSTERID
448          * MPIDR[24] = MT
449          * MPIDR[29:25] = RES0
450          * MPIDR[30] = U
451          * MPIDR[31] = ME
452          * MPIDR[39:32] = AFF3
453          *
454          * Linear Processor ID (LPID) calculation from MPIDR_EL1:
455          * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
456          * until AFF2_CLUSTERID and AFF3 have non-zero values)
457          *
458          * LPID = MPIDR[15:8] | MPIDR[1:0]
459          */
460         mrs     x0, mpidr_el1
461         ubfm    x1, x0, #8, #15
462         ubfm    x2, x0, #0, #1
463         orr     x10, x2, x1, lsl #2     /* x10 has LPID */
464         ubfm    x9, x0, #0, #15         /* x9 contains MPIDR[15:0] */
465         /*
466          * offset of the spin table element for this core from start of spin
467          * table (each elem is padded to 64 bytes)
468          */
469         lsl     x1, x10, #6
470         ldr     x0, =__spin_table
471         /* physical address of this cpus spin table element */
472         add     x11, x1, x0
473
474         ldr     x0, =__real_cntfrq
475         ldr     x0, [x0]
476         msr     cntfrq_el0, x0  /* set with real frequency */
477         str     x9, [x11, #16]  /* LPID */
478         mov     x4, #1
479         str     x4, [x11, #8]   /* STATUS */
480         dsb     sy
481 #if defined(CONFIG_GICV3)
482         gic_wait_for_interrupt_m x0
483 #elif defined(CONFIG_GICV2)
484         bl      get_gic_offset
485         mov     x0, x1
486         gic_wait_for_interrupt_m x0, w1
487 #endif
488
489 slave_cpu:
490         wfe
491         ldr     x0, [x11]
492         cbz     x0, slave_cpu
493 #ifndef CONFIG_ARMV8_SWITCH_TO_EL1
494         mrs     x1, sctlr_el2
495 #else
496         mrs     x1, sctlr_el1
497 #endif
498         tbz     x1, #25, cpu_is_le
499         rev     x0, x0                  /* BE to LE conversion */
500 cpu_is_le:
501         ldr     x5, [x11, #24]
502         cbz     x5, 1f
503
504 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
505         adr     x4, secondary_switch_to_el1
506         ldr     x5, =ES_TO_AARCH64
507 #else
508         ldr     x4, [x11]
509         ldr     x5, =ES_TO_AARCH32
510 #endif
511         bl      secondary_switch_to_el2
512
513 1:
514 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
515         adr     x4, secondary_switch_to_el1
516 #else
517         ldr     x4, [x11]
518 #endif
519         ldr     x5, =ES_TO_AARCH64
520         bl      secondary_switch_to_el2
521
522 ENDPROC(secondary_boot_func)
523
524 ENTRY(secondary_switch_to_el2)
525         switch_el x6, 1f, 0f, 0f
526 0:      ret
527 1:      armv8_switch_to_el2_m x4, x5, x6
528 ENDPROC(secondary_switch_to_el2)
529
530 ENTRY(secondary_switch_to_el1)
531         mrs     x0, mpidr_el1
532         ubfm    x1, x0, #8, #15
533         ubfm    x2, x0, #0, #1
534         orr     x10, x2, x1, lsl #2     /* x10 has LPID */
535
536         lsl     x1, x10, #6
537         ldr     x0, =__spin_table
538         /* physical address of this cpus spin table element */
539         add     x11, x1, x0
540
541         ldr     x4, [x11]
542
543         ldr     x5, [x11, #24]
544         cbz     x5, 2f
545
546         ldr     x5, =ES_TO_AARCH32
547         bl      switch_to_el1
548
549 2:      ldr     x5, =ES_TO_AARCH64
550
551 switch_to_el1:
552         switch_el x6, 0f, 1f, 0f
553 0:      ret
554 1:      armv8_switch_to_el1_m x4, x5, x6
555 ENDPROC(secondary_switch_to_el1)
556
557         /* Ensure that the literals used by the secondary boot code are
558          * assembled within it (this is required so that we can protect
559          * this area with a single memreserve region
560          */
561         .ltorg
562
563         /* 64 bit alignment for elements accessed as data */
564         .align 4
565         .global __real_cntfrq
566 __real_cntfrq:
567         .quad COUNTER_FREQUENCY
568         .globl __secondary_boot_code_size
569         .type __secondary_boot_code_size, %object
570         /* Secondary Boot Code ends here */
571 __secondary_boot_code_size:
572         .quad .-secondary_boot_code
573 #endif