1/* 2 * Copyright 2018-2020 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8.section .text, "ax" 9 10#include <asm_macros.S> 11 12#include <lib/psci/psci.h> 13#include <nxp_timer.h> 14#include <plat_gic.h> 15#include <pmu.h> 16 17#include <bl31_data.h> 18#include <plat_psci.h> 19#include <platform_def.h> 20 21.global soc_init_start 22.global soc_init_percpu 23.global soc_init_finish 24.global _set_platform_security 25.global _soc_set_start_addr 26 27.global _soc_core_release 28.global _soc_ck_disabled 29.global _soc_core_restart 30.global _soc_core_prep_off 31.global _soc_core_entr_off 32.global _soc_core_exit_off 33.global _soc_sys_reset 34.global _soc_sys_off 35.global _soc_core_prep_stdby 36.global _soc_core_entr_stdby 37.global _soc_core_exit_stdby 38.global _soc_core_prep_pwrdn 39.global _soc_core_entr_pwrdn 40.global _soc_core_exit_pwrdn 41.global _soc_clstr_prep_stdby 42.global _soc_clstr_exit_stdby 43.global _soc_clstr_prep_pwrdn 44.global _soc_clstr_exit_pwrdn 45.global _soc_sys_prep_stdby 46.global _soc_sys_exit_stdby 47.global _soc_sys_prep_pwrdn 48.global _soc_sys_pwrdn_wfi 49.global _soc_sys_exit_pwrdn 50 51.equ TZPC_BASE, 0x02200000 52.equ TZPCDECPROT_0_SET_BASE, 0x02200804 53.equ TZPCDECPROT_1_SET_BASE, 0x02200810 54.equ TZPCDECPROT_2_SET_BASE, 0x0220081C 55 56#define CLUSTER_3_CORES_MASK 0xC0 57#define CLUSTER_3_IN_RESET 1 58#define CLUSTER_3_NORMAL 0 59 60/* cluster 3 handling no longer based on frequency, but rather on RCW[850], 61 * which is bit 18 of RCWSR27 62 */ 63#define CLUSTER_3_RCW_BIT 0x40000 64 65/* retry count for clock-stop acks */ 66.equ CLOCK_RETRY_CNT, 800 67 68/* disable prefetching in the A72 core */ 69#define CPUACTLR_DIS_LS_HW_PRE 0x100000000000000 70#define CPUACTLR_DIS_L2_TLB_PRE 0x200000 71 72/* Function starts the initialization tasks of the soc, 73 * using secondary cores if they are available 74 * 75 * Called from C, saving the non-volatile regs 76 * save these as pairs of registers to maintain the 77 * required 16-byte alignment on the stack 78 * 79 * in: 80 * out: 81 * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11 82 */ 83func soc_init_start 84 stp x4, x5, [sp, #-16]! 85 stp x6, x7, [sp, #-16]! 86 stp x8, x9, [sp, #-16]! 87 stp x10, x11, [sp, #-16]! 88 stp x12, x13, [sp, #-16]! 89 stp x18, x30, [sp, #-16]! 90 91 /* make sure the personality has been 92 * established by releasing cores that 93 * are marked "to-be-disabled" from reset 94 */ 95 bl release_disabled /* 0-9 */ 96 97 /* init the task flags */ 98 bl _init_task_flags /* 0-1 */ 99 100 /* set SCRATCHRW7 to 0x0 */ 101 ldr x0, =DCFG_SCRATCHRW7_OFFSET 102 mov x1, xzr 103 bl _write_reg_dcfg 104 1051: 106 /* restore the aarch32/64 non-volatile registers */ 107 ldp x18, x30, [sp], #16 108 ldp x12, x13, [sp], #16 109 ldp x10, x11, [sp], #16 110 ldp x8, x9, [sp], #16 111 ldp x6, x7, [sp], #16 112 ldp x4, x5, [sp], #16 113 ret 114endfunc soc_init_start 115 116 117/* Function performs any soc-specific initialization that is needed on 118 * a per-core basis. 119 * in: none 120 * out: none 121 * uses x0, x1, x2, x3 122 */ 123func soc_init_percpu 124 stp x4, x30, [sp, #-16]! 125 126 bl plat_my_core_mask 127 mov x2, x0 /* x2 = core mask */ 128 129 /* Check if this core is marked for prefetch disable 130 */ 131 mov x0, #PREFETCH_DIS_OFFSET 132 bl _get_global_data /* 0-1 */ 133 tst x0, x2 134 b.eq 1f 135 bl _disable_ldstr_pfetch_A72 /* 0 */ 1361: 137 mov x0, #NXP_PMU_ADDR 138 bl enable_timer_base_to_cluster 139 ldp x4, x30, [sp], #16 140 ret 141endfunc soc_init_percpu 142 143 144/* Function completes the initialization tasks of the soc 145 * in: 146 * out: 147 * uses x0, x1, x2, x3, x4 148 */ 149func soc_init_finish 150 stp x4, x30, [sp, #-16]! 151 152 ldp x4, x30, [sp], #16 153 ret 154endfunc soc_init_finish 155 156 157/* Function sets the security mechanisms in the SoC to implement the 158 * Platform Security Policy 159 */ 160func _set_platform_security 161 mov x8, x30 162 163#if (!SUPPRESS_TZC) 164 /* initialize the tzpc */ 165 bl init_tzpc 166#endif 167 168#if (!SUPPRESS_SEC) 169 /* initialize secmon */ 170#ifdef NXP_SNVS_ENABLED 171 mov x0, #NXP_SNVS_ADDR 172 bl init_sec_mon 173#endif 174#endif 175 176 mov x30, x8 177 ret 178endfunc _set_platform_security 179 180 181/* Function writes a 64-bit address to bootlocptrh/l 182 * in: x0, 64-bit address to write to BOOTLOCPTRL/H 183 * uses x0, x1, x2 184 */ 185func _soc_set_start_addr 186 /* Get the 64-bit base address of the dcfg block */ 187 ldr x2, =NXP_DCFG_ADDR 188 189 /* write the 32-bit BOOTLOCPTRL register */ 190 mov x1, x0 191 str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET] 192 193 /* write the 32-bit BOOTLOCPTRH register */ 194 lsr x1, x0, #32 195 str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET] 196 ret 197endfunc _soc_set_start_addr 198 199/* Function releases a secondary core from reset 200 * in: x0 = core_mask_lsb 201 * out: none 202 * uses: x0, x1, x2, x3 203 */ 204func _soc_core_release 205 mov x3, x30 206 207 ldr x1, =NXP_SEC_REGFILE_ADDR 208 /* write to CORE_HOLD to tell 209 * the bootrom that this core is 210 * expected to run. 211 */ 212 str w0, [x1, #CORE_HOLD_OFFSET] 213 214 /* read-modify-write BRRL to release core */ 215 mov x1, #NXP_RESET_ADDR 216 ldr w2, [x1, #BRR_OFFSET] 217 218 /* x0 = core mask */ 219 orr w2, w2, w0 220 str w2, [x1, #BRR_OFFSET] 221 dsb sy 222 isb 223 224 /* send event */ 225 sev 226 isb 227 228 mov x30, x3 229 ret 230endfunc _soc_core_release 231 232 233/* Function determines if a core is disabled via COREDISABLEDSR 234 * in: w0 = core_mask_lsb 235 * out: w0 = 0, core not disabled 236 * w0 != 0, core disabled 237 * uses x0, x1 238 */ 239func _soc_ck_disabled 240 241 /* get base addr of dcfg block */ 242 ldr x1, =NXP_DCFG_ADDR 243 244 /* read COREDISABLEDSR */ 245 ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET] 246 247 /* test core bit */ 248 and w0, w1, w0 249 250 ret 251endfunc _soc_ck_disabled 252 253 254/* Part of CPU_ON 255 * Function restarts a core shutdown via _soc_core_entr_off 256 * in: x0 = core mask lsb (of the target cpu) 257 * out: x0 == 0, on success 258 * x0 != 0, on failure 259 * uses x0, x1, x2, x3, x4, x5, x6 260 */ 261func _soc_core_restart 262 mov x6, x30 263 mov x4, x0 264 265 /* pgm GICD_CTLR - enable secure grp0 */ 266 mov x5, #NXP_GICD_ADDR 267 ldr w2, [x5, #GICD_CTLR_OFFSET] 268 orr w2, w2, #GICD_CTLR_EN_GRP_0 269 str w2, [x5, #GICD_CTLR_OFFSET] 270 dsb sy 271 isb 272 273 /* poll on RWP til write completes */ 2744: 275 ldr w2, [x5, #GICD_CTLR_OFFSET] 276 tst w2, #GICD_CTLR_RWP 277 b.ne 4b 278 279 /* x4 = core mask lsb 280 * x5 = gicd base addr 281 */ 282 mov x0, x4 283 bl get_mpidr_value 284 285 /* x0 = mpidr of target core 286 * x4 = core mask lsb of target core 287 * x5 = gicd base addr 288 */ 289 290 /* generate target list bit */ 291 and x1, x0, #MPIDR_AFFINITY0_MASK 292 mov x2, #1 293 lsl x2, x2, x1 294 295 /* get the affinity1 field */ 296 and x1, x0, #MPIDR_AFFINITY1_MASK 297 lsl x1, x1, #8 298 orr x2, x2, x1 299 300 /* insert the INTID for SGI15 */ 301 orr x2, x2, #ICC_SGI0R_EL1_INTID 302 303 /* fire the SGI */ 304 msr ICC_SGI0R_EL1, x2 305 dsb sy 306 isb 307 308 /* load '0' on success */ 309 mov x0, xzr 310 311 mov x30, x6 312 ret 313endfunc _soc_core_restart 314 315 316/* Part of CPU_OFF 317 * Function programs SoC & GIC registers in preparation for shutting down 318 * the core 319 * in: x0 = core mask lsb 320 * out: none 321 * uses x0, x1, x2, x3, x4, x5, x6, x7 322 */ 323func _soc_core_prep_off 324 mov x8, x30 325 mov x7, x0 /* x7 = core mask lsb */ 326 327 mrs x1, CORTEX_A72_ECTLR_EL1 328 329 /* set smp and disable L2 snoops in cpuectlr */ 330 orr x1, x1, #CPUECTLR_SMPEN_EN 331 orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH 332 bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK 333 bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK 334 335 /* set retention control in cpuectlr */ 336 bic x1, x1, #CPUECTLR_TIMER_MASK 337 orr x1, x1, #CPUECTLR_TIMER_8TICKS 338 msr CORTEX_A72_ECTLR_EL1, x1 339 340 /* get redistributor rd base addr for this core */ 341 mov x0, x7 342 bl get_gic_rd_base 343 mov x6, x0 344 345 /* get redistributor sgi base addr for this core */ 346 mov x0, x7 347 bl get_gic_sgi_base 348 mov x5, x0 349 350 /* x5 = gicr sgi base addr 351 * x6 = gicr rd base addr 352 * x7 = core mask lsb 353 */ 354 355 /* disable SGI 15 at redistributor - GICR_ICENABLER0 */ 356 mov w3, #GICR_ICENABLER0_SGI15 357 str w3, [x5, #GICR_ICENABLER0_OFFSET] 3582: 359 /* poll on rwp bit in GICR_CTLR */ 360 ldr w4, [x6, #GICR_CTLR_OFFSET] 361 tst w4, #GICR_CTLR_RWP 362 b.ne 2b 363 364 /* disable GRP1 interrupts at cpu interface */ 365 msr ICC_IGRPEN1_EL3, xzr 366 367 /* disable GRP0 ints at cpu interface */ 368 msr ICC_IGRPEN0_EL1, xzr 369 370 /* program the redistributor - poll on GICR_CTLR.RWP as needed */ 371 372 /* define SGI 15 as Grp0 - GICR_IGROUPR0 */ 373 ldr w4, [x5, #GICR_IGROUPR0_OFFSET] 374 bic w4, w4, #GICR_IGROUPR0_SGI15 375 str w4, [x5, #GICR_IGROUPR0_OFFSET] 376 377 /* define SGI 15 as Grp0 - GICR_IGRPMODR0 */ 378 ldr w3, [x5, #GICR_IGRPMODR0_OFFSET] 379 bic w3, w3, #GICR_IGRPMODR0_SGI15 380 str w3, [x5, #GICR_IGRPMODR0_OFFSET] 381 382 /* set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */ 383 ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET] 384 bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK 385 str w4, [x5, #GICR_IPRIORITYR3_OFFSET] 386 387 /* enable SGI 15 at redistributor - GICR_ISENABLER0 */ 388 mov w3, #GICR_ISENABLER0_SGI15 389 str w3, [x5, #GICR_ISENABLER0_OFFSET] 390 dsb sy 391 isb 3923: 393 /* poll on rwp bit in GICR_CTLR */ 394 ldr w4, [x6, #GICR_CTLR_OFFSET] 395 tst w4, #GICR_CTLR_RWP 396 b.ne 3b 397 398 /* quiesce the debug interfaces */ 399 mrs x3, osdlr_el1 400 orr x3, x3, #OSDLR_EL1_DLK_LOCK 401 msr osdlr_el1, x3 402 isb 403 404 /* enable grp0 ints */ 405 mov x3, #ICC_IGRPEN0_EL1_EN 406 msr ICC_IGRPEN0_EL1, x3 407 408 /* x5 = gicr sgi base addr 409 * x6 = gicr rd base addr 410 * x7 = core mask lsb 411 */ 412 413 /* clear any pending interrupts */ 414 mvn w1, wzr 415 str w1, [x5, #GICR_ICPENDR0_OFFSET] 416 417 /* make sure system counter is enabled */ 418 ldr x3, =NXP_TIMER_ADDR 419 ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET] 420 tst w0, #SYS_COUNTER_CNTCR_EN 421 b.ne 4f 422 orr w0, w0, #SYS_COUNTER_CNTCR_EN 423 str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET] 4244: 425 /* enable the core timer and mask timer interrupt */ 426 mov x1, #CNTP_CTL_EL0_EN 427 orr x1, x1, #CNTP_CTL_EL0_IMASK 428 msr cntp_ctl_el0, x1 429 430 isb 431 mov x30, x8 432 ret 433endfunc _soc_core_prep_off 434 435 436/* Part of CPU_OFF: 437 * Function performs the final steps to shutdown the core 438 * in: x0 = core mask lsb 439 * out: none 440 * uses x0, x1, x2, x3, x4, x5 441 */ 442func _soc_core_entr_off 443 mov x5, x30 444 mov x4, x0 445 4461: 447 /* enter low-power state by executing wfi */ 448 wfi 449 450 /* see if SGI15 woke us up */ 451 mrs x2, ICC_IAR0_EL1 452 mov x3, #ICC_IAR0_EL1_SGI15 453 cmp x2, x3 454 b.ne 2f 455 456 /* deactivate the intrrupts. */ 457 msr ICC_EOIR0_EL1, x2 458 4592: 460 /* check if core is turned ON */ 461 mov x0, x4 462 /* Fetched the core state in x0 */ 463 bl _getCoreState 464 465 cmp x0, #CORE_WAKEUP 466 b.ne 1b 467 468 /* Reached here, exited the wfi */ 469 470 mov x30, x5 471 ret 472endfunc _soc_core_entr_off 473 474 475/* Part of CPU_OFF: 476 * Function starts the process of starting a core back up 477 * in: x0 = core mask lsb 478 * out: none 479 * uses x0, x1, x2, x3, x4, x5, x6 480 */ 481func _soc_core_exit_off 482 mov x6, x30 483 mov x5, x0 484 485 /* disable forwarding of GRP0 ints at cpu interface */ 486 msr ICC_IGRPEN0_EL1, xzr 487 488 /* get redistributor sgi base addr for this core */ 489 mov x0, x5 490 bl get_gic_sgi_base 491 mov x4, x0 492 493 /* x4 = gicr sgi base addr 494 * x5 = core mask 495 */ 496 497 /* disable SGI 15 at redistributor - GICR_ICENABLER0 */ 498 mov w1, #GICR_ICENABLER0_SGI15 499 str w1, [x4, #GICR_ICENABLER0_OFFSET] 500 501 /* get redistributor rd base addr for this core */ 502 mov x0, x5 503 bl get_gic_rd_base 504 mov x4, x0 505 5062: 507 /* poll on rwp bit in GICR_CTLR */ 508 ldr w2, [x4, #GICR_CTLR_OFFSET] 509 tst w2, #GICR_CTLR_RWP 510 b.ne 2b 511 512 /* unlock the debug interfaces */ 513 mrs x3, osdlr_el1 514 bic x3, x3, #OSDLR_EL1_DLK_LOCK 515 msr osdlr_el1, x3 516 isb 517 518 dsb sy 519 isb 520 mov x30, x6 521 ret 522endfunc _soc_core_exit_off 523 524 525/* Function requests a reset of the entire SOC 526 * in: none 527 * out: none 528 * uses: x0, x1, x2, x3, x4, x5, x6 529 */ 530func _soc_sys_reset 531 mov x6, x30 532 533 ldr x2, =NXP_RST_ADDR 534 /* clear the RST_REQ_MSK and SW_RST_REQ */ 535 536 mov w0, #0x00000000 537 str w0, [x2, #RSTCNTL_OFFSET] 538 539 /* initiate the sw reset request */ 540 mov w0, #SW_RST_REQ_INIT 541 str w0, [x2, #RSTCNTL_OFFSET] 542 543 /* In case this address range is mapped as cacheable, 544 * flush the write out of the dcaches. 545 */ 546 add x2, x2, #RSTCNTL_OFFSET 547 dc cvac, x2 548 dsb st 549 isb 550 551 /* Function does not return */ 552 b . 553endfunc _soc_sys_reset 554 555 556/* Part of SYSTEM_OFF: 557 * Function turns off the SoC clocks 558 * Note: Function is not intended to return, and the only allowable 559 * recovery is POR 560 * in: none 561 * out: none 562 * uses x0, x1, x2, x3 563 */ 564func _soc_sys_off 565 566 /* disable sec, QBman, spi and qspi */ 567 ldr x2, =NXP_DCFG_ADDR 568 ldr x0, =DCFG_DEVDISR1_OFFSET 569 ldr w1, =DCFG_DEVDISR1_SEC 570 str w1, [x2, x0] 571 ldr x0, =DCFG_DEVDISR3_OFFSET 572 ldr w1, =DCFG_DEVDISR3_QBMAIN 573 str w1, [x2, x0] 574 ldr x0, =DCFG_DEVDISR4_OFFSET 575 ldr w1, =DCFG_DEVDISR4_SPI_QSPI 576 str w1, [x2, x0] 577 578 /* set TPMWAKEMR0 */ 579 ldr x0, =TPMWAKEMR0_ADDR 580 mov w1, #0x1 581 str w1, [x0] 582 583 /* disable icache, dcache, mmu @ EL1 */ 584 mov x1, #SCTLR_I_C_M_MASK 585 mrs x0, sctlr_el1 586 bic x0, x0, x1 587 msr sctlr_el1, x0 588 589 /* disable L2 prefetches */ 590 mrs x0, CORTEX_A72_ECTLR_EL1 591 bic x1, x1, #CPUECTLR_TIMER_MASK 592 orr x0, x0, #CPUECTLR_SMPEN_EN 593 orr x0, x0, #CPUECTLR_TIMER_8TICKS 594 msr CORTEX_A72_ECTLR_EL1, x0 595 isb 596 597 /* disable CCN snoop domain */ 598 mov x1, #NXP_CCN_HN_F_0_ADDR 599 ldr x0, =CCN_HN_F_SNP_DMN_CTL_MASK 600 str x0, [x1, #CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET] 6013: 602 ldr w2, [x1, #CCN_HN_F_SNP_DMN_CTL_OFFSET] 603 cmp w2, #0x2 604 b.ne 3b 605 606 mov x3, #NXP_PMU_ADDR 607 6084: 609 ldr w1, [x3, #PMU_PCPW20SR_OFFSET] 610 cmp w1, #PMU_IDLE_CORE_MASK 611 b.ne 4b 612 613 mov w1, #PMU_IDLE_CLUSTER_MASK 614 str w1, [x3, #PMU_CLAINACTSETR_OFFSET] 615 6161: 617 ldr w1, [x3, #PMU_PCPW20SR_OFFSET] 618 cmp w1, #PMU_IDLE_CORE_MASK 619 b.ne 1b 620 621 mov w1, #PMU_FLUSH_CLUSTER_MASK 622 str w1, [x3, #PMU_CLL2FLUSHSETR_OFFSET] 623 6242: 625 ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET] 626 cmp w1, #PMU_FLUSH_CLUSTER_MASK 627 b.ne 2b 628 629 mov w1, #PMU_FLUSH_CLUSTER_MASK 630 str w1, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET] 631 632 mov w1, #PMU_FLUSH_CLUSTER_MASK 633 str w1, [x3, #PMU_CLSINACTSETR_OFFSET] 634 635 mov x2, #DAIF_SET_MASK 636 mrs x1, spsr_el1 637 orr x1, x1, x2 638 msr spsr_el1, x1 639 640 mrs x1, spsr_el2 641 orr x1, x1, x2 642 msr spsr_el2, x1 643 644 /* force the debug interface to be quiescent */ 645 mrs x0, osdlr_el1 646 orr x0, x0, #0x1 647 msr osdlr_el1, x0 648 649 /* invalidate all TLB entries at all 3 exception levels */ 650 tlbi alle1 651 tlbi alle2 652 tlbi alle3 653 654 /* x3 = pmu base addr */ 655 656 /* request lpm20 */ 657 ldr x0, =PMU_POWMGTCSR_OFFSET 658 ldr w1, =PMU_POWMGTCSR_VAL 659 str w1, [x3, x0] 660 6615: 662 wfe 663 b.eq 5b 664endfunc _soc_sys_off 665 666 667/* Part of CPU_SUSPEND 668 * Function puts the calling core into standby state 669 * in: x0 = core mask lsb 670 * out: none 671 * uses x0 672 */ 673func _soc_core_entr_stdby 674 675 dsb sy 676 isb 677 wfi 678 679 ret 680endfunc _soc_core_entr_stdby 681 682 683/* Part of CPU_SUSPEND 684 * Function performs SoC-specific programming prior to standby 685 * in: x0 = core mask lsb 686 * out: none 687 * uses x0, x1 688 */ 689func _soc_core_prep_stdby 690 691 /* clear CORTEX_A72_ECTLR_EL1[2:0] */ 692 mrs x1, CORTEX_A72_ECTLR_EL1 693 bic x1, x1, #CPUECTLR_TIMER_MASK 694 msr CORTEX_A72_ECTLR_EL1, x1 695 696 ret 697endfunc _soc_core_prep_stdby 698 699 700/* Part of CPU_SUSPEND 701 * Function performs any SoC-specific cleanup after standby state 702 * in: x0 = core mask lsb 703 * out: none 704 * uses none 705 */ 706func _soc_core_exit_stdby 707 708 ret 709endfunc _soc_core_exit_stdby 710 711 712/* Part of CPU_SUSPEND 713 * Function performs SoC-specific programming prior to power-down 714 * in: x0 = core mask lsb 715 * out: none 716 * uses none 717 */ 718func _soc_core_prep_pwrdn 719 720 /* make sure system counter is enabled */ 721 ldr x2, =NXP_TIMER_ADDR 722 ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 723 tst w0, #SYS_COUNTER_CNTCR_EN 724 b.ne 1f 725 orr w0, w0, #SYS_COUNTER_CNTCR_EN 726 str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 7271: 728 729 /* enable dynamic retention control (CPUECTLR[2:0]) 730 * set the SMPEN bit (CPUECTLR[6]) 731 */ 732 mrs x1, CORTEX_A72_ECTLR_EL1 733 bic x1, x1, #CPUECTLR_RET_MASK 734 orr x1, x1, #CPUECTLR_TIMER_8TICKS 735 orr x1, x1, #CPUECTLR_SMPEN_EN 736 msr CORTEX_A72_ECTLR_EL1, x1 737 738 isb 739 ret 740endfunc _soc_core_prep_pwrdn 741 742 743/* Part of CPU_SUSPEND 744 * Function puts the calling core into a power-down state 745 * in: x0 = core mask lsb 746 * out: none 747 * uses x0 748 */ 749func _soc_core_entr_pwrdn 750 751 /* X0 = core mask lsb */ 752 753 dsb sy 754 isb 755 wfi 756 757 ret 758endfunc _soc_core_entr_pwrdn 759 760 761/* Part of CPU_SUSPEND 762 * Function performs any SoC-specific cleanup after power-down state 763 * in: x0 = core mask lsb 764 * out: none 765 * uses none 766 */ 767func _soc_core_exit_pwrdn 768 769 ret 770endfunc _soc_core_exit_pwrdn 771 772 773/* Part of CPU_SUSPEND 774 * Function performs SoC-specific programming prior to standby 775 * in: x0 = core mask lsb 776 * out: none 777 * uses x0, x1 778 */ 779func _soc_clstr_prep_stdby 780 781 /* clear CORTEX_A72_ECTLR_EL1[2:0] */ 782 mrs x1, CORTEX_A72_ECTLR_EL1 783 bic x1, x1, #CPUECTLR_TIMER_MASK 784 msr CORTEX_A72_ECTLR_EL1, x1 785 786 ret 787endfunc _soc_clstr_prep_stdby 788 789 790/* Part of CPU_SUSPEND 791 * Function performs any SoC-specific cleanup after standby state 792 * in: x0 = core mask lsb 793 * out: none 794 * uses none 795 */ 796func _soc_clstr_exit_stdby 797 798 ret 799endfunc _soc_clstr_exit_stdby 800 801 802/* Part of CPU_SUSPEND 803 * Function performs SoC-specific programming prior to power-down 804 * in: x0 = core mask lsb 805 * out: none 806 * uses none 807 */ 808func _soc_clstr_prep_pwrdn 809 810 /* make sure system counter is enabled */ 811 ldr x2, =NXP_TIMER_ADDR 812 ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 813 tst w0, #SYS_COUNTER_CNTCR_EN 814 b.ne 1f 815 orr w0, w0, #SYS_COUNTER_CNTCR_EN 816 str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 8171: 818 819 /* enable dynamic retention control (CPUECTLR[2:0]) 820 * set the SMPEN bit (CPUECTLR[6]) 821 */ 822 mrs x1, CORTEX_A72_ECTLR_EL1 823 bic x1, x1, #CPUECTLR_RET_MASK 824 orr x1, x1, #CPUECTLR_TIMER_8TICKS 825 orr x1, x1, #CPUECTLR_SMPEN_EN 826 msr CORTEX_A72_ECTLR_EL1, x1 827 828 isb 829 ret 830endfunc _soc_clstr_prep_pwrdn 831 832 833/* Part of CPU_SUSPEND 834 * Function performs any SoC-specific cleanup after power-down state 835 * in: x0 = core mask lsb 836 * out: none 837 * uses none 838 */ 839func _soc_clstr_exit_pwrdn 840 841 ret 842endfunc _soc_clstr_exit_pwrdn 843 844 845/* Part of CPU_SUSPEND 846 * Function performs SoC-specific programming prior to standby 847 * in: x0 = core mask lsb 848 * out: none 849 * uses x0, x1 850 */ 851func _soc_sys_prep_stdby 852 853 /* clear CORTEX_A72_ECTLR_EL1[2:0] */ 854 mrs x1, CORTEX_A72_ECTLR_EL1 855 bic x1, x1, #CPUECTLR_TIMER_MASK 856 msr CORTEX_A72_ECTLR_EL1, x1 857 ret 858endfunc _soc_sys_prep_stdby 859 860 861/* Part of CPU_SUSPEND 862 * Function performs any SoC-specific cleanup after standby state 863 * in: x0 = core mask lsb 864 * out: none 865 * uses none 866 */ 867func _soc_sys_exit_stdby 868 869 ret 870endfunc _soc_sys_exit_stdby 871 872 873/* Part of CPU_SUSPEND 874 * Function performs SoC-specific programming prior to 875 * suspend-to-power-down 876 * in: x0 = core mask lsb 877 * out: none 878 * uses x0, x1 879 */ 880func _soc_sys_prep_pwrdn 881 882 mrs x1, CORTEX_A72_ECTLR_EL1 883 /* make sure the smp bit is set */ 884 orr x1, x1, #CPUECTLR_SMPEN_MASK 885 /* set the retention control */ 886 orr x1, x1, #CPUECTLR_RET_8CLK 887 /* disable tablewalk prefetch */ 888 orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH 889 msr CORTEX_A72_ECTLR_EL1, x1 890 isb 891 892 ret 893endfunc _soc_sys_prep_pwrdn 894 895 896/* Part of CPU_SUSPEND 897 * Function puts the calling core, and potentially the soc, into a 898 * low-power state 899 * in: x0 = core mask lsb 900 * out: x0 = 0, success 901 * x0 < 0, failure 902 * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, 903 * x15, x16, x17, x18, x19, x20, x21, x28 904 */ 905func _soc_sys_pwrdn_wfi 906 mov x28, x30 907 908 /* disable cluster snooping in the CCN-508 */ 909 ldr x1, =NXP_CCN_HN_F_0_ADDR 910 ldr x7, [x1, #CCN_HN_F_SNP_DMN_CTL_OFFSET] 911 mov x6, #CCN_HNF_NODE_COUNT 9121: 913 str x7, [x1, #CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET] 914 sub x6, x6, #1 915 add x1, x1, #CCN_HNF_OFFSET 916 cbnz x6, 1b 917 918 /* x0 = core mask 919 * x7 = hnf sdcr 920 */ 921 922 ldr x1, =NXP_PMU_CCSR_ADDR 923 ldr x2, =NXP_PMU_DCSR_ADDR 924 925 /* enable the stop-request-override */ 926 mov x3, #PMU_POWMGTDCR0_OFFSET 927 mov x4, #POWMGTDCR_STP_OV_EN 928 str w4, [x2, x3] 929 930 /* x0 = core mask 931 * x1 = NXP_PMU_CCSR_ADDR 932 * x2 = NXP_PMU_DCSR_ADDR 933 * x7 = hnf sdcr 934 */ 935 936 /* disable prefetching in the A72 core */ 937 mrs x8, CORTEX_A72_CPUACTLR_EL1 938 tst x8, #CPUACTLR_DIS_LS_HW_PRE 939 b.ne 2f 940 dsb sy 941 isb 942 /* disable data prefetch */ 943 orr x16, x8, #CPUACTLR_DIS_LS_HW_PRE 944 /* disable tlb prefetch */ 945 orr x16, x16, #CPUACTLR_DIS_L2_TLB_PRE 946 msr CORTEX_A72_CPUACTLR_EL1, x16 947 isb 948 949 /* x0 = core mask 950 * x1 = NXP_PMU_CCSR_ADDR 951 * x2 = NXP_PMU_DCSR_ADDR 952 * x7 = hnf sdcr 953 * x8 = cpuactlr 954 */ 955 9562: 957 /* save hnf-sdcr and cpuactlr to stack */ 958 stp x7, x8, [sp, #-16]! 959 960 /* x0 = core mask 961 * x1 = NXP_PMU_CCSR_ADDR 962 * x2 = NXP_PMU_DCSR_ADDR 963 */ 964 965 /* save the IPSTPCRn registers to stack */ 966 mov x15, #PMU_IPSTPCR0_OFFSET 967 ldr w9, [x1, x15] 968 mov x16, #PMU_IPSTPCR1_OFFSET 969 ldr w10, [x1, x16] 970 mov x17, #PMU_IPSTPCR2_OFFSET 971 ldr w11, [x1, x17] 972 mov x18, #PMU_IPSTPCR3_OFFSET 973 ldr w12, [x1, x18] 974 mov x19, #PMU_IPSTPCR4_OFFSET 975 ldr w13, [x1, x19] 976 mov x20, #PMU_IPSTPCR5_OFFSET 977 ldr w14, [x1, x20] 978 979 stp x9, x10, [sp, #-16]! 980 stp x11, x12, [sp, #-16]! 981 stp x13, x14, [sp, #-16]! 982 983 /* x0 = core mask 984 * x1 = NXP_PMU_CCSR_ADDR 985 * x2 = NXP_PMU_DCSR_ADDR 986 * x15 = PMU_IPSTPCR0_OFFSET 987 * x16 = PMU_IPSTPCR1_OFFSET 988 * x17 = PMU_IPSTPCR2_OFFSET 989 * x18 = PMU_IPSTPCR3_OFFSET 990 * x19 = PMU_IPSTPCR4_OFFSET 991 * x20 = PMU_IPSTPCR5_OFFSET 992 */ 993 994 /* load the full clock mask for IPSTPCR0 */ 995 ldr x3, =DEVDISR1_MASK 996 /* get the exclusions */ 997 mov x21, #PMU_IPPDEXPCR0_OFFSET 998 ldr w4, [x1, x21] 999 /* apply the exclusions to the mask */ 1000 bic w7, w3, w4 1001 /* stop the clocks in IPSTPCR0 */ 1002 str w7, [x1, x15] 1003 1004 /* use same procedure for IPSTPCR1-IPSTPCR5 */ 1005 1006 /* stop the clocks in IPSTPCR1 */ 1007 ldr x5, =DEVDISR2_MASK 1008 mov x21, #PMU_IPPDEXPCR1_OFFSET 1009 ldr w6, [x1, x21] 1010 bic w8, w5, w6 1011 str w8, [x1, x16] 1012 1013 /* stop the clocks in IPSTPCR2 */ 1014 ldr x3, =DEVDISR3_MASK 1015 mov x21, #PMU_IPPDEXPCR2_OFFSET 1016 ldr w4, [x1, x21] 1017 bic w9, w3, w4 1018 str w9, [x1, x17] 1019 1020 /* stop the clocks in IPSTPCR3 */ 1021 ldr x5, =DEVDISR4_MASK 1022 mov x21, #PMU_IPPDEXPCR3_OFFSET 1023 ldr w6, [x1, x21] 1024 bic w10, w5, w6 1025 str w10, [x1, x18] 1026 1027 /* stop the clocks in IPSTPCR4 1028 * - exclude the ddr clocks as we are currently executing 1029 * out of *some* memory, might be ddr 1030 * - exclude the OCRAM clk so that we retain any code/data in 1031 * OCRAM 1032 * - may need to exclude the debug clock if we are testing 1033 */ 1034 ldr x3, =DEVDISR5_MASK 1035 mov w6, #DEVDISR5_MASK_ALL_MEM 1036 bic w3, w3, w6 1037 1038 mov w5, #POLICY_DEBUG_ENABLE 1039 cbz w5, 3f 1040 mov w6, #DEVDISR5_MASK_DBG 1041 bic w3, w3, w6 10423: 1043 mov x21, #PMU_IPPDEXPCR4_OFFSET 1044 ldr w4, [x1, x21] 1045 bic w11, w3, w4 1046 str w11, [x1, x19] 1047 1048 /* stop the clocks in IPSTPCR5 */ 1049 ldr x5, =DEVDISR6_MASK 1050 mov x21, #PMU_IPPDEXPCR5_OFFSET 1051 ldr w6, [x1, x21] 1052 bic w12, w5, w6 1053 str w12, [x1, x20] 1054 1055 /* x0 = core mask 1056 * x1 = NXP_PMU_CCSR_ADDR 1057 * x2 = NXP_PMU_DCSR_ADDR 1058 * x7 = IPSTPCR0 1059 * x8 = IPSTPCR1 1060 * x9 = IPSTPCR2 1061 * x10 = IPSTPCR3 1062 * x11 = IPSTPCR4 1063 * x12 = IPSTPCR5 1064 */ 1065 1066 /* poll until the clocks are stopped in IPSTPACKSR0 */ 1067 mov w4, #CLOCK_RETRY_CNT 1068 mov x21, #PMU_IPSTPACKSR0_OFFSET 10694: 1070 ldr w5, [x1, x21] 1071 cmp w5, w7 1072 b.eq 5f 1073 sub w4, w4, #1 1074 cbnz w4, 4b 1075 1076 /* poll until the clocks are stopped in IPSTPACKSR1 */ 10775: 1078 mov w4, #CLOCK_RETRY_CNT 1079 mov x21, #PMU_IPSTPACKSR1_OFFSET 10806: 1081 ldr w5, [x1, x21] 1082 cmp w5, w8 1083 b.eq 7f 1084 sub w4, w4, #1 1085 cbnz w4, 6b 1086 1087 /* poll until the clocks are stopped in IPSTPACKSR2 */ 10887: 1089 mov w4, #CLOCK_RETRY_CNT 1090 mov x21, #PMU_IPSTPACKSR2_OFFSET 10918: 1092 ldr w5, [x1, x21] 1093 cmp w5, w9 1094 b.eq 9f 1095 sub w4, w4, #1 1096 cbnz w4, 8b 1097 1098 /* poll until the clocks are stopped in IPSTPACKSR3 */ 10999: 1100 mov w4, #CLOCK_RETRY_CNT 1101 mov x21, #PMU_IPSTPACKSR3_OFFSET 110210: 1103 ldr w5, [x1, x21] 1104 cmp w5, w10 1105 b.eq 11f 1106 sub w4, w4, #1 1107 cbnz w4, 10b 1108 1109 /* poll until the clocks are stopped in IPSTPACKSR4 */ 111011: 1111 mov w4, #CLOCK_RETRY_CNT 1112 mov x21, #PMU_IPSTPACKSR4_OFFSET 111312: 1114 ldr w5, [x1, x21] 1115 cmp w5, w11 1116 b.eq 13f 1117 sub w4, w4, #1 1118 cbnz w4, 12b 1119 1120 /* poll until the clocks are stopped in IPSTPACKSR5 */ 112113: 1122 mov w4, #CLOCK_RETRY_CNT 1123 mov x21, #PMU_IPSTPACKSR5_OFFSET 112414: 1125 ldr w5, [x1, x21] 1126 cmp w5, w12 1127 b.eq 15f 1128 sub w4, w4, #1 1129 cbnz w4, 14b 1130 1131 /* x0 = core mask 1132 * x1 = NXP_PMU_CCSR_ADDR 1133 * x2 = NXP_PMU_DCSR_ADDR 1134 * x7 = IPSTPCR0 1135 * x8 = IPSTPCR1 1136 * x9 = IPSTPCR2 1137 * x10 = IPSTPCR3 1138 * x11 = IPSTPCR4 1139 * x12 = IPSTPCR5 1140 */ 1141 114215: 1143 mov x3, #NXP_DCFG_ADDR 1144 1145 /* save the devdisr registers to stack */ 1146 ldr w13, [x3, #DCFG_DEVDISR1_OFFSET] 1147 ldr w14, [x3, #DCFG_DEVDISR2_OFFSET] 1148 ldr w15, [x3, #DCFG_DEVDISR3_OFFSET] 1149 ldr w16, [x3, #DCFG_DEVDISR4_OFFSET] 1150 ldr w17, [x3, #DCFG_DEVDISR5_OFFSET] 1151 ldr w18, [x3, #DCFG_DEVDISR6_OFFSET] 1152 1153 stp x13, x14, [sp, #-16]! 1154 stp x15, x16, [sp, #-16]! 1155 stp x17, x18, [sp, #-16]! 1156 1157 /* power down the IP in DEVDISR1 - corresponds to IPSTPCR0 */ 1158 str w7, [x3, #DCFG_DEVDISR1_OFFSET] 1159 1160 /* power down the IP in DEVDISR2 - corresponds to IPSTPCR1 */ 1161 str w8, [x3, #DCFG_DEVDISR2_OFFSET] 1162 1163 /* power down the IP in DEVDISR3 - corresponds to IPSTPCR2 */ 1164 str w9, [x3, #DCFG_DEVDISR3_OFFSET] 1165 1166 /* power down the IP in DEVDISR4 - corresponds to IPSTPCR3 */ 1167 str w10, [x3, #DCFG_DEVDISR4_OFFSET] 1168 1169 /* power down the IP in DEVDISR5 - corresponds to IPSTPCR4 */ 1170 str w11, [x3, #DCFG_DEVDISR5_OFFSET] 1171 1172 /* power down the IP in DEVDISR6 - corresponds to IPSTPCR5 */ 1173 str w12, [x3, #DCFG_DEVDISR6_OFFSET] 1174 1175 /* setup register values for the cache-only sequence */ 1176 mov x4, #NXP_DDR_ADDR 1177 mov x5, #NXP_DDR2_ADDR 1178 mov x6, x11 1179 mov x7, x17 1180 ldr x12, =PMU_CLAINACTSETR_OFFSET 1181 ldr x13, =PMU_CLSINACTSETR_OFFSET 1182 ldr x14, =PMU_CLAINACTCLRR_OFFSET 1183 ldr x15, =PMU_CLSINACTCLRR_OFFSET 1184 1185 /* x0 = core mask 1186 * x1 = NXP_PMU_CCSR_ADDR 1187 * x2 = NXP_PMU_DCSR_ADDR 1188 * x3 = NXP_DCFG_ADDR 1189 * x4 = NXP_DDR_ADDR 1190 * x5 = NXP_DDR2_ADDR 1191 * w6 = IPSTPCR4 1192 * w7 = DEVDISR5 1193 * x12 = PMU_CLAINACTSETR_OFFSET 1194 * x13 = PMU_CLSINACTSETR_OFFSET 1195 * x14 = PMU_CLAINACTCLRR_OFFSET 1196 * x15 = PMU_CLSINACTCLRR_OFFSET 1197 */ 1198 1199 mov x8, #POLICY_DEBUG_ENABLE 1200 cbnz x8, 29f 1201 /* force the debug interface to be quiescent */ 1202 mrs x9, OSDLR_EL1 1203 orr x9, x9, #0x1 1204 msr OSDLR_EL1, x9 1205 1206 /* enter the cache-only sequence */ 120729: 1208 bl final_pwrdown 1209 1210 /* when we are here, the core has come out of wfi and the 1211 * ddr is back up 1212 */ 1213 1214 mov x8, #POLICY_DEBUG_ENABLE 1215 cbnz x8, 30f 1216 /* restart the debug interface */ 1217 mrs x9, OSDLR_EL1 1218 mov x10, #1 1219 bic x9, x9, x10 1220 msr OSDLR_EL1, x9 1221 1222 /* get saved DEVDISR regs off stack */ 122330: 1224 ldp x17, x18, [sp], #16 1225 ldp x15, x16, [sp], #16 1226 ldp x13, x14, [sp], #16 1227 /* restore DEVDISR regs */ 1228 str w18, [x3, #DCFG_DEVDISR6_OFFSET] 1229 str w17, [x3, #DCFG_DEVDISR5_OFFSET] 1230 str w16, [x3, #DCFG_DEVDISR4_OFFSET] 1231 str w15, [x3, #DCFG_DEVDISR3_OFFSET] 1232 str w14, [x3, #DCFG_DEVDISR2_OFFSET] 1233 str w13, [x3, #DCFG_DEVDISR1_OFFSET] 1234 isb 1235 1236 /* get saved IPSTPCRn regs off stack */ 1237 ldp x13, x14, [sp], #16 1238 ldp x11, x12, [sp], #16 1239 ldp x9, x10, [sp], #16 1240 1241 /* restore IPSTPCRn regs */ 1242 mov x15, #PMU_IPSTPCR5_OFFSET 1243 str w14, [x1, x15] 1244 mov x16, #PMU_IPSTPCR4_OFFSET 1245 str w13, [x1, x16] 1246 mov x17, #PMU_IPSTPCR3_OFFSET 1247 str w12, [x1, x17] 1248 mov x18, #PMU_IPSTPCR2_OFFSET 1249 str w11, [x1, x18] 1250 mov x19, #PMU_IPSTPCR1_OFFSET 1251 str w10, [x1, x19] 1252 mov x20, #PMU_IPSTPCR0_OFFSET 1253 str w9, [x1, x20] 1254 isb 1255 1256 /* poll on IPSTPACKCRn regs til IP clocks are restarted */ 1257 mov w4, #CLOCK_RETRY_CNT 1258 mov x15, #PMU_IPSTPACKSR5_OFFSET 125916: 1260 ldr w5, [x1, x15] 1261 and w5, w5, w14 1262 cbz w5, 17f 1263 sub w4, w4, #1 1264 cbnz w4, 16b 1265 126617: 1267 mov w4, #CLOCK_RETRY_CNT 1268 mov x15, #PMU_IPSTPACKSR4_OFFSET 126918: 1270 ldr w5, [x1, x15] 1271 and w5, w5, w13 1272 cbz w5, 19f 1273 sub w4, w4, #1 1274 cbnz w4, 18b 1275 127619: 1277 mov w4, #CLOCK_RETRY_CNT 1278 mov x15, #PMU_IPSTPACKSR3_OFFSET 127920: 1280 ldr w5, [x1, x15] 1281 and w5, w5, w12 1282 cbz w5, 21f 1283 sub w4, w4, #1 1284 cbnz w4, 20b 1285 128621: 1287 mov w4, #CLOCK_RETRY_CNT 1288 mov x15, #PMU_IPSTPACKSR2_OFFSET 128922: 1290 ldr w5, [x1, x15] 1291 and w5, w5, w11 1292 cbz w5, 23f 1293 sub w4, w4, #1 1294 cbnz w4, 22b 1295 129623: 1297 mov w4, #CLOCK_RETRY_CNT 1298 mov x15, #PMU_IPSTPACKSR1_OFFSET 129924: 1300 ldr w5, [x1, x15] 1301 and w5, w5, w10 1302 cbz w5, 25f 1303 sub w4, w4, #1 1304 cbnz w4, 24b 1305 130625: 1307 mov w4, #CLOCK_RETRY_CNT 1308 mov x15, #PMU_IPSTPACKSR0_OFFSET 130926: 1310 ldr w5, [x1, x15] 1311 and w5, w5, w9 1312 cbz w5, 27f 1313 sub w4, w4, #1 1314 cbnz w4, 26b 1315 131627: 1317 /* disable the stop-request-override */ 1318 mov x8, #PMU_POWMGTDCR0_OFFSET 1319 mov w9, #POWMGTDCR_STP_OV_EN 1320 str w9, [x2, x8] 1321 isb 1322 1323 /* get hnf-sdcr and cpuactlr off stack */ 1324 ldp x7, x8, [sp], #16 1325 1326 /* restore cpuactlr */ 1327 msr CORTEX_A72_CPUACTLR_EL1, x8 1328 isb 1329 1330 /* restore snooping in the hnf nodes */ 1331 ldr x9, =NXP_CCN_HN_F_0_ADDR 1332 mov x6, #CCN_HNF_NODE_COUNT 133328: 1334 str x7, [x9, #CCN_HN_F_SNP_DMN_CTL_SET_OFFSET] 1335 sub x6, x6, #1 1336 add x9, x9, #CCN_HNF_OFFSET 1337 cbnz x6, 28b 1338 isb 1339 1340 mov x30, x28 1341 ret 1342endfunc _soc_sys_pwrdn_wfi 1343 1344 1345/* Part of CPU_SUSPEND 1346 * Function performs any SoC-specific cleanup after power-down 1347 * in: x0 = core mask lsb 1348 * out: none 1349 * uses x0, 1350 */ 1351func _soc_sys_exit_pwrdn 1352 1353 mrs x1, CORTEX_A72_ECTLR_EL1 1354 /* make sure the smp bit is set */ 1355 orr x1, x1, #CPUECTLR_SMPEN_MASK 1356 /* clr the retention control */ 1357 mov x2, #CPUECTLR_RET_8CLK 1358 bic x1, x1, x2 1359 /* enable tablewalk prefetch */ 1360 mov x2, #CPUECTLR_DISABLE_TWALK_PREFETCH 1361 bic x1, x1, x2 1362 msr CORTEX_A72_ECTLR_EL1, x1 1363 isb 1364 1365 ret 1366endfunc _soc_sys_exit_pwrdn 1367 1368 1369/* Function will pwrdown ddr and the final core - it will do this 1370 * by loading itself into the icache and then executing from there 1371 * in: 1372 * x0 = core mask 1373 * x1 = NXP_PMU_CCSR_ADDR 1374 * x2 = NXP_PMU_DCSR_ADDR 1375 * x3 = NXP_DCFG_ADDR 1376 * x4 = NXP_DDR_ADDR 1377 * x5 = NXP_DDR2_ADDR 1378 * w6 = IPSTPCR4 1379 * w7 = DEVDISR5 1380 * x12 = PMU_CLAINACTSETR_OFFSET 1381 * x13 = PMU_CLSINACTSETR_OFFSET 1382 * x14 = PMU_CLAINACTCLRR_OFFSET 1383 * x15 = PMU_CLSINACTCLRR_OFFSET 1384 * out: none 1385 * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x13, x14, x15, x16, 1386 * x17, x18 1387 */ 1388 1389/* 4Kb aligned */ 1390.align 12 1391func final_pwrdown 1392 1393 mov x0, xzr 1394 b touch_line_0 1395start_line_0: 1396 mov x0, #1 1397 /* put ddr controller 1 into self-refresh */ 1398 ldr w8, [x4, #DDR_CFG_2_OFFSET] 1399 orr w8, w8, #CFG_2_FORCE_REFRESH 1400 str w8, [x4, #DDR_CFG_2_OFFSET] 1401 1402 /* put ddr controller 2 into self-refresh */ 1403 ldr w8, [x5, #DDR_CFG_2_OFFSET] 1404 orr w8, w8, #CFG_2_FORCE_REFRESH 1405 str w8, [x5, #DDR_CFG_2_OFFSET] 1406 1407 /* stop the clocks in both ddr controllers */ 1408 mov w10, #DEVDISR5_MASK_DDR 1409 mov x16, #PMU_IPSTPCR4_OFFSET 1410 orr w9, w6, w10 1411 str w9, [x1, x16] 1412 isb 1413 1414 mov x17, #PMU_IPSTPACKSR4_OFFSET 1415touch_line_0: 1416 cbz x0, touch_line_1 1417 1418start_line_1: 1419 /* poll IPSTPACKSR4 until 1420 * ddr controller clocks are stopped. 1421 */ 14221: 1423 ldr w8, [x1, x17] 1424 and w8, w8, w10 1425 cmp w8, w10 1426 b.ne 1b 1427 1428 /* shut down power to the ddr controllers */ 1429 orr w9, w7, #DEVDISR5_MASK_DDR 1430 str w9, [x3, #DCFG_DEVDISR5_OFFSET] 1431 1432 /* disable cluster acp ports */ 1433 mov w8, #CLAINACT_DISABLE_ACP 1434 str w8, [x1, x12] 1435 1436 /* disable skyros ports */ 1437 mov w9, #CLSINACT_DISABLE_SKY 1438 str w9, [x1, x13] 1439 isb 1440 1441touch_line_1: 1442 cbz x0, touch_line_2 1443 1444start_line_2: 1445 isb 14463: 1447 wfi 1448 1449 /* if we are here then we are awake 1450 * - bring this device back up 1451 */ 1452 1453 /* enable skyros ports */ 1454 mov w9, #CLSINACT_DISABLE_SKY 1455 str w9, [x1, x15] 1456 1457 /* enable acp ports */ 1458 mov w8, #CLAINACT_DISABLE_ACP 1459 str w8, [x1, x14] 1460 isb 1461 1462 /* bring up the ddr controllers */ 1463 str w7, [x3, #DCFG_DEVDISR5_OFFSET] 1464 isb 1465 str w6, [x1, x16] 1466 isb 1467 1468 nop 1469touch_line_2: 1470 cbz x0, touch_line_3 1471 1472start_line_3: 1473 /* poll IPSTPACKSR4 until 1474 * ddr controller clocks are running 1475 */ 1476 mov w10, #DEVDISR5_MASK_DDR 14772: 1478 ldr w8, [x1, x17] 1479 and w8, w8, w10 1480 cbnz w8, 2b 1481 1482 /* take ddr controller 2 out of self-refresh */ 1483 mov w8, #CFG_2_FORCE_REFRESH 1484 ldr w9, [x5, #DDR_CFG_2_OFFSET] 1485 bic w9, w9, w8 1486 str w9, [x5, #DDR_CFG_2_OFFSET] 1487 1488 /* take ddr controller 1 out of self-refresh */ 1489 ldr w9, [x4, #DDR_CFG_2_OFFSET] 1490 bic w9, w9, w8 1491 str w9, [x4, #DDR_CFG_2_OFFSET] 1492 isb 1493 1494 nop 1495 nop 1496 nop 1497touch_line_3: 1498 cbz x0, start_line_0 1499 1500 /* execute here after ddr is back up */ 1501 1502 ret 1503endfunc final_pwrdown 1504 1505/* Function returns CLUSTER_3_NORMAL if the cores of cluster 3 are 1506 * to be handled normally, and it returns CLUSTER_3_IN_RESET if the cores 1507 * are to be held in reset 1508 * in: none 1509 * out: x0 = #CLUSTER_3_NORMAL, cluster 3 treated normal 1510 * x0 = #CLUSTER_3_IN_RESET, cluster 3 cores held in reset 1511 * uses x0, x1, x2 1512 */ 1513func cluster3InReset 1514 1515 /* default return is treat cores normal */ 1516 mov x0, #CLUSTER_3_NORMAL 1517 1518 /* read RCW_SR27 register */ 1519 mov x1, #NXP_DCFG_ADDR 1520 ldr w2, [x1, #RCW_SR27_OFFSET] 1521 1522 /* test the cluster 3 bit */ 1523 tst w2, #CLUSTER_3_RCW_BIT 1524 b.eq 1f 1525 1526 /* if we are here, then the bit was set */ 1527 mov x0, #CLUSTER_3_IN_RESET 15281: 1529 ret 1530endfunc cluster3InReset 1531 1532 1533/* Function checks to see if cores which are to be disabled have been 1534 * released from reset - if not, it releases them 1535 * Note: there may be special handling of cluster 3 cores depending upon the 1536 * sys clk frequency 1537 * in: none 1538 * out: none 1539 * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 1540 */ 1541func release_disabled 1542 mov x9, x30 1543 1544 /* check if we need to keep cluster 3 cores in reset */ 1545 bl cluster3InReset /* 0-2 */ 1546 mov x8, x0 1547 1548 /* x8 = cluster 3 handling */ 1549 1550 /* read COREDISABLESR */ 1551 mov x0, #NXP_DCFG_ADDR 1552 ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET] 1553 cmp x8, #CLUSTER_3_IN_RESET 1554 b.ne 4f 1555 1556 /* the cluster 3 cores are to be held in reset, so remove 1557 * them from the disable mask 1558 */ 1559 bic x4, x4, #CLUSTER_3_CORES_MASK 15604: 1561 /* get the number of cpus on this device */ 1562 mov x6, #PLATFORM_CORE_COUNT 1563 1564 mov x0, #NXP_RESET_ADDR 1565 ldr w5, [x0, #BRR_OFFSET] 1566 1567 /* load the core mask for the first core */ 1568 mov x7, #1 1569 1570 /* x4 = COREDISABLESR 1571 * x5 = BRR 1572 * x6 = loop count 1573 * x7 = core mask bit 1574 */ 15752: 1576 /* check if the core is to be disabled */ 1577 tst x4, x7 1578 b.eq 1f 1579 1580 /* see if disabled cores have already been released from reset */ 1581 tst x5, x7 1582 b.ne 5f 1583 1584 /* if core has not been released, then release it (0-3) */ 1585 mov x0, x7 1586 bl _soc_core_release 1587 1588 /* record the core state in the data area (0-3) */ 1589 mov x0, x7 1590 mov x1, #CORE_STATE_DATA 1591 mov x2, #CORE_DISABLED 1592 bl _setCoreData 1593 15941: 1595 /* see if this is a cluster 3 core */ 1596 mov x3, #CLUSTER_3_CORES_MASK 1597 tst x3, x7 1598 b.eq 5f 1599 1600 /* this is a cluster 3 core - see if it needs to be held in reset */ 1601 cmp x8, #CLUSTER_3_IN_RESET 1602 b.ne 5f 1603 1604 /* record the core state as disabled in the data area (0-3) */ 1605 mov x0, x7 1606 mov x1, #CORE_STATE_DATA 1607 mov x2, #CORE_DISABLED 1608 bl _setCoreData 1609 16105: 1611 /* decrement the counter */ 1612 subs x6, x6, #1 1613 b.le 3f 1614 1615 /* shift the core mask to the next core */ 1616 lsl x7, x7, #1 1617 /* continue */ 1618 b 2b 16193: 1620 cmp x8, #CLUSTER_3_IN_RESET 1621 b.ne 6f 1622 1623 /* we need to hold the cluster 3 cores in reset, 1624 * so mark them in the COREDISR and COREDISABLEDSR registers as 1625 * "disabled", and the rest of the sw stack will leave them alone 1626 * thinking that they have been disabled 1627 */ 1628 mov x0, #NXP_DCFG_ADDR 1629 ldr w1, [x0, #DCFG_COREDISR_OFFSET] 1630 orr w1, w1, #CLUSTER_3_CORES_MASK 1631 str w1, [x0, #DCFG_COREDISR_OFFSET] 1632 1633 ldr w2, [x0, #DCFG_COREDISABLEDSR_OFFSET] 1634 orr w2, w2, #CLUSTER_3_CORES_MASK 1635 str w2, [x0, #DCFG_COREDISABLEDSR_OFFSET] 1636 dsb sy 1637 isb 1638 1639#if (PSCI_TEST) 1640 /* x0 = NXP_DCFG_ADDR : read COREDISABLESR */ 1641 ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET] 1642 /* read COREDISR */ 1643 ldr w3, [x0, #DCFG_COREDISR_OFFSET] 1644#endif 1645 16466: 1647 mov x30, x9 1648 ret 1649 1650endfunc release_disabled 1651 1652 1653/* Function setc up the TrustZone Address Space Controller (TZASC) 1654 * in: none 1655 * out: none 1656 * uses x0, x1 1657 */ 1658func init_tzpc 1659 1660 /* set Non Secure access for all devices protected via TZPC */ 1661 1662 /* decode Protection-0 Set Reg */ 1663 ldr x1, =TZPCDECPROT_0_SET_BASE 1664 /* set decode region to NS, Bits[7:0] */ 1665 mov w0, #0xFF 1666 str w0, [x1] 1667 1668 /* decode Protection-1 Set Reg */ 1669 ldr x1, =TZPCDECPROT_1_SET_BASE 1670 /* set decode region to NS, Bits[7:0] */ 1671 mov w0, #0xFF 1672 str w0, [x1] 1673 1674 /* decode Protection-2 Set Reg */ 1675 ldr x1, =TZPCDECPROT_2_SET_BASE 1676 /* set decode region to NS, Bits[7:0] */ 1677 mov w0, #0xFF 1678 str w0, [x1] 1679 1680 /* entire SRAM as NS */ 1681 /* secure RAM region size Reg */ 1682 ldr x1, =TZPC_BASE 1683 /* 0x00000000 = no secure region */ 1684 mov w0, #0x00000000 1685 str w0, [x1] 1686 1687 ret 1688endfunc init_tzpc 1689 1690/* write a register in the DCFG block 1691 * in: x0 = offset 1692 * in: w1 = value to write 1693 * uses x0, x1, x2 1694 */ 1695func _write_reg_dcfg 1696 ldr x2, =NXP_DCFG_ADDR 1697 str w1, [x2, x0] 1698 ret 1699endfunc _write_reg_dcfg 1700 1701 1702/* read a register in the DCFG block 1703 * in: x0 = offset 1704 * out: w0 = value read 1705 * uses x0, x1, x2 1706 */ 1707func _read_reg_dcfg 1708 ldr x2, =NXP_DCFG_ADDR 1709 ldr w1, [x2, x0] 1710 mov w0, w1 1711 ret 1712endfunc _read_reg_dcfg 1713 1714 1715/* Function returns an mpidr value for a core, given a core_mask_lsb 1716 * in: x0 = core mask lsb 1717 * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits 1718 * uses x0, x1 1719 */ 1720func get_mpidr_value 1721 1722 /* convert a core mask to an SoC core number */ 1723 clz w0, w0 1724 mov w1, #31 1725 sub w0, w1, w0 1726 1727 /* get the mpidr core number from the SoC core number */ 1728 mov w1, wzr 1729 tst x0, #1 1730 b.eq 1f 1731 orr w1, w1, #1 1732 17331: 1734 /* extract the cluster number */ 1735 lsr w0, w0, #1 1736 orr w0, w1, w0, lsl #8 1737 1738 ret 1739endfunc get_mpidr_value 1740 1741 1742/* Function returns the redistributor base address for the core specified 1743 * in x1 1744 * in: x0 - core mask lsb of specified core 1745 * out: x0 = redistributor rd base address for specified core 1746 * uses x0, x1, x2 1747 */ 1748func get_gic_rd_base 1749 clz w1, w0 1750 mov w2, #0x20 1751 sub w2, w2, w1 1752 sub w2, w2, #1 1753 1754 ldr x0, =NXP_GICR_ADDR 1755 mov x1, #GIC_RD_OFFSET 1756 1757 /* x2 = core number 1758 * loop counter 1759 */ 17602: 1761 cbz x2, 1f 1762 add x0, x0, x1 1763 sub x2, x2, #1 1764 b 2b 17651: 1766 ret 1767endfunc get_gic_rd_base 1768 1769 1770/* Function returns the redistributor base address for the core specified 1771 * in x1 1772 * in: x0 - core mask lsb of specified core 1773 * out: x0 = redistributor sgi base address for specified core 1774 * uses x0, x1, x2 1775 */ 1776func get_gic_sgi_base 1777 clz w1, w0 1778 mov w2, #0x20 1779 sub w2, w2, w1 1780 sub w2, w2, #1 1781 1782 ldr x0, =NXP_GICR_SGI_ADDR 1783 mov x1, #GIC_SGI_OFFSET 1784 1785 /* loop counter */ 17862: 1787 cbz x2, 1f /* x2 = core number */ 1788 add x0, x0, x1 1789 sub x2, x2, #1 1790 b 2b 17911: 1792 ret 1793endfunc get_gic_sgi_base 1794 1795/* Function writes a register in the RESET block 1796 * in: x0 = offset 1797 * in: w1 = value to write 1798 * uses x0, x1, x2 1799 */ 1800func _write_reg_reset 1801 ldr x2, =NXP_RESET_ADDR 1802 str w1, [x2, x0] 1803 ret 1804endfunc _write_reg_reset 1805 1806 1807/* Function reads a register in the RESET block 1808 * in: x0 = offset 1809 * out: w0 = value read 1810 * uses x0, x1 1811 */ 1812func _read_reg_reset 1813 ldr x1, =NXP_RESET_ADDR 1814 ldr w0, [x1, x0] 1815 ret 1816endfunc _read_reg_reset 1817