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