]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / 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 #ifdef CONFIG_FSL_TZASC_1
237         ldr     x1, =TZASC_GATE_KEEPER(0)
238         ldr     w0, [x1]                /* Filter 0 Gate Keeper Register */
239         orr     w0, w0, #1 << 0         /* Set open_request for Filter 0 */
240         str     w0, [x1]
241
242         ldr     x1, =TZASC_REGION_ATTRIBUTES_0(0)
243         ldr     w0, [x1]                /* Region-0 Attributes Register */
244         orr     w0, w0, #1 << 31        /* Set Sec global write en, Bit[31] */
245         orr     w0, w0, #1 << 30        /* Set Sec global read en, Bit[30] */
246         str     w0, [x1]
247
248         ldr     x1, =TZASC_REGION_ID_ACCESS_0(0)
249         ldr     w0, [x1]                /* Region-0 Access Register */
250         mov     w0, #0xFFFFFFFF         /* Set nsaid_wr_en and nsaid_rd_en */
251         str     w0, [x1]
252 #endif
253 #ifdef CONFIG_FSL_TZASC_2
254         ldr     x1, =TZASC_GATE_KEEPER(1)
255         ldr     w0, [x1]                /* Filter 0 Gate Keeper Register */
256         orr     w0, w0, #1 << 0         /* Set open_request for Filter 0 */
257         str     w0, [x1]
258
259         ldr     x1, =TZASC_REGION_ATTRIBUTES_0(1)
260         ldr     w0, [x1]                /* Region-1 Attributes Register */
261         orr     w0, w0, #1 << 31        /* Set Sec global write en, Bit[31] */
262         orr     w0, w0, #1 << 30        /* Set Sec global read en, Bit[30] */
263         str     w0, [x1]
264
265         ldr     x1, =TZASC_REGION_ID_ACCESS_0(1)
266         ldr     w0, [x1]                /* Region-1 Attributes Register */
267         mov     w0, #0xFFFFFFFF         /* Set nsaid_wr_en and nsaid_rd_en */
268         str     w0, [x1]
269 #endif
270         isb
271         dsb     sy
272 #endif
273 100:
274 1:
275 #ifdef CONFIG_ARCH_LS1046A
276         switch_el x1, 1f, 100f, 100f    /* skip if not in EL3 */
277 1:
278         /* Initialize the L2 RAM latency */
279         mrs   x1, S3_1_c11_c0_2
280         mov   x0, #0x1C7
281         /* Clear L2 Tag RAM latency and L2 Data RAM latency */
282         bic   x1, x1, x0
283         /* Set L2 data ram latency bits [2:0] */
284         orr   x1, x1, #0x2
285         /* set L2 tag ram latency bits [8:6] */
286         orr   x1,  x1, #0x80
287         msr   S3_1_c11_c0_2, x1
288         isb
289 100:
290 #endif
291
292 #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
293         bl      fsl_ocram_init
294 #endif
295
296         mov     lr, x29                 /* Restore LR */
297         ret
298 ENDPROC(lowlevel_init)
299
300 #if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
301 ENTRY(fsl_ocram_init)
302         mov     x28, lr                 /* Save LR */
303         bl      fsl_clear_ocram
304         bl      fsl_ocram_clear_ecc_err
305         mov     lr, x28                 /* Restore LR */
306         ret
307 ENDPROC(fsl_ocram_init)
308
309 ENTRY(fsl_clear_ocram)
310 /* Clear OCRAM */
311         ldr     x0, =CONFIG_SYS_FSL_OCRAM_BASE
312         ldr     x1, =(CONFIG_SYS_FSL_OCRAM_BASE + CONFIG_SYS_FSL_OCRAM_SIZE)
313         mov     x2, #0
314 clear_loop:
315         str     x2, [x0]
316         add     x0, x0, #8
317         cmp     x0, x1
318         b.lo    clear_loop
319         ret
320 ENDPROC(fsl_clear_ocram)
321
322 ENTRY(fsl_ocram_clear_ecc_err)
323         /* OCRAM1/2 ECC status bit */
324         mov     w1, #0x60
325         ldr     x0, =DCSR_DCFG_SBEESR2
326         str     w1, [x0]
327         ldr     x0, =DCSR_DCFG_MBEESR2
328         str     w1, [x0]
329         ret
330 ENDPROC(fsl_ocram_init)
331 #endif
332
333 #ifdef CONFIG_FSL_LSCH3
334         .globl get_svr
335 get_svr:
336         ldr     x1, =FSL_LSCH3_SVR
337         ldr     w0, [x1]
338         ret
339 #endif
340
341 #ifdef CONFIG_SYS_FSL_HAS_CCN504
342 hnf_pstate_poll:
343         /* x0 has the desired status, return 0 for success, 1 for timeout
344          * clobber x1, x2, x3, x4, x6, x7
345          */
346         mov     x1, x0
347         mov     x7, #0                  /* flag for timeout */
348         mrs     x3, cntpct_el0          /* read timer */
349         add     x3, x3, #1200           /* timeout after 100 microseconds */
350         mov     x0, #0x18
351         movk    x0, #0x420, lsl #16     /* HNF0_PSTATE_STATUS */
352         mov     w6, #8                  /* HN-F node count */
353 1:
354         ldr     x2, [x0]
355         cmp     x2, x1                  /* check status */
356         b.eq    2f
357         mrs     x4, cntpct_el0
358         cmp     x4, x3
359         b.ls    1b
360         mov     x7, #1                  /* timeout */
361         b       3f
362 2:
363         add     x0, x0, #0x10000        /* move to next node */
364         subs    w6, w6, #1
365         cbnz    w6, 1b
366 3:
367         mov     x0, x7
368         ret
369
370 hnf_set_pstate:
371         /* x0 has the desired state, clobber x1, x2, x6 */
372         mov     x1, x0
373         /* power state to SFONLY */
374         mov     w6, #8                  /* HN-F node count */
375         mov     x0, #0x10
376         movk    x0, #0x420, lsl #16     /* HNF0_PSTATE_REQ */
377 1:      /* set pstate to sfonly */
378         ldr     x2, [x0]
379         and     x2, x2, #0xfffffffffffffffc     /* & HNFPSTAT_MASK */
380         orr     x2, x2, x1
381         str     x2, [x0]
382         add     x0, x0, #0x10000        /* move to next node */
383         subs    w6, w6, #1
384         cbnz    w6, 1b
385
386         ret
387
388 ENTRY(__asm_flush_l3_dcache)
389         /*
390          * Return status in x0
391          *    success 0
392          *    timeout 1 for setting SFONLY, 2 for FAM, 3 for both
393          */
394         mov     x29, lr
395         mov     x8, #0
396
397         dsb     sy
398         mov     x0, #0x1                /* HNFPSTAT_SFONLY */
399         bl      hnf_set_pstate
400
401         mov     x0, #0x4                /* SFONLY status */
402         bl      hnf_pstate_poll
403         cbz     x0, 1f
404         mov     x8, #1                  /* timeout */
405 1:
406         dsb     sy
407         mov     x0, #0x3                /* HNFPSTAT_FAM */
408         bl      hnf_set_pstate
409
410         mov     x0, #0xc                /* FAM status */
411         bl      hnf_pstate_poll
412         cbz     x0, 1f
413         add     x8, x8, #0x2
414 1:
415         mov     x0, x8
416         mov     lr, x29
417         ret
418 ENDPROC(__asm_flush_l3_dcache)
419 #endif /* CONFIG_SYS_FSL_HAS_CCN504 */
420
421 #ifdef CONFIG_MP
422         /* Keep literals not used by the secondary boot code outside it */
423         .ltorg
424
425         /* Using 64 bit alignment since the spin table is accessed as data */
426         .align 4
427         .global secondary_boot_code
428         /* Secondary Boot Code starts here */
429 secondary_boot_code:
430         .global __spin_table
431 __spin_table:
432         .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
433
434         .align 2
435 ENTRY(secondary_boot_func)
436         /*
437          * MPIDR_EL1 Fields:
438          * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
439          * MPIDR[7:2] = AFF0_RES
440          * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
441          * MPIDR[23:16] = AFF2_CLUSTERID
442          * MPIDR[24] = MT
443          * MPIDR[29:25] = RES0
444          * MPIDR[30] = U
445          * MPIDR[31] = ME
446          * MPIDR[39:32] = AFF3
447          *
448          * Linear Processor ID (LPID) calculation from MPIDR_EL1:
449          * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
450          * until AFF2_CLUSTERID and AFF3 have non-zero values)
451          *
452          * LPID = MPIDR[15:8] | MPIDR[1:0]
453          */
454         mrs     x0, mpidr_el1
455         ubfm    x1, x0, #8, #15
456         ubfm    x2, x0, #0, #1
457         orr     x10, x2, x1, lsl #2     /* x10 has LPID */
458         ubfm    x9, x0, #0, #15         /* x9 contains MPIDR[15:0] */
459         /*
460          * offset of the spin table element for this core from start of spin
461          * table (each elem is padded to 64 bytes)
462          */
463         lsl     x1, x10, #6
464         ldr     x0, =__spin_table
465         /* physical address of this cpus spin table element */
466         add     x11, x1, x0
467
468         ldr     x0, =__real_cntfrq
469         ldr     x0, [x0]
470         msr     cntfrq_el0, x0  /* set with real frequency */
471         str     x9, [x11, #16]  /* LPID */
472         mov     x4, #1
473         str     x4, [x11, #8]   /* STATUS */
474         dsb     sy
475 #if defined(CONFIG_GICV3)
476         gic_wait_for_interrupt_m x0
477 #elif defined(CONFIG_GICV2)
478         bl      get_gic_offset
479         mov     x0, x1
480         gic_wait_for_interrupt_m x0, w1
481 #endif
482
483 slave_cpu:
484         wfe
485         ldr     x0, [x11]
486         cbz     x0, slave_cpu
487 #ifndef CONFIG_ARMV8_SWITCH_TO_EL1
488         mrs     x1, sctlr_el2
489 #else
490         mrs     x1, sctlr_el1
491 #endif
492         tbz     x1, #25, cpu_is_le
493         rev     x0, x0                  /* BE to LE conversion */
494 cpu_is_le:
495         ldr     x5, [x11, #24]
496         cbz     x5, 1f
497
498 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
499         adr     x4, secondary_switch_to_el1
500         ldr     x5, =ES_TO_AARCH64
501 #else
502         ldr     x4, [x11]
503         ldr     x5, =ES_TO_AARCH32
504 #endif
505         bl      secondary_switch_to_el2
506
507 1:
508 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
509         adr     x4, secondary_switch_to_el1
510 #else
511         ldr     x4, [x11]
512 #endif
513         ldr     x5, =ES_TO_AARCH64
514         bl      secondary_switch_to_el2
515
516 ENDPROC(secondary_boot_func)
517
518 ENTRY(secondary_switch_to_el2)
519         switch_el x6, 1f, 0f, 0f
520 0:      ret
521 1:      armv8_switch_to_el2_m x4, x5, x6
522 ENDPROC(secondary_switch_to_el2)
523
524 ENTRY(secondary_switch_to_el1)
525         mrs     x0, mpidr_el1
526         ubfm    x1, x0, #8, #15
527         ubfm    x2, x0, #0, #1
528         orr     x10, x2, x1, lsl #2     /* x10 has LPID */
529
530         lsl     x1, x10, #6
531         ldr     x0, =__spin_table
532         /* physical address of this cpus spin table element */
533         add     x11, x1, x0
534
535         ldr     x4, [x11]
536
537         ldr     x5, [x11, #24]
538         cbz     x5, 2f
539
540         ldr     x5, =ES_TO_AARCH32
541         bl      switch_to_el1
542
543 2:      ldr     x5, =ES_TO_AARCH64
544
545 switch_to_el1:
546         switch_el x6, 0f, 1f, 0f
547 0:      ret
548 1:      armv8_switch_to_el1_m x4, x5, x6
549 ENDPROC(secondary_switch_to_el1)
550
551         /* Ensure that the literals used by the secondary boot code are
552          * assembled within it (this is required so that we can protect
553          * this area with a single memreserve region
554          */
555         .ltorg
556
557         /* 64 bit alignment for elements accessed as data */
558         .align 4
559         .global __real_cntfrq
560 __real_cntfrq:
561         .quad COUNTER_FREQUENCY
562         .globl __secondary_boot_code_size
563         .type __secondary_boot_code_size, %object
564         /* Secondary Boot Code ends here */
565 __secondary_boot_code_size:
566         .quad .-secondary_boot_code
567 #endif