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*/ 30ENTRY(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 541: 55#endif 56 ret 57ENDPROC(get_gic_offset) 58 59ENTRY(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 68ENDPROC(smp_kick_all_cpus) 69 70 71ENTRY(lowlevel_init) 72 mov x29, lr /* Save LR */ 73 74 switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ 751: 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 1031: 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 1871: 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 197100: 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 2052: 206 switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ 2071: 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 273100: 2741: 275#ifdef CONFIG_ARCH_LS1046A 276 switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */ 2771: 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 289100: 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 298ENDPROC(lowlevel_init) 299 300#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD) 301ENTRY(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 307ENDPROC(fsl_ocram_init) 308 309ENTRY(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 314clear_loop: 315 str x2, [x0] 316 add x0, x0, #8 317 cmp x0, x1 318 b.lo clear_loop 319 ret 320ENDPROC(fsl_clear_ocram) 321 322ENTRY(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 330ENDPROC(fsl_ocram_init) 331#endif 332 333#ifdef CONFIG_FSL_LSCH3 334 .globl get_svr 335get_svr: 336 ldr x1, =FSL_LSCH3_SVR 337 ldr w0, [x1] 338 ret 339#endif 340 341#ifdef CONFIG_SYS_FSL_HAS_CCN504 342hnf_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 */ 3531: 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 3622: 363 add x0, x0, #0x10000 /* move to next node */ 364 subs w6, w6, #1 365 cbnz w6, 1b 3663: 367 mov x0, x7 368 ret 369 370hnf_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 */ 3771: /* 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 388ENTRY(__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 */ 4051: 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 4141: 415 mov x0, x8 416 mov lr, x29 417 ret 418ENDPROC(__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 */ 429secondary_boot_code: 430 .global __spin_table 431__spin_table: 432 .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE 433 434 .align 2 435ENTRY(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 483slave_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 */ 494cpu_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 5071: 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 516ENDPROC(secondary_boot_func) 517 518ENTRY(secondary_switch_to_el2) 519 switch_el x6, 1f, 0f, 0f 5200: ret 5211: armv8_switch_to_el2_m x4, x5, x6 522ENDPROC(secondary_switch_to_el2) 523 524ENTRY(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 5432: ldr x5, =ES_TO_AARCH64 544 545switch_to_el1: 546 switch_el x6, 0f, 1f, 0f 5470: ret 5481: armv8_switch_to_el1_m x4, x5, x6 549ENDPROC(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 568