1*9d250f03SJiafei Pan/* 2*9d250f03SJiafei Pan * Copyright 2018-2021 NXP 3*9d250f03SJiafei Pan * 4*9d250f03SJiafei Pan * SPDX-License-Identifier: BSD-3-Clause 5*9d250f03SJiafei Pan */ 6*9d250f03SJiafei Pan 7*9d250f03SJiafei Pan .section .text, "ax" 8*9d250f03SJiafei Pan 9*9d250f03SJiafei Pan#include <asm_macros.S> 10*9d250f03SJiafei Pan 11*9d250f03SJiafei Pan#include <lib/psci/psci.h> 12*9d250f03SJiafei Pan#include <nxp_timer.h> 13*9d250f03SJiafei Pan#include <plat_gic.h> 14*9d250f03SJiafei Pan#include <pmu.h> 15*9d250f03SJiafei Pan 16*9d250f03SJiafei Pan#include <bl31_data.h> 17*9d250f03SJiafei Pan#include <plat_psci.h> 18*9d250f03SJiafei Pan#include <platform_def.h> 19*9d250f03SJiafei Pan 20*9d250f03SJiafei Pan .global soc_init_lowlevel 21*9d250f03SJiafei Pan .global soc_init_percpu 22*9d250f03SJiafei Pan .global _set_platform_security 23*9d250f03SJiafei Pan .global _soc_set_start_addr 24*9d250f03SJiafei Pan 25*9d250f03SJiafei Pan .global _soc_core_release 26*9d250f03SJiafei Pan .global _soc_ck_disabled 27*9d250f03SJiafei Pan .global _soc_core_restart 28*9d250f03SJiafei Pan .global _soc_core_prep_off 29*9d250f03SJiafei Pan .global _soc_core_entr_off 30*9d250f03SJiafei Pan .global _soc_core_exit_off 31*9d250f03SJiafei Pan .global _soc_sys_reset 32*9d250f03SJiafei Pan .global _soc_sys_off 33*9d250f03SJiafei Pan .global _soc_core_prep_stdby 34*9d250f03SJiafei Pan .global _soc_core_entr_stdby 35*9d250f03SJiafei Pan .global _soc_core_exit_stdby 36*9d250f03SJiafei Pan .global _soc_core_prep_pwrdn 37*9d250f03SJiafei Pan .global _soc_core_entr_pwrdn 38*9d250f03SJiafei Pan .global _soc_core_exit_pwrdn 39*9d250f03SJiafei Pan .global _soc_clstr_prep_stdby 40*9d250f03SJiafei Pan .global _soc_clstr_exit_stdby 41*9d250f03SJiafei Pan .global _soc_clstr_prep_pwrdn 42*9d250f03SJiafei Pan .global _soc_clstr_exit_pwrdn 43*9d250f03SJiafei Pan .global _soc_sys_prep_stdby 44*9d250f03SJiafei Pan .global _soc_sys_exit_stdby 45*9d250f03SJiafei Pan .global _soc_sys_prep_pwrdn 46*9d250f03SJiafei Pan .global _soc_sys_pwrdn_wfi 47*9d250f03SJiafei Pan .global _soc_sys_exit_pwrdn 48*9d250f03SJiafei Pan 49*9d250f03SJiafei Pan .equ TZPCDECPROT_0_SET_BASE, 0x02200804 50*9d250f03SJiafei Pan .equ TZPCDECPROT_1_SET_BASE, 0x02200810 51*9d250f03SJiafei Pan .equ TZPCDECPROT_2_SET_BASE, 0x0220081C 52*9d250f03SJiafei Pan 53*9d250f03SJiafei Pan .equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110 54*9d250f03SJiafei Pan 55*9d250f03SJiafei Pan/* 56*9d250f03SJiafei Pan * This function initialize the soc. 57*9d250f03SJiafei Pan * in: void 58*9d250f03SJiafei Pan * out: void 59*9d250f03SJiafei Pan * uses x0 - x11 60*9d250f03SJiafei Pan */ 61*9d250f03SJiafei Panfunc soc_init_lowlevel 62*9d250f03SJiafei Pan /* 63*9d250f03SJiafei Pan * Called from C, so save the non-volatile regs 64*9d250f03SJiafei Pan * save these as pairs of registers to maintain the 65*9d250f03SJiafei Pan * required 16-byte alignment on the stack 66*9d250f03SJiafei Pan */ 67*9d250f03SJiafei Pan stp x4, x5, [sp, #-16]! 68*9d250f03SJiafei Pan stp x6, x7, [sp, #-16]! 69*9d250f03SJiafei Pan stp x8, x9, [sp, #-16]! 70*9d250f03SJiafei Pan stp x10, x11, [sp, #-16]! 71*9d250f03SJiafei Pan stp x12, x13, [sp, #-16]! 72*9d250f03SJiafei Pan stp x18, x30, [sp, #-16]! 73*9d250f03SJiafei Pan 74*9d250f03SJiafei Pan /* 75*9d250f03SJiafei Pan * Make sure the personality has been established by releasing cores 76*9d250f03SJiafei Pan * that are marked "to-be-disabled" from reset 77*9d250f03SJiafei Pan */ 78*9d250f03SJiafei Pan bl release_disabled /* 0-8 */ 79*9d250f03SJiafei Pan 80*9d250f03SJiafei Pan /* Set SCRATCHRW7 to 0x0 */ 81*9d250f03SJiafei Pan ldr x0, =DCFG_SCRATCHRW7_OFFSET 82*9d250f03SJiafei Pan mov x1, xzr 83*9d250f03SJiafei Pan bl _write_reg_dcfg 84*9d250f03SJiafei Pan 85*9d250f03SJiafei Pan /* Restore the aarch32/64 non-volatile registers */ 86*9d250f03SJiafei Pan ldp x18, x30, [sp], #16 87*9d250f03SJiafei Pan ldp x12, x13, [sp], #16 88*9d250f03SJiafei Pan ldp x10, x11, [sp], #16 89*9d250f03SJiafei Pan ldp x8, x9, [sp], #16 90*9d250f03SJiafei Pan ldp x6, x7, [sp], #16 91*9d250f03SJiafei Pan ldp x4, x5, [sp], #16 92*9d250f03SJiafei Pan ret 93*9d250f03SJiafei Panendfunc soc_init_lowlevel 94*9d250f03SJiafei Pan 95*9d250f03SJiafei Pan/* 96*9d250f03SJiafei Pan * void soc_init_percpu(void) 97*9d250f03SJiafei Pan * 98*9d250f03SJiafei Pan * This function performs any soc-specific initialization that is needed on 99*9d250f03SJiafei Pan * a per-core basis 100*9d250f03SJiafei Pan * in: none 101*9d250f03SJiafei Pan * out: none 102*9d250f03SJiafei Pan * uses x0 - x3 103*9d250f03SJiafei Pan */ 104*9d250f03SJiafei Panfunc soc_init_percpu 105*9d250f03SJiafei Pan stp x4, x30, [sp, #-16]! 106*9d250f03SJiafei Pan 107*9d250f03SJiafei Pan bl plat_my_core_mask 108*9d250f03SJiafei Pan mov x2, x0 109*9d250f03SJiafei Pan 110*9d250f03SJiafei Pan /* x2 = core mask */ 111*9d250f03SJiafei Pan 112*9d250f03SJiafei Pan /* see if this core is marked for prefetch disable */ 113*9d250f03SJiafei Pan mov x0, #PREFETCH_DIS_OFFSET 114*9d250f03SJiafei Pan bl _get_global_data /* 0-1 */ 115*9d250f03SJiafei Pan tst x0, x2 116*9d250f03SJiafei Pan b.eq 1f 117*9d250f03SJiafei Pan bl _disable_ldstr_pfetch_A72 /* 0 */ 118*9d250f03SJiafei Pan1: 119*9d250f03SJiafei Pan mov x0, #NXP_PMU_ADDR 120*9d250f03SJiafei Pan bl enable_timer_base_to_cluster 121*9d250f03SJiafei Pan 122*9d250f03SJiafei Pan ldp x4, x30, [sp], #16 123*9d250f03SJiafei Pan ret 124*9d250f03SJiafei Panendfunc soc_init_percpu 125*9d250f03SJiafei Pan 126*9d250f03SJiafei Pan/* 127*9d250f03SJiafei Pan * This function determines if a core is disabled via COREDISABLEDSR 128*9d250f03SJiafei Pan * in: w0 = core_mask_lsb 129*9d250f03SJiafei Pan * out: w0 = 0, core not disabled 130*9d250f03SJiafei Pan * w0 != 0, core disabled 131*9d250f03SJiafei Pan * uses x0, x1 132*9d250f03SJiafei Pan */ 133*9d250f03SJiafei Panfunc _soc_ck_disabled 134*9d250f03SJiafei Pan /* get base addr of dcfg block */ 135*9d250f03SJiafei Pan ldr x1, =NXP_DCFG_ADDR 136*9d250f03SJiafei Pan 137*9d250f03SJiafei Pan /* read COREDISABLEDSR */ 138*9d250f03SJiafei Pan ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET] 139*9d250f03SJiafei Pan 140*9d250f03SJiafei Pan /* test core bit */ 141*9d250f03SJiafei Pan and w0, w1, w0 142*9d250f03SJiafei Pan 143*9d250f03SJiafei Pan ret 144*9d250f03SJiafei Panendfunc _soc_ck_disabled 145*9d250f03SJiafei Pan 146*9d250f03SJiafei Pan/* 147*9d250f03SJiafei Pan * This function sets the security mechanisms in the SoC to implement the 148*9d250f03SJiafei Pan * Platform Security Policy 149*9d250f03SJiafei Pan */ 150*9d250f03SJiafei Panfunc _set_platform_security 151*9d250f03SJiafei Pan mov x3, x30 152*9d250f03SJiafei Pan 153*9d250f03SJiafei Pan#if (!SUPPRESS_TZC) 154*9d250f03SJiafei Pan /* initialize the tzpc */ 155*9d250f03SJiafei Pan bl init_tzpc 156*9d250f03SJiafei Pan#endif 157*9d250f03SJiafei Pan 158*9d250f03SJiafei Pan#if (!SUPPRESS_SEC) 159*9d250f03SJiafei Pan /* initialize secmon */ 160*9d250f03SJiafei Pan bl initSecMon 161*9d250f03SJiafei Pan#endif 162*9d250f03SJiafei Pan 163*9d250f03SJiafei Pan mov x30, x3 164*9d250f03SJiafei Pan ret 165*9d250f03SJiafei Panendfunc _set_platform_security 166*9d250f03SJiafei Pan 167*9d250f03SJiafei Pan/* 168*9d250f03SJiafei Pan * Part of CPU_ON 169*9d250f03SJiafei Pan * 170*9d250f03SJiafei Pan * This function releases a secondary core from reset 171*9d250f03SJiafei Pan * in: x0 = core_mask_lsb 172*9d250f03SJiafei Pan * out: none 173*9d250f03SJiafei Pan * uses: x0 - x3 174*9d250f03SJiafei Pan */ 175*9d250f03SJiafei Pan_soc_core_release: 176*9d250f03SJiafei Pan mov x3, x30 177*9d250f03SJiafei Pan 178*9d250f03SJiafei Pan /* 179*9d250f03SJiafei Pan * Write to CORE_HOLD to tell the bootrom that we want this core 180*9d250f03SJiafei Pan * to run 181*9d250f03SJiafei Pan */ 182*9d250f03SJiafei Pan ldr x1, =NXP_SEC_REGFILE_ADDR 183*9d250f03SJiafei Pan str w0, [x1, #CORE_HOLD_OFFSET] 184*9d250f03SJiafei Pan 185*9d250f03SJiafei Pan /* Read-modify-write BRRL to release core */ 186*9d250f03SJiafei Pan mov x1, #NXP_RESET_ADDR 187*9d250f03SJiafei Pan ldr w2, [x1, #BRR_OFFSET] 188*9d250f03SJiafei Pan orr w2, w2, w0 189*9d250f03SJiafei Pan str w2, [x1, #BRR_OFFSET] 190*9d250f03SJiafei Pan dsb sy 191*9d250f03SJiafei Pan isb 192*9d250f03SJiafei Pan 193*9d250f03SJiafei Pan /* Send event */ 194*9d250f03SJiafei Pan sev 195*9d250f03SJiafei Pan isb 196*9d250f03SJiafei Pan 197*9d250f03SJiafei Pan mov x30, x3 198*9d250f03SJiafei Pan ret 199*9d250f03SJiafei Pan 200*9d250f03SJiafei Pan/* 201*9d250f03SJiafei Pan * This function writes a 64-bit address to bootlocptrh/l 202*9d250f03SJiafei Pan * in: x0, 64-bit address to write to BOOTLOCPTRL/H 203*9d250f03SJiafei Pan * uses x0, x1, x2 204*9d250f03SJiafei Pan */ 205*9d250f03SJiafei Panfunc _soc_set_start_addr 206*9d250f03SJiafei Pan /* Get the 64-bit base address of the dcfg block */ 207*9d250f03SJiafei Pan ldr x2, =NXP_DCFG_ADDR 208*9d250f03SJiafei Pan 209*9d250f03SJiafei Pan /* Write the 32-bit BOOTLOCPTRL register */ 210*9d250f03SJiafei Pan mov x1, x0 211*9d250f03SJiafei Pan str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET] 212*9d250f03SJiafei Pan 213*9d250f03SJiafei Pan /* Write the 32-bit BOOTLOCPTRH register */ 214*9d250f03SJiafei Pan lsr x1, x0, #32 215*9d250f03SJiafei Pan str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET] 216*9d250f03SJiafei Pan ret 217*9d250f03SJiafei Panendfunc _soc_set_start_addr 218*9d250f03SJiafei Pan 219*9d250f03SJiafei Pan/* 220*9d250f03SJiafei Pan * Part of CPU_ON 221*9d250f03SJiafei Pan * 222*9d250f03SJiafei Pan * This function restarts a core shutdown via _soc_core_entr_off 223*9d250f03SJiafei Pan * in: x0 = core mask lsb (of the target cpu) 224*9d250f03SJiafei Pan * out: x0 == 0, on success 225*9d250f03SJiafei Pan * x0 != 0, on failure 226*9d250f03SJiafei Pan * uses x0 - x6 227*9d250f03SJiafei Pan */ 228*9d250f03SJiafei Pan_soc_core_restart: 229*9d250f03SJiafei Pan mov x6, x30 230*9d250f03SJiafei Pan mov x4, x0 231*9d250f03SJiafei Pan 232*9d250f03SJiafei Pan /* pgm GICD_CTLR - enable secure grp0 */ 233*9d250f03SJiafei Pan mov x5, #NXP_GICD_ADDR 234*9d250f03SJiafei Pan ldr w2, [x5, #GICD_CTLR_OFFSET] 235*9d250f03SJiafei Pan orr w2, w2, #GICD_CTLR_EN_GRP_0 236*9d250f03SJiafei Pan str w2, [x5, #GICD_CTLR_OFFSET] 237*9d250f03SJiafei Pan dsb sy 238*9d250f03SJiafei Pan isb 239*9d250f03SJiafei Pan 240*9d250f03SJiafei Pan /* Poll on RWP til write completes */ 241*9d250f03SJiafei Pan4: 242*9d250f03SJiafei Pan ldr w2, [x5, #GICD_CTLR_OFFSET] 243*9d250f03SJiafei Pan tst w2, #GICD_CTLR_RWP 244*9d250f03SJiafei Pan b.ne 4b 245*9d250f03SJiafei Pan 246*9d250f03SJiafei Pan /* 247*9d250f03SJiafei Pan * x4 = core mask lsb 248*9d250f03SJiafei Pan * x5 = gicd base addr 249*9d250f03SJiafei Pan */ 250*9d250f03SJiafei Pan 251*9d250f03SJiafei Pan mov x0, x4 252*9d250f03SJiafei Pan bl get_mpidr_value 253*9d250f03SJiafei Pan 254*9d250f03SJiafei Pan /* Generate target list bit */ 255*9d250f03SJiafei Pan and x1, x0, #MPIDR_AFFINITY0_MASK 256*9d250f03SJiafei Pan mov x2, #1 257*9d250f03SJiafei Pan lsl x2, x2, x1 258*9d250f03SJiafei Pan 259*9d250f03SJiafei Pan /* Get the affinity1 field */ 260*9d250f03SJiafei Pan and x1, x0, #MPIDR_AFFINITY1_MASK 261*9d250f03SJiafei Pan lsl x1, x1, #8 262*9d250f03SJiafei Pan orr x2, x2, x1 263*9d250f03SJiafei Pan 264*9d250f03SJiafei Pan /* Insert the INTID for SGI15 */ 265*9d250f03SJiafei Pan orr x2, x2, #ICC_SGI0R_EL1_INTID 266*9d250f03SJiafei Pan 267*9d250f03SJiafei Pan /* Fire the SGI */ 268*9d250f03SJiafei Pan msr ICC_SGI0R_EL1, x2 269*9d250f03SJiafei Pan dsb sy 270*9d250f03SJiafei Pan isb 271*9d250f03SJiafei Pan 272*9d250f03SJiafei Pan /* Load '0' on success */ 273*9d250f03SJiafei Pan mov x0, xzr 274*9d250f03SJiafei Pan 275*9d250f03SJiafei Pan mov x30, x6 276*9d250f03SJiafei Pan ret 277*9d250f03SJiafei Pan 278*9d250f03SJiafei Pan/* 279*9d250f03SJiafei Pan * Part of CPU_OFF 280*9d250f03SJiafei Pan * 281*9d250f03SJiafei Pan * This function programs SoC & GIC registers in preparation for shutting down 282*9d250f03SJiafei Pan * the core 283*9d250f03SJiafei Pan * in: x0 = core mask lsb 284*9d250f03SJiafei Pan * out: none 285*9d250f03SJiafei Pan * uses x0 - x7 286*9d250f03SJiafei Pan */ 287*9d250f03SJiafei Pan_soc_core_prep_off: 288*9d250f03SJiafei Pan mov x8, x30 289*9d250f03SJiafei Pan mov x7, x0 290*9d250f03SJiafei Pan 291*9d250f03SJiafei Pan /* x7 = core mask lsb */ 292*9d250f03SJiafei Pan 293*9d250f03SJiafei Pan mrs x1, CPUECTLR_EL1 294*9d250f03SJiafei Pan 295*9d250f03SJiafei Pan /* Set smp and disable L2 snoops in cpuectlr */ 296*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_SMPEN_EN 297*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH 298*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK 299*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK 300*9d250f03SJiafei Pan 301*9d250f03SJiafei Pan /* Set retention control in cpuectlr */ 302*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_TIMER_MASK 303*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_TIMER_2TICKS 304*9d250f03SJiafei Pan msr CPUECTLR_EL1, x1 305*9d250f03SJiafei Pan 306*9d250f03SJiafei Pan /* Get redistributor rd base addr for this core */ 307*9d250f03SJiafei Pan mov x0, x7 308*9d250f03SJiafei Pan bl get_gic_rd_base 309*9d250f03SJiafei Pan mov x6, x0 310*9d250f03SJiafei Pan 311*9d250f03SJiafei Pan /* Get redistributor sgi base addr for this core */ 312*9d250f03SJiafei Pan mov x0, x7 313*9d250f03SJiafei Pan bl get_gic_sgi_base 314*9d250f03SJiafei Pan mov x5, x0 315*9d250f03SJiafei Pan 316*9d250f03SJiafei Pan /* 317*9d250f03SJiafei Pan * x5 = gicr sgi base addr 318*9d250f03SJiafei Pan * x6 = gicr rd base addr 319*9d250f03SJiafei Pan * x7 = core mask lsb 320*9d250f03SJiafei Pan */ 321*9d250f03SJiafei Pan 322*9d250f03SJiafei Pan /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */ 323*9d250f03SJiafei Pan mov w3, #GICR_ICENABLER0_SGI15 324*9d250f03SJiafei Pan str w3, [x5, #GICR_ICENABLER0_OFFSET] 325*9d250f03SJiafei Pan2: 326*9d250f03SJiafei Pan /* Poll on rwp bit in GICR_CTLR */ 327*9d250f03SJiafei Pan ldr w4, [x6, #GICR_CTLR_OFFSET] 328*9d250f03SJiafei Pan tst w4, #GICR_CTLR_RWP 329*9d250f03SJiafei Pan b.ne 2b 330*9d250f03SJiafei Pan 331*9d250f03SJiafei Pan /* Disable GRP1 interrupts at cpu interface */ 332*9d250f03SJiafei Pan msr ICC_IGRPEN1_EL3, xzr 333*9d250f03SJiafei Pan 334*9d250f03SJiafei Pan /* Disable GRP0 ints at cpu interface */ 335*9d250f03SJiafei Pan msr ICC_IGRPEN0_EL1, xzr 336*9d250f03SJiafei Pan 337*9d250f03SJiafei Pan /* Program the redistributor - poll on GICR_CTLR.RWP as needed */ 338*9d250f03SJiafei Pan 339*9d250f03SJiafei Pan /* Define SGI 15 as Grp0 - GICR_IGROUPR0 */ 340*9d250f03SJiafei Pan ldr w4, [x5, #GICR_IGROUPR0_OFFSET] 341*9d250f03SJiafei Pan bic w4, w4, #GICR_IGROUPR0_SGI15 342*9d250f03SJiafei Pan str w4, [x5, #GICR_IGROUPR0_OFFSET] 343*9d250f03SJiafei Pan 344*9d250f03SJiafei Pan /* Define SGI 15 as Grp0 - GICR_IGRPMODR0 */ 345*9d250f03SJiafei Pan ldr w3, [x5, #GICR_IGRPMODR0_OFFSET] 346*9d250f03SJiafei Pan bic w3, w3, #GICR_IGRPMODR0_SGI15 347*9d250f03SJiafei Pan str w3, [x5, #GICR_IGRPMODR0_OFFSET] 348*9d250f03SJiafei Pan 349*9d250f03SJiafei Pan /* Set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */ 350*9d250f03SJiafei Pan ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET] 351*9d250f03SJiafei Pan bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK 352*9d250f03SJiafei Pan str w4, [x5, #GICR_IPRIORITYR3_OFFSET] 353*9d250f03SJiafei Pan 354*9d250f03SJiafei Pan /* Enable SGI 15 at redistributor - GICR_ISENABLER0 */ 355*9d250f03SJiafei Pan mov w3, #GICR_ISENABLER0_SGI15 356*9d250f03SJiafei Pan str w3, [x5, #GICR_ISENABLER0_OFFSET] 357*9d250f03SJiafei Pan dsb sy 358*9d250f03SJiafei Pan isb 359*9d250f03SJiafei Pan3: 360*9d250f03SJiafei Pan /* Poll on rwp bit in GICR_CTLR */ 361*9d250f03SJiafei Pan ldr w4, [x6, #GICR_CTLR_OFFSET] 362*9d250f03SJiafei Pan tst w4, #GICR_CTLR_RWP 363*9d250f03SJiafei Pan b.ne 3b 364*9d250f03SJiafei Pan 365*9d250f03SJiafei Pan /* Quiesce the debug interfaces */ 366*9d250f03SJiafei Pan mrs x3, osdlr_el1 367*9d250f03SJiafei Pan orr x3, x3, #OSDLR_EL1_DLK_LOCK 368*9d250f03SJiafei Pan msr osdlr_el1, x3 369*9d250f03SJiafei Pan isb 370*9d250f03SJiafei Pan 371*9d250f03SJiafei Pan /* Enable grp0 ints */ 372*9d250f03SJiafei Pan mov x3, #ICC_IGRPEN0_EL1_EN 373*9d250f03SJiafei Pan msr ICC_IGRPEN0_EL1, x3 374*9d250f03SJiafei Pan 375*9d250f03SJiafei Pan /* 376*9d250f03SJiafei Pan * x5 = gicr sgi base addr 377*9d250f03SJiafei Pan * x6 = gicr rd base addr 378*9d250f03SJiafei Pan * x7 = core mask lsb 379*9d250f03SJiafei Pan */ 380*9d250f03SJiafei Pan 381*9d250f03SJiafei Pan /* Clear any pending interrupts */ 382*9d250f03SJiafei Pan mvn w1, wzr 383*9d250f03SJiafei Pan str w1, [x5, #GICR_ICPENDR0_OFFSET] 384*9d250f03SJiafei Pan 385*9d250f03SJiafei Pan /* Make sure system counter is enabled */ 386*9d250f03SJiafei Pan ldr x3, =NXP_TIMER_ADDR 387*9d250f03SJiafei Pan ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET] 388*9d250f03SJiafei Pan tst w0, #SYS_COUNTER_CNTCR_EN 389*9d250f03SJiafei Pan b.ne 4f 390*9d250f03SJiafei Pan orr w0, w0, #SYS_COUNTER_CNTCR_EN 391*9d250f03SJiafei Pan str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET] 392*9d250f03SJiafei Pan4: 393*9d250f03SJiafei Pan /* Enable the core timer and mask timer interrupt */ 394*9d250f03SJiafei Pan mov x1, #CNTP_CTL_EL0_EN 395*9d250f03SJiafei Pan orr x1, x1, #CNTP_CTL_EL0_IMASK 396*9d250f03SJiafei Pan msr cntp_ctl_el0, x1 397*9d250f03SJiafei Pan 398*9d250f03SJiafei Pan isb 399*9d250f03SJiafei Pan mov x30, x8 400*9d250f03SJiafei Pan ret 401*9d250f03SJiafei Pan 402*9d250f03SJiafei Pan/* 403*9d250f03SJiafei Pan * Part of CPU_OFF 404*9d250f03SJiafei Pan * 405*9d250f03SJiafei Pan * This function performs the final steps to shutdown the core 406*9d250f03SJiafei Pan * in: x0 = core mask lsb 407*9d250f03SJiafei Pan * out: none 408*9d250f03SJiafei Pan * uses x0 - x5 409*9d250f03SJiafei Pan */ 410*9d250f03SJiafei Pan_soc_core_entr_off: 411*9d250f03SJiafei Pan mov x5, x30 412*9d250f03SJiafei Pan mov x4, x0 413*9d250f03SJiafei Pan 414*9d250f03SJiafei Pan /* x4 = core mask */ 415*9d250f03SJiafei Pan1: 416*9d250f03SJiafei Pan /* Enter low-power state by executing wfi */ 417*9d250f03SJiafei Pan wfi 418*9d250f03SJiafei Pan 419*9d250f03SJiafei Pan /* See if SGI15 woke us up */ 420*9d250f03SJiafei Pan mrs x2, ICC_IAR0_EL1 421*9d250f03SJiafei Pan mov x3, #ICC_IAR0_EL1_SGI15 422*9d250f03SJiafei Pan cmp x2, x3 423*9d250f03SJiafei Pan b.ne 1b 424*9d250f03SJiafei Pan 425*9d250f03SJiafei Pan /* Deactivate the int */ 426*9d250f03SJiafei Pan msr ICC_EOIR0_EL1, x2 427*9d250f03SJiafei Pan 428*9d250f03SJiafei Pan /* x4 = core mask */ 429*9d250f03SJiafei Pan2: 430*9d250f03SJiafei Pan /* Check if core has been turned on */ 431*9d250f03SJiafei Pan mov x0, x4 432*9d250f03SJiafei Pan bl _getCoreState 433*9d250f03SJiafei Pan 434*9d250f03SJiafei Pan /* x0 = core state */ 435*9d250f03SJiafei Pan 436*9d250f03SJiafei Pan cmp x0, #CORE_WAKEUP 437*9d250f03SJiafei Pan b.ne 1b 438*9d250f03SJiafei Pan 439*9d250f03SJiafei Pan /* If we get here, then we have exited the wfi */ 440*9d250f03SJiafei Pan mov x30, x5 441*9d250f03SJiafei Pan ret 442*9d250f03SJiafei Pan 443*9d250f03SJiafei Pan/* 444*9d250f03SJiafei Pan * Part of CPU_OFF 445*9d250f03SJiafei Pan * 446*9d250f03SJiafei Pan * This function starts the process of starting a core back up 447*9d250f03SJiafei Pan * in: x0 = core mask lsb 448*9d250f03SJiafei Pan * out: none 449*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6 450*9d250f03SJiafei Pan */ 451*9d250f03SJiafei Pan_soc_core_exit_off: 452*9d250f03SJiafei Pan mov x6, x30 453*9d250f03SJiafei Pan mov x5, x0 454*9d250f03SJiafei Pan 455*9d250f03SJiafei Pan /* Disable forwarding of GRP0 ints at cpu interface */ 456*9d250f03SJiafei Pan msr ICC_IGRPEN0_EL1, xzr 457*9d250f03SJiafei Pan 458*9d250f03SJiafei Pan /* Get redistributor sgi base addr for this core */ 459*9d250f03SJiafei Pan mov x0, x5 460*9d250f03SJiafei Pan bl get_gic_sgi_base 461*9d250f03SJiafei Pan mov x4, x0 462*9d250f03SJiafei Pan 463*9d250f03SJiafei Pan /* x4 = gicr sgi base addr */ 464*9d250f03SJiafei Pan /* x5 = core mask */ 465*9d250f03SJiafei Pan 466*9d250f03SJiafei Pan /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */ 467*9d250f03SJiafei Pan mov w1, #GICR_ICENABLER0_SGI15 468*9d250f03SJiafei Pan str w1, [x4, #GICR_ICENABLER0_OFFSET] 469*9d250f03SJiafei Pan 470*9d250f03SJiafei Pan /* Get redistributor rd base addr for this core */ 471*9d250f03SJiafei Pan mov x0, x5 472*9d250f03SJiafei Pan bl get_gic_rd_base 473*9d250f03SJiafei Pan mov x4, x0 474*9d250f03SJiafei Pan 475*9d250f03SJiafei Pan /* x4 = gicr rd base addr */ 476*9d250f03SJiafei Pan2: 477*9d250f03SJiafei Pan /* Poll on rwp bit in GICR_CTLR */ 478*9d250f03SJiafei Pan ldr w2, [x4, #GICR_CTLR_OFFSET] 479*9d250f03SJiafei Pan tst w2, #GICR_CTLR_RWP 480*9d250f03SJiafei Pan b.ne 2b 481*9d250f03SJiafei Pan 482*9d250f03SJiafei Pan /* x4 = gicr rd base addr */ 483*9d250f03SJiafei Pan 484*9d250f03SJiafei Pan /* Unlock the debug interfaces */ 485*9d250f03SJiafei Pan mrs x3, osdlr_el1 486*9d250f03SJiafei Pan bic x3, x3, #OSDLR_EL1_DLK_LOCK 487*9d250f03SJiafei Pan msr osdlr_el1, x3 488*9d250f03SJiafei Pan isb 489*9d250f03SJiafei Pan 490*9d250f03SJiafei Pan dsb sy 491*9d250f03SJiafei Pan isb 492*9d250f03SJiafei Pan mov x30, x6 493*9d250f03SJiafei Pan ret 494*9d250f03SJiafei Pan 495*9d250f03SJiafei Pan/* 496*9d250f03SJiafei Pan * This function requests a reset of the entire SOC 497*9d250f03SJiafei Pan * in: none 498*9d250f03SJiafei Pan * out: none 499*9d250f03SJiafei Pan * uses: x0, x1, x2, x3, x4, x5, x6 500*9d250f03SJiafei Pan */ 501*9d250f03SJiafei Pan_soc_sys_reset: 502*9d250f03SJiafei Pan mov x3, x30 503*9d250f03SJiafei Pan 504*9d250f03SJiafei Pan /* Make sure the mask is cleared in the reset request mask register */ 505*9d250f03SJiafei Pan mov x0, #RST_RSTRQMR1_OFFSET 506*9d250f03SJiafei Pan mov w1, wzr 507*9d250f03SJiafei Pan bl _write_reg_reset 508*9d250f03SJiafei Pan 509*9d250f03SJiafei Pan /* Set the reset request */ 510*9d250f03SJiafei Pan mov x4, #RST_RSTCR_OFFSET 511*9d250f03SJiafei Pan mov x0, x4 512*9d250f03SJiafei Pan mov w1, #RSTCR_RESET_REQ 513*9d250f03SJiafei Pan bl _write_reg_reset 514*9d250f03SJiafei Pan 515*9d250f03SJiafei Pan /* x4 = RST_RSTCR_OFFSET */ 516*9d250f03SJiafei Pan 517*9d250f03SJiafei Pan /* 518*9d250f03SJiafei Pan * Just in case this address range is mapped as cacheable, 519*9d250f03SJiafei Pan * flush the write out of the dcaches 520*9d250f03SJiafei Pan */ 521*9d250f03SJiafei Pan mov x2, #NXP_RESET_ADDR 522*9d250f03SJiafei Pan add x2, x2, x4 523*9d250f03SJiafei Pan dc cvac, x2 524*9d250f03SJiafei Pan dsb st 525*9d250f03SJiafei Pan isb 526*9d250f03SJiafei Pan 527*9d250f03SJiafei Pan /* This function does not return */ 528*9d250f03SJiafei Pan1: 529*9d250f03SJiafei Pan wfi 530*9d250f03SJiafei Pan b 1b 531*9d250f03SJiafei Pan 532*9d250f03SJiafei Pan/* 533*9d250f03SJiafei Pan * Part of SYSTEM_OFF 534*9d250f03SJiafei Pan * 535*9d250f03SJiafei Pan * This function turns off the SoC clocks 536*9d250f03SJiafei Pan * Note: this function is not intended to return, and the only allowable 537*9d250f03SJiafei Pan * recovery is POR 538*9d250f03SJiafei Pan * in: none 539*9d250f03SJiafei Pan * out: none 540*9d250f03SJiafei Pan * uses x0, x1, x2, x3 541*9d250f03SJiafei Pan */ 542*9d250f03SJiafei Pan_soc_sys_off: 543*9d250f03SJiafei Pan /* 544*9d250f03SJiafei Pan * Disable sec, spi and flexspi 545*9d250f03SJiafei Pan * TBD - Check if eNETC needs to be disabled 546*9d250f03SJiafei Pan */ 547*9d250f03SJiafei Pan ldr x2, =NXP_DCFG_ADDR 548*9d250f03SJiafei Pan ldr x0, =DCFG_DEVDISR1_OFFSET 549*9d250f03SJiafei Pan ldr w1, =DCFG_DEVDISR1_SEC 550*9d250f03SJiafei Pan str w1, [x2, x0] 551*9d250f03SJiafei Pan ldr x0, =DCFG_DEVDISR4_OFFSET 552*9d250f03SJiafei Pan ldr w1, =DCFG_DEVDISR4_SPI_QSPI 553*9d250f03SJiafei Pan str w1, [x2, x0] 554*9d250f03SJiafei Pan 555*9d250f03SJiafei Pan /* Set TPMWAKEMR0 */ 556*9d250f03SJiafei Pan ldr x0, =TPMWAKEMR0_ADDR 557*9d250f03SJiafei Pan mov w1, #0x1 558*9d250f03SJiafei Pan str w1, [x0] 559*9d250f03SJiafei Pan 560*9d250f03SJiafei Pan /* Disable icache, dcache, mmu @ EL1 */ 561*9d250f03SJiafei Pan mov x1, #SCTLR_I_C_M_MASK 562*9d250f03SJiafei Pan mrs x0, sctlr_el1 563*9d250f03SJiafei Pan bic x0, x0, x1 564*9d250f03SJiafei Pan msr sctlr_el1, x0 565*9d250f03SJiafei Pan 566*9d250f03SJiafei Pan /* Disable L2 prefetches */ 567*9d250f03SJiafei Pan mrs x0, CPUECTLR_EL1 568*9d250f03SJiafei Pan orr x0, x0, #CPUECTLR_SMPEN_EN 569*9d250f03SJiafei Pan bic x0, x0, #CPUECTLR_TIMER_MASK 570*9d250f03SJiafei Pan orr x0, x0, #CPUECTLR_TIMER_2TICKS 571*9d250f03SJiafei Pan msr CPUECTLR_EL1, x0 572*9d250f03SJiafei Pan dsb sy 573*9d250f03SJiafei Pan isb 574*9d250f03SJiafei Pan 575*9d250f03SJiafei Pan /* Disable CCI snoop domain */ 576*9d250f03SJiafei Pan ldr x0, =NXP_CCI_ADDR 577*9d250f03SJiafei Pan mov w1, #0x1 578*9d250f03SJiafei Pan str w1, [x0] 579*9d250f03SJiafei Pan 580*9d250f03SJiafei Pan bl get_pmu_idle_core_mask 581*9d250f03SJiafei Pan 582*9d250f03SJiafei Pan /* x3 = pmu base addr */ 583*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 584*9d250f03SJiafei Pan4: 585*9d250f03SJiafei Pan ldr w1, [x3, #PMU_PCPW20SR_OFFSET] 586*9d250f03SJiafei Pan cmp w1, w0 587*9d250f03SJiafei Pan b.ne 4b 588*9d250f03SJiafei Pan 589*9d250f03SJiafei Pan bl get_pmu_idle_cluster_mask 590*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 591*9d250f03SJiafei Pan str w0, [x3, #PMU_CLAINACTSETR_OFFSET] 592*9d250f03SJiafei Pan 593*9d250f03SJiafei Pan bl get_pmu_idle_core_mask 594*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 595*9d250f03SJiafei Pan1: 596*9d250f03SJiafei Pan ldr w1, [x3, #PMU_PCPW20SR_OFFSET] 597*9d250f03SJiafei Pan cmp w1, w0 598*9d250f03SJiafei Pan b.ne 1b 599*9d250f03SJiafei Pan 600*9d250f03SJiafei Pan bl get_pmu_flush_cluster_mask 601*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 602*9d250f03SJiafei Pan str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET] 603*9d250f03SJiafei Pan2: 604*9d250f03SJiafei Pan ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET] 605*9d250f03SJiafei Pan cmp w1, w0 606*9d250f03SJiafei Pan b.ne 2b 607*9d250f03SJiafei Pan 608*9d250f03SJiafei Pan str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET] 609*9d250f03SJiafei Pan 610*9d250f03SJiafei Pan str w0, [x3, #PMU_CLSINACTSETR_OFFSET] 611*9d250f03SJiafei Pan 612*9d250f03SJiafei Pan mov x2, #DAIF_SET_MASK 613*9d250f03SJiafei Pan mrs x1, spsr_el1 614*9d250f03SJiafei Pan orr x1, x1, x2 615*9d250f03SJiafei Pan msr spsr_el1, x1 616*9d250f03SJiafei Pan 617*9d250f03SJiafei Pan mrs x1, spsr_el2 618*9d250f03SJiafei Pan orr x1, x1, x2 619*9d250f03SJiafei Pan msr spsr_el2, x1 620*9d250f03SJiafei Pan 621*9d250f03SJiafei Pan /* Force the debug interface to be quiescent */ 622*9d250f03SJiafei Pan mrs x0, osdlr_el1 623*9d250f03SJiafei Pan orr x0, x0, #0x1 624*9d250f03SJiafei Pan msr osdlr_el1, x0 625*9d250f03SJiafei Pan 626*9d250f03SJiafei Pan /* Invalidate all TLB entries at all 3 exception levels */ 627*9d250f03SJiafei Pan tlbi alle1 628*9d250f03SJiafei Pan tlbi alle2 629*9d250f03SJiafei Pan tlbi alle3 630*9d250f03SJiafei Pan 631*9d250f03SJiafei Pan /* x3 = pmu base addr */ 632*9d250f03SJiafei Pan 633*9d250f03SJiafei Pan /* Request lpm20 */ 634*9d250f03SJiafei Pan ldr x0, =PMU_POWMGTCSR_OFFSET 635*9d250f03SJiafei Pan ldr w1, =PMU_POWMGTCSR_VAL 636*9d250f03SJiafei Pan str w1, [x3, x0] 637*9d250f03SJiafei Pan isb 638*9d250f03SJiafei Pan dsb sy 639*9d250f03SJiafei Pan5: 640*9d250f03SJiafei Pan wfe 641*9d250f03SJiafei Pan b.eq 5b 642*9d250f03SJiafei Pan 643*9d250f03SJiafei Pan/* 644*9d250f03SJiafei Pan * Part of CPU_SUSPEND 645*9d250f03SJiafei Pan * 646*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to standby 647*9d250f03SJiafei Pan * in: x0 = core mask lsb 648*9d250f03SJiafei Pan * out: none 649*9d250f03SJiafei Pan * uses x0, x1 650*9d250f03SJiafei Pan */ 651*9d250f03SJiafei Pan_soc_core_prep_stdby: 652*9d250f03SJiafei Pan /* Clear CPUECTLR_EL1[2:0] */ 653*9d250f03SJiafei Pan mrs x1, CPUECTLR_EL1 654*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_TIMER_MASK 655*9d250f03SJiafei Pan msr CPUECTLR_EL1, x1 656*9d250f03SJiafei Pan 657*9d250f03SJiafei Pan ret 658*9d250f03SJiafei Pan 659*9d250f03SJiafei Pan/* 660*9d250f03SJiafei Pan * Part of CPU_SUSPEND 661*9d250f03SJiafei Pan * 662*9d250f03SJiafei Pan * This function puts the calling core into standby state 663*9d250f03SJiafei Pan * in: x0 = core mask lsb 664*9d250f03SJiafei Pan * out: none 665*9d250f03SJiafei Pan * uses x0 666*9d250f03SJiafei Pan */ 667*9d250f03SJiafei Pan_soc_core_entr_stdby: 668*9d250f03SJiafei Pan /* X0 = core mask lsb */ 669*9d250f03SJiafei Pan dsb sy 670*9d250f03SJiafei Pan isb 671*9d250f03SJiafei Pan wfi 672*9d250f03SJiafei Pan 673*9d250f03SJiafei Pan ret 674*9d250f03SJiafei Pan 675*9d250f03SJiafei Pan/* 676*9d250f03SJiafei Pan * Part of CPU_SUSPEND 677*9d250f03SJiafei Pan * 678*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after standby state 679*9d250f03SJiafei Pan * in: x0 = core mask lsb 680*9d250f03SJiafei Pan * out: none 681*9d250f03SJiafei Pan * uses none 682*9d250f03SJiafei Pan */ 683*9d250f03SJiafei Pan_soc_core_exit_stdby: 684*9d250f03SJiafei Pan ret 685*9d250f03SJiafei Pan 686*9d250f03SJiafei Pan/* 687*9d250f03SJiafei Pan * Part of CPU_SUSPEND 688*9d250f03SJiafei Pan * 689*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to power-down 690*9d250f03SJiafei Pan * in: x0 = core mask lsb 691*9d250f03SJiafei Pan * out: none 692*9d250f03SJiafei Pan * uses x0, x1, x2 693*9d250f03SJiafei Pan */ 694*9d250f03SJiafei Pan_soc_core_prep_pwrdn: 695*9d250f03SJiafei Pan /* Make sure system counter is enabled */ 696*9d250f03SJiafei Pan ldr x2, =NXP_TIMER_ADDR 697*9d250f03SJiafei Pan ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 698*9d250f03SJiafei Pan tst w0, #SYS_COUNTER_CNTCR_EN 699*9d250f03SJiafei Pan b.ne 1f 700*9d250f03SJiafei Pan orr w0, w0, #SYS_COUNTER_CNTCR_EN 701*9d250f03SJiafei Pan str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 702*9d250f03SJiafei Pan1: 703*9d250f03SJiafei Pan /* 704*9d250f03SJiafei Pan * Enable dynamic retention control (CPUECTLR[2:0]) 705*9d250f03SJiafei Pan * Set the SMPEN bit (CPUECTLR[6]) 706*9d250f03SJiafei Pan */ 707*9d250f03SJiafei Pan mrs x1, CPUECTLR_EL1 708*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_RET_MASK 709*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_TIMER_2TICKS 710*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_SMPEN_EN 711*9d250f03SJiafei Pan msr CPUECTLR_EL1, x1 712*9d250f03SJiafei Pan 713*9d250f03SJiafei Pan isb 714*9d250f03SJiafei Pan ret 715*9d250f03SJiafei Pan 716*9d250f03SJiafei Pan/* 717*9d250f03SJiafei Pan * Part of CPU_SUSPEND 718*9d250f03SJiafei Pan * 719*9d250f03SJiafei Pan * This function puts the calling core into a power-down state 720*9d250f03SJiafei Pan * in: x0 = core mask lsb 721*9d250f03SJiafei Pan * out: none 722*9d250f03SJiafei Pan * uses x0 723*9d250f03SJiafei Pan */ 724*9d250f03SJiafei Pan_soc_core_entr_pwrdn: 725*9d250f03SJiafei Pan /* X0 = core mask lsb */ 726*9d250f03SJiafei Pan dsb sy 727*9d250f03SJiafei Pan isb 728*9d250f03SJiafei Pan wfi 729*9d250f03SJiafei Pan 730*9d250f03SJiafei Pan ret 731*9d250f03SJiafei Pan 732*9d250f03SJiafei Pan/* 733*9d250f03SJiafei Pan * Part of CPU_SUSPEND 734*9d250f03SJiafei Pan * 735*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after power-down state 736*9d250f03SJiafei Pan * in: x0 = core mask lsb 737*9d250f03SJiafei Pan * out: none 738*9d250f03SJiafei Pan * uses none 739*9d250f03SJiafei Pan */ 740*9d250f03SJiafei Pan_soc_core_exit_pwrdn: 741*9d250f03SJiafei Pan ret 742*9d250f03SJiafei Pan 743*9d250f03SJiafei Pan/* 744*9d250f03SJiafei Pan * Part of CPU_SUSPEND 745*9d250f03SJiafei Pan * 746*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to standby 747*9d250f03SJiafei Pan * in: x0 = core mask lsb 748*9d250f03SJiafei Pan * out: none 749*9d250f03SJiafei Pan * uses x0, x1 750*9d250f03SJiafei Pan */ 751*9d250f03SJiafei Pan_soc_clstr_prep_stdby: 752*9d250f03SJiafei Pan /* Clear CPUECTLR_EL1[2:0] */ 753*9d250f03SJiafei Pan mrs x1, CPUECTLR_EL1 754*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_TIMER_MASK 755*9d250f03SJiafei Pan msr CPUECTLR_EL1, x1 756*9d250f03SJiafei Pan 757*9d250f03SJiafei Pan ret 758*9d250f03SJiafei Pan 759*9d250f03SJiafei Pan/* 760*9d250f03SJiafei Pan * Part of CPU_SUSPEND 761*9d250f03SJiafei Pan * 762*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after standby state 763*9d250f03SJiafei Pan * in: x0 = core mask lsb 764*9d250f03SJiafei Pan * out: none 765*9d250f03SJiafei Pan * uses none 766*9d250f03SJiafei Pan */ 767*9d250f03SJiafei Pan_soc_clstr_exit_stdby: 768*9d250f03SJiafei Pan ret 769*9d250f03SJiafei Pan 770*9d250f03SJiafei Pan/* 771*9d250f03SJiafei Pan * Part of CPU_SUSPEND 772*9d250f03SJiafei Pan * 773*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to power-down 774*9d250f03SJiafei Pan * in: x0 = core mask lsb 775*9d250f03SJiafei Pan * out: none 776*9d250f03SJiafei Pan * uses x0, x1, x2 777*9d250f03SJiafei Pan */ 778*9d250f03SJiafei Pan_soc_clstr_prep_pwrdn: 779*9d250f03SJiafei Pan /* Make sure system counter is enabled */ 780*9d250f03SJiafei Pan ldr x2, =NXP_TIMER_ADDR 781*9d250f03SJiafei Pan ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 782*9d250f03SJiafei Pan tst w0, #SYS_COUNTER_CNTCR_EN 783*9d250f03SJiafei Pan b.ne 1f 784*9d250f03SJiafei Pan orr w0, w0, #SYS_COUNTER_CNTCR_EN 785*9d250f03SJiafei Pan str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] 786*9d250f03SJiafei Pan1: 787*9d250f03SJiafei Pan /* 788*9d250f03SJiafei Pan * Enable dynamic retention control (CPUECTLR[2:0]) 789*9d250f03SJiafei Pan * Set the SMPEN bit (CPUECTLR[6]) 790*9d250f03SJiafei Pan */ 791*9d250f03SJiafei Pan mrs x1, CPUECTLR_EL1 792*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_RET_MASK 793*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_TIMER_2TICKS 794*9d250f03SJiafei Pan orr x1, x1, #CPUECTLR_SMPEN_EN 795*9d250f03SJiafei Pan msr CPUECTLR_EL1, x1 796*9d250f03SJiafei Pan 797*9d250f03SJiafei Pan isb 798*9d250f03SJiafei Pan ret 799*9d250f03SJiafei Pan 800*9d250f03SJiafei Pan/* 801*9d250f03SJiafei Pan * Part of CPU_SUSPEND 802*9d250f03SJiafei Pan * 803*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after power-down state 804*9d250f03SJiafei Pan * in: x0 = core mask lsb 805*9d250f03SJiafei Pan * out: none 806*9d250f03SJiafei Pan * uses none 807*9d250f03SJiafei Pan */ 808*9d250f03SJiafei Pan_soc_clstr_exit_pwrdn: 809*9d250f03SJiafei Pan ret 810*9d250f03SJiafei Pan 811*9d250f03SJiafei Pan/* 812*9d250f03SJiafei Pan * Part of CPU_SUSPEND 813*9d250f03SJiafei Pan * 814*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to standby 815*9d250f03SJiafei Pan * in: x0 = core mask lsb 816*9d250f03SJiafei Pan * out: none 817*9d250f03SJiafei Pan * uses x0, x1 818*9d250f03SJiafei Pan */ 819*9d250f03SJiafei Pan_soc_sys_prep_stdby: 820*9d250f03SJiafei Pan /* Clear CPUECTLR_EL1[2:0] */ 821*9d250f03SJiafei Pan mrs x1, CPUECTLR_EL1 822*9d250f03SJiafei Pan bic x1, x1, #CPUECTLR_TIMER_MASK 823*9d250f03SJiafei Pan msr CPUECTLR_EL1, x1 824*9d250f03SJiafei Pan 825*9d250f03SJiafei Pan ret 826*9d250f03SJiafei Pan 827*9d250f03SJiafei Pan/* 828*9d250f03SJiafei Pan * Part of CPU_SUSPEND 829*9d250f03SJiafei Pan * 830*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after standby state 831*9d250f03SJiafei Pan * in: x0 = core mask lsb 832*9d250f03SJiafei Pan * out: none 833*9d250f03SJiafei Pan * uses none 834*9d250f03SJiafei Pan */ 835*9d250f03SJiafei Pan_soc_sys_exit_stdby: 836*9d250f03SJiafei Pan ret 837*9d250f03SJiafei Pan 838*9d250f03SJiafei Pan/* 839*9d250f03SJiafei Pan * Part of CPU_SUSPEND 840*9d250f03SJiafei Pan * 841*9d250f03SJiafei Pan * This function performs SoC-specific programming prior to 842*9d250f03SJiafei Pan * suspend-to-power-down 843*9d250f03SJiafei Pan * in: x0 = core mask lsb 844*9d250f03SJiafei Pan * out: none 845*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4 846*9d250f03SJiafei Pan */ 847*9d250f03SJiafei Pan_soc_sys_prep_pwrdn: 848*9d250f03SJiafei Pan /* Set retention control */ 849*9d250f03SJiafei Pan mrs x0, CPUECTLR_EL1 850*9d250f03SJiafei Pan bic x0, x0, #CPUECTLR_TIMER_MASK 851*9d250f03SJiafei Pan orr x0, x0, #CPUECTLR_TIMER_2TICKS 852*9d250f03SJiafei Pan orr x0, x0, #CPUECTLR_SMPEN_EN 853*9d250f03SJiafei Pan msr CPUECTLR_EL1, x0 854*9d250f03SJiafei Pan dsb sy 855*9d250f03SJiafei Pan isb 856*9d250f03SJiafei Pan ret 857*9d250f03SJiafei Pan 858*9d250f03SJiafei Pan/* 859*9d250f03SJiafei Pan * Part of CPU_SUSPEND 860*9d250f03SJiafei Pan * 861*9d250f03SJiafei Pan * This function puts the calling core, and potentially the soc, into a 862*9d250f03SJiafei Pan * low-power state 863*9d250f03SJiafei Pan * in: x0 = core mask lsb 864*9d250f03SJiafei Pan * out: x0 = 0, success 865*9d250f03SJiafei Pan * x0 < 0, failure 866*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x13, x14, x15, 867*9d250f03SJiafei Pan * x16, x17, x18 868*9d250f03SJiafei Pan */ 869*9d250f03SJiafei Pan_soc_sys_pwrdn_wfi: 870*9d250f03SJiafei Pan mov x18, x30 871*9d250f03SJiafei Pan 872*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 873*9d250f03SJiafei Pan 874*9d250f03SJiafei Pan /* x3 = pmu base addr */ 875*9d250f03SJiafei Pan 876*9d250f03SJiafei Pan /* Backup epu registers to stack */ 877*9d250f03SJiafei Pan ldr x2, =NXP_EPU_ADDR 878*9d250f03SJiafei Pan ldr w4, [x2, #EPU_EPIMCR10_OFFSET] 879*9d250f03SJiafei Pan ldr w5, [x2, #EPU_EPCCR10_OFFSET] 880*9d250f03SJiafei Pan ldr w6, [x2, #EPU_EPCTR10_OFFSET] 881*9d250f03SJiafei Pan ldr w7, [x2, #EPU_EPGCR_OFFSET] 882*9d250f03SJiafei Pan stp x4, x5, [sp, #-16]! 883*9d250f03SJiafei Pan stp x6, x7, [sp, #-16]! 884*9d250f03SJiafei Pan 885*9d250f03SJiafei Pan /* 886*9d250f03SJiafei Pan * x2 = epu base addr 887*9d250f03SJiafei Pan * x3 = pmu base addr 888*9d250f03SJiafei Pan */ 889*9d250f03SJiafei Pan 890*9d250f03SJiafei Pan /* Set up EPU event to receive the wake signal from PMU */ 891*9d250f03SJiafei Pan mov w4, #EPU_EPIMCR10_VAL 892*9d250f03SJiafei Pan mov w5, #EPU_EPCCR10_VAL 893*9d250f03SJiafei Pan mov w6, #EPU_EPCTR10_VAL 894*9d250f03SJiafei Pan mov w7, #EPU_EPGCR_VAL 895*9d250f03SJiafei Pan str w4, [x2, #EPU_EPIMCR10_OFFSET] 896*9d250f03SJiafei Pan str w5, [x2, #EPU_EPCCR10_OFFSET] 897*9d250f03SJiafei Pan str w6, [x2, #EPU_EPCTR10_OFFSET] 898*9d250f03SJiafei Pan str w7, [x2, #EPU_EPGCR_OFFSET] 899*9d250f03SJiafei Pan 900*9d250f03SJiafei Pan ldr x2, =NXP_GICD_ADDR 901*9d250f03SJiafei Pan 902*9d250f03SJiafei Pan /* 903*9d250f03SJiafei Pan * x2 = gicd base addr 904*9d250f03SJiafei Pan * x3 = pmu base addr 905*9d250f03SJiafei Pan */ 906*9d250f03SJiafei Pan 907*9d250f03SJiafei Pan /* Backup flextimer/mmc/usb interrupt router */ 908*9d250f03SJiafei Pan ldr x0, =GICD_IROUTER60_OFFSET 909*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER76_OFFSET 910*9d250f03SJiafei Pan ldr w4, [x2, x0] 911*9d250f03SJiafei Pan ldr w5, [x2, x1] 912*9d250f03SJiafei Pan ldr x0, =GICD_IROUTER112_OFFSET 913*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER113_OFFSET 914*9d250f03SJiafei Pan ldr w6, [x2, x0] 915*9d250f03SJiafei Pan ldr w7, [x2, x1] 916*9d250f03SJiafei Pan stp x4, x5, [sp, #-16]! 917*9d250f03SJiafei Pan stp x6, x7, [sp, #-16]! 918*9d250f03SJiafei Pan 919*9d250f03SJiafei Pan /* 920*9d250f03SJiafei Pan * x2 = gicd base addr 921*9d250f03SJiafei Pan * x3 = pmu base addr 922*9d250f03SJiafei Pan * x0 = GICD_IROUTER112_OFFSET 923*9d250f03SJiafei Pan * x1 = GICD_IROUTER113_OFFSET 924*9d250f03SJiafei Pan */ 925*9d250f03SJiafei Pan 926*9d250f03SJiafei Pan /* Re-route interrupt to cluster 1 */ 927*9d250f03SJiafei Pan ldr w4, =GICD_IROUTER_VALUE 928*9d250f03SJiafei Pan str w4, [x2, x0] 929*9d250f03SJiafei Pan str w4, [x2, x1] 930*9d250f03SJiafei Pan ldr x0, =GICD_IROUTER60_OFFSET 931*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER76_OFFSET 932*9d250f03SJiafei Pan str w4, [x2, x0] 933*9d250f03SJiafei Pan str w4, [x2, x1] 934*9d250f03SJiafei Pan dsb sy 935*9d250f03SJiafei Pan isb 936*9d250f03SJiafei Pan 937*9d250f03SJiafei Pan /* x3 = pmu base addr */ 938*9d250f03SJiafei Pan 939*9d250f03SJiafei Pan /* Disable sec, Check for eNETC, spi and qspi */ 940*9d250f03SJiafei Pan ldr x2, =NXP_DCFG_ADDR 941*9d250f03SJiafei Pan ldr x0, =DCFG_DEVDISR1_OFFSET 942*9d250f03SJiafei Pan ldr w1, =DCFG_DEVDISR1_SEC 943*9d250f03SJiafei Pan str w1, [x2, x0] 944*9d250f03SJiafei Pan 945*9d250f03SJiafei Pan ldr x0, =DCFG_DEVDISR4_OFFSET 946*9d250f03SJiafei Pan ldr w1, =DCFG_DEVDISR4_SPI_QSPI 947*9d250f03SJiafei Pan str w1, [x2, x0] 948*9d250f03SJiafei Pan 949*9d250f03SJiafei Pan /* x3 = pmu base addr */ 950*9d250f03SJiafei Pan 951*9d250f03SJiafei Pan /* Set TPMWAKEMR0 */ 952*9d250f03SJiafei Pan ldr x0, =TPMWAKEMR0_ADDR 953*9d250f03SJiafei Pan mov w1, #0x1 954*9d250f03SJiafei Pan str w1, [x0] 955*9d250f03SJiafei Pan 956*9d250f03SJiafei Pan /* Disable CCI snoop domain */ 957*9d250f03SJiafei Pan ldr x0, =NXP_CCI_ADDR 958*9d250f03SJiafei Pan mov w1, #0x1 959*9d250f03SJiafei Pan str w1, [x0] 960*9d250f03SJiafei Pan 961*9d250f03SJiafei Pan /* Setup retention control */ 962*9d250f03SJiafei Pan mrs x0, CPUECTLR_EL1 963*9d250f03SJiafei Pan orr x0, x0, #CPUECTLR_SMPEN_EN 964*9d250f03SJiafei Pan orr x0, x0, #CPUECTLR_TIMER_2TICKS 965*9d250f03SJiafei Pan msr CPUECTLR_EL1, x0 966*9d250f03SJiafei Pan dsb sy 967*9d250f03SJiafei Pan isb 968*9d250f03SJiafei Pan 969*9d250f03SJiafei Pan bl get_pmu_idle_core_mask 970*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 971*9d250f03SJiafei Pan8: 972*9d250f03SJiafei Pan ldr w1, [x3, #PMU_PCPW20SR_OFFSET] 973*9d250f03SJiafei Pan cmp w1, w0 974*9d250f03SJiafei Pan b.ne 8b 975*9d250f03SJiafei Pan 976*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 977*9d250f03SJiafei Pan /* 1 cluster SoC */ 978*9d250f03SJiafei Pan 979*9d250f03SJiafei Pan bl get_pmu_idle_cluster_mask 980*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 981*9d250f03SJiafei Pan 982*9d250f03SJiafei Pan str w0, [x3, #PMU_CLAINACTSETR_OFFSET] 983*9d250f03SJiafei Pan 984*9d250f03SJiafei Pan bl get_pmu_idle_core_mask 985*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 986*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 987*9d250f03SJiafei Pan1: 988*9d250f03SJiafei Pan ldr w1, [x3, #PMU_PCPW20SR_OFFSET] 989*9d250f03SJiafei Pan cmp w1, w0 990*9d250f03SJiafei Pan b.ne 1b 991*9d250f03SJiafei Pan 992*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 993*9d250f03SJiafei Pan bl get_pmu_flush_cluster_mask 994*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 995*9d250f03SJiafei Pan 996*9d250f03SJiafei Pan str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET] 997*9d250f03SJiafei Pan 998*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 999*9d250f03SJiafei Pan2: 1000*9d250f03SJiafei Pan ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET] 1001*9d250f03SJiafei Pan cmp w1, w0 1002*9d250f03SJiafei Pan b.ne 2b 1003*9d250f03SJiafei Pan 1004*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 1005*9d250f03SJiafei Pan 1006*9d250f03SJiafei Pan str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET] 1007*9d250f03SJiafei Pan 1008*9d250f03SJiafei Pan str w0, [x3, #PMU_CLSINACTSETR_OFFSET] 1009*9d250f03SJiafei Pan 1010*9d250f03SJiafei Pan /* Force the debug interface to be quiescent */ 1011*9d250f03SJiafei Pan mrs x0, osdlr_el1 1012*9d250f03SJiafei Pan orr x0, x0, #0x1 1013*9d250f03SJiafei Pan msr osdlr_el1, x0 1014*9d250f03SJiafei Pan 1015*9d250f03SJiafei Pan /* 1016*9d250f03SJiafei Pan * Enable the WakeRequest signal 1017*9d250f03SJiafei Pan * x3 is cpu mask starting from cpu1 to cpu0 1018*9d250f03SJiafei Pan */ 1019*9d250f03SJiafei Pan bl get_tot_num_cores 1020*9d250f03SJiafei Pan sub x0, x0, #1 1021*9d250f03SJiafei Pan mov x3, #0x1 1022*9d250f03SJiafei Pan lsl x3, x3, x0 1023*9d250f03SJiafei Pan2: 1024*9d250f03SJiafei Pan mov x0, x3 1025*9d250f03SJiafei Pan bl get_gic_rd_base // 0-2 1026*9d250f03SJiafei Pan ldr w1, [x0, #GICR_WAKER_OFFSET] 1027*9d250f03SJiafei Pan orr w1, w1, #GICR_WAKER_SLEEP_BIT 1028*9d250f03SJiafei Pan str w1, [x0, #GICR_WAKER_OFFSET] 1029*9d250f03SJiafei Pan1: 1030*9d250f03SJiafei Pan ldr w1, [x0, #GICR_WAKER_OFFSET] 1031*9d250f03SJiafei Pan cmp w1, #GICR_WAKER_ASLEEP 1032*9d250f03SJiafei Pan b.ne 1b 1033*9d250f03SJiafei Pan 1034*9d250f03SJiafei Pan lsr x3, x3, #1 1035*9d250f03SJiafei Pan cbnz x3, 2b 1036*9d250f03SJiafei Pan 1037*9d250f03SJiafei Pan /* Invalidate all TLB entries at all 3 exception levels */ 1038*9d250f03SJiafei Pan tlbi alle1 1039*9d250f03SJiafei Pan tlbi alle2 1040*9d250f03SJiafei Pan tlbi alle3 1041*9d250f03SJiafei Pan 1042*9d250f03SJiafei Pan /* Request lpm20 */ 1043*9d250f03SJiafei Pan mov x3, #NXP_PMU_ADDR 1044*9d250f03SJiafei Pan ldr x0, =PMU_POWMGTCSR_OFFSET 1045*9d250f03SJiafei Pan ldr w1, =PMU_POWMGTCSR_VAL 1046*9d250f03SJiafei Pan str w1, [x3, x0] 1047*9d250f03SJiafei Pan 1048*9d250f03SJiafei Pan ldr x5, =NXP_EPU_ADDR 1049*9d250f03SJiafei Pan4: 1050*9d250f03SJiafei Pan wfe 1051*9d250f03SJiafei Pan ldr w1, [x5, #EPU_EPCTR10_OFFSET] 1052*9d250f03SJiafei Pan cmp w1, #0 1053*9d250f03SJiafei Pan b.eq 4b 1054*9d250f03SJiafei Pan 1055*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 1056*9d250f03SJiafei Pan 1057*9d250f03SJiafei Pan bl get_pmu_idle_cluster_mask 1058*9d250f03SJiafei Pan mov x3, NXP_PMU_ADDR 1059*9d250f03SJiafei Pan 1060*9d250f03SJiafei Pan /* Re-enable the GPP ACP */ 1061*9d250f03SJiafei Pan str w0, [x3, #PMU_CLAINACTCLRR_OFFSET] 1062*9d250f03SJiafei Pan str w0, [x3, #PMU_CLSINACTCLRR_OFFSET] 1063*9d250f03SJiafei Pan 1064*9d250f03SJiafei Pan /* x3 = NXP_PMU_ADDR */ 1065*9d250f03SJiafei Pan3: 1066*9d250f03SJiafei Pan ldr w1, [x3, #PMU_CLAINACTSETR_OFFSET] 1067*9d250f03SJiafei Pan cbnz w1, 3b 1068*9d250f03SJiafei Pan4: 1069*9d250f03SJiafei Pan ldr w1, [x3, #PMU_CLSINACTSETR_OFFSET] 1070*9d250f03SJiafei Pan cbnz w1, 4b 1071*9d250f03SJiafei Pan 1072*9d250f03SJiafei Pan /* 1073*9d250f03SJiafei Pan * Enable the WakeRequest signal on cpu 0-1 1074*9d250f03SJiafei Pan * x3 is cpu mask starting from cpu1 1075*9d250f03SJiafei Pan */ 1076*9d250f03SJiafei Pan bl get_tot_num_cores 1077*9d250f03SJiafei Pan sub x0, x0, #1 1078*9d250f03SJiafei Pan mov x3, #0x1 1079*9d250f03SJiafei Pan lsl x3, x3, x0 1080*9d250f03SJiafei Pan2: 1081*9d250f03SJiafei Pan mov x0, x3 1082*9d250f03SJiafei Pan bl get_gic_rd_base // 0-2 1083*9d250f03SJiafei Pan ldr w1, [x0, #GICR_WAKER_OFFSET] 1084*9d250f03SJiafei Pan bic w1, w1, #GICR_WAKER_SLEEP_BIT 1085*9d250f03SJiafei Pan str w1, [x0, #GICR_WAKER_OFFSET] 1086*9d250f03SJiafei Pan1: 1087*9d250f03SJiafei Pan ldr w1, [x0, #GICR_WAKER_OFFSET] 1088*9d250f03SJiafei Pan cbnz w1, 1b 1089*9d250f03SJiafei Pan 1090*9d250f03SJiafei Pan lsr x3, x3, #1 1091*9d250f03SJiafei Pan cbnz x3, 2b 1092*9d250f03SJiafei Pan 1093*9d250f03SJiafei Pan /* Enable CCI snoop domain */ 1094*9d250f03SJiafei Pan ldr x0, =NXP_CCI_ADDR 1095*9d250f03SJiafei Pan str wzr, [x0] 1096*9d250f03SJiafei Pan dsb sy 1097*9d250f03SJiafei Pan isb 1098*9d250f03SJiafei Pan 1099*9d250f03SJiafei Pan ldr x3, =NXP_EPU_ADDR 1100*9d250f03SJiafei Pan 1101*9d250f03SJiafei Pan /* x3 = epu base addr */ 1102*9d250f03SJiafei Pan 1103*9d250f03SJiafei Pan /* Enable sec, enetc, spi and qspi */ 1104*9d250f03SJiafei Pan ldr x2, =NXP_DCFG_ADDR 1105*9d250f03SJiafei Pan str wzr, [x2, #DCFG_DEVDISR1_OFFSET] 1106*9d250f03SJiafei Pan str wzr, [x2, #DCFG_DEVDISR2_OFFSET] 1107*9d250f03SJiafei Pan str wzr, [x2, #DCFG_DEVDISR4_OFFSET] 1108*9d250f03SJiafei Pan 1109*9d250f03SJiafei Pan /* Restore flextimer/mmc/usb interrupt router */ 1110*9d250f03SJiafei Pan ldr x3, =NXP_GICD_ADDR 1111*9d250f03SJiafei Pan ldp x0, x2, [sp], #16 1112*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER113_OFFSET 1113*9d250f03SJiafei Pan str w2, [x3, x1] 1114*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER112_OFFSET 1115*9d250f03SJiafei Pan str w0, [x3, x1] 1116*9d250f03SJiafei Pan ldp x0, x2, [sp], #16 1117*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER76_OFFSET 1118*9d250f03SJiafei Pan str w2, [x3, x1] 1119*9d250f03SJiafei Pan ldr x1, =GICD_IROUTER60_OFFSET 1120*9d250f03SJiafei Pan str w0, [x3, x1] 1121*9d250f03SJiafei Pan 1122*9d250f03SJiafei Pan /* Restore EPU registers */ 1123*9d250f03SJiafei Pan ldr x3, =NXP_EPU_ADDR 1124*9d250f03SJiafei Pan ldp x0, x2, [sp], #16 1125*9d250f03SJiafei Pan str w2, [x3, #EPU_EPGCR_OFFSET] 1126*9d250f03SJiafei Pan str w0, [x3, #EPU_EPCTR10_OFFSET] 1127*9d250f03SJiafei Pan ldp x2, x1, [sp], #16 1128*9d250f03SJiafei Pan str w1, [x3, #EPU_EPCCR10_OFFSET] 1129*9d250f03SJiafei Pan str w2, [x3, #EPU_EPIMCR10_OFFSET] 1130*9d250f03SJiafei Pan 1131*9d250f03SJiafei Pan dsb sy 1132*9d250f03SJiafei Pan isb 1133*9d250f03SJiafei Pan mov x30, x18 1134*9d250f03SJiafei Pan ret 1135*9d250f03SJiafei Pan 1136*9d250f03SJiafei Pan/* 1137*9d250f03SJiafei Pan * Part of CPU_SUSPEND 1138*9d250f03SJiafei Pan * 1139*9d250f03SJiafei Pan * This function performs any SoC-specific cleanup after power-down 1140*9d250f03SJiafei Pan * in: x0 = core mask lsb 1141*9d250f03SJiafei Pan * out: none 1142*9d250f03SJiafei Pan * uses x0, x1 1143*9d250f03SJiafei Pan */ 1144*9d250f03SJiafei Pan_soc_sys_exit_pwrdn: 1145*9d250f03SJiafei Pan /* Enable stack alignment checking */ 1146*9d250f03SJiafei Pan mrs x1, SCTLR_EL1 1147*9d250f03SJiafei Pan orr x1, x1, #0x4 1148*9d250f03SJiafei Pan msr SCTLR_EL1, x1 1149*9d250f03SJiafei Pan 1150*9d250f03SJiafei Pan /* Enable debug interface */ 1151*9d250f03SJiafei Pan mrs x1, osdlr_el1 1152*9d250f03SJiafei Pan bic x1, x1, #OSDLR_EL1_DLK_LOCK 1153*9d250f03SJiafei Pan msr osdlr_el1, x1 1154*9d250f03SJiafei Pan 1155*9d250f03SJiafei Pan /* Enable i-cache */ 1156*9d250f03SJiafei Pan mrs x1, SCTLR_EL3 1157*9d250f03SJiafei Pan orr x1, x1, #SCTLR_I_MASK 1158*9d250f03SJiafei Pan msr SCTLR_EL3, x1 1159*9d250f03SJiafei Pan 1160*9d250f03SJiafei Pan isb 1161*9d250f03SJiafei Pan ret 1162*9d250f03SJiafei Pan 1163*9d250f03SJiafei Pan/* 1164*9d250f03SJiafei Pan * This function setc up the TrustZone Address Space Controller (TZASC) 1165*9d250f03SJiafei Pan * in: none 1166*9d250f03SJiafei Pan * out: none 1167*9d250f03SJiafei Pan * uses x0, x1 1168*9d250f03SJiafei Pan */ 1169*9d250f03SJiafei Paninit_tzpc: 1170*9d250f03SJiafei Pan /* Set Non Secure access for all devices protected via TZPC */ 1171*9d250f03SJiafei Pan ldr x1, =TZPCDECPROT_0_SET_BASE /* decode Protection-0 Set Reg */ 1172*9d250f03SJiafei Pan mov w0, #0xFF /* set decode region to NS, Bits[7:0] */ 1173*9d250f03SJiafei Pan str w0, [x1] 1174*9d250f03SJiafei Pan 1175*9d250f03SJiafei Pan ldr x1, =TZPCDECPROT_1_SET_BASE /* decode Protection-1 Set Reg */ 1176*9d250f03SJiafei Pan mov w0, #0xFF /* set decode region to NS, Bits[7:0] */ 1177*9d250f03SJiafei Pan str w0, [x1] 1178*9d250f03SJiafei Pan 1179*9d250f03SJiafei Pan ldr x1, =TZPCDECPROT_2_SET_BASE /* decode Protection-2 Set Reg */ 1180*9d250f03SJiafei Pan mov w0, #0xFF /* set decode region to NS, Bits[7:0] */ 1181*9d250f03SJiafei Pan str w0, [x1] 1182*9d250f03SJiafei Pan 1183*9d250f03SJiafei Pan /* entire SRAM as NS */ 1184*9d250f03SJiafei Pan ldr x1, =NXP_OCRAM_TZPC_ADDR /* secure RAM region size Reg */ 1185*9d250f03SJiafei Pan mov w0, #0x00000000 /* 0x00000000 = no secure region */ 1186*9d250f03SJiafei Pan str w0, [x1] 1187*9d250f03SJiafei Pan 1188*9d250f03SJiafei Pan ret 1189*9d250f03SJiafei Pan 1190*9d250f03SJiafei Pan/* 1191*9d250f03SJiafei Pan * This function performs any needed initialization on SecMon for 1192*9d250f03SJiafei Pan * boot services 1193*9d250f03SJiafei Pan */ 1194*9d250f03SJiafei PaninitSecMon: 1195*9d250f03SJiafei Pan /* Read the register hpcomr */ 1196*9d250f03SJiafei Pan ldr x1, =NXP_SNVS_ADDR 1197*9d250f03SJiafei Pan ldr w0, [x1, #SECMON_HPCOMR_OFFSET] 1198*9d250f03SJiafei Pan /* Turn off secure access for the privileged registers */ 1199*9d250f03SJiafei Pan orr w0, w0, #SECMON_HPCOMR_NPSWAEN 1200*9d250f03SJiafei Pan /* Write back */ 1201*9d250f03SJiafei Pan str w0, [x1, #SECMON_HPCOMR_OFFSET] 1202*9d250f03SJiafei Pan 1203*9d250f03SJiafei Pan ret 1204*9d250f03SJiafei Pan 1205*9d250f03SJiafei Pan/* 1206*9d250f03SJiafei Pan * This function checks to see if cores which are to be disabled have been 1207*9d250f03SJiafei Pan * released from reset - if not, it releases them 1208*9d250f03SJiafei Pan * in: none 1209*9d250f03SJiafei Pan * out: none 1210*9d250f03SJiafei Pan * uses x0, x1, x2, x3, x4, x5, x6, x7, x8 1211*9d250f03SJiafei Pan */ 1212*9d250f03SJiafei Panrelease_disabled: 1213*9d250f03SJiafei Pan stp x18, x30, [sp, #-16]! 1214*9d250f03SJiafei Pan 1215*9d250f03SJiafei Pan /* 1216*9d250f03SJiafei Pan * Get the number of cpus on this device 1217*9d250f03SJiafei Pan * Calling the below c function. 1218*9d250f03SJiafei Pan * No need to Callee saved registers x9-x15, 1219*9d250f03SJiafei Pan * as these registers are not used by the callee 1220*9d250f03SJiafei Pan * prior to calling the below C-routine. 1221*9d250f03SJiafei Pan */ 1222*9d250f03SJiafei Pan bl get_tot_num_cores 1223*9d250f03SJiafei Pan mov x6, x0 1224*9d250f03SJiafei Pan 1225*9d250f03SJiafei Pan /* Read COREDISABLESR */ 1226*9d250f03SJiafei Pan mov x0, #NXP_DCFG_ADDR 1227*9d250f03SJiafei Pan ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET] 1228*9d250f03SJiafei Pan 1229*9d250f03SJiafei Pan mov x0, #NXP_RESET_ADDR 1230*9d250f03SJiafei Pan ldr w5, [x0, #BRR_OFFSET] 1231*9d250f03SJiafei Pan 1232*9d250f03SJiafei Pan /* Load the core mask for the first core */ 1233*9d250f03SJiafei Pan mov x7, #1 1234*9d250f03SJiafei Pan 1235*9d250f03SJiafei Pan /* 1236*9d250f03SJiafei Pan * x4 = COREDISABLESR 1237*9d250f03SJiafei Pan * x5 = BRR 1238*9d250f03SJiafei Pan * x6 = loop count 1239*9d250f03SJiafei Pan * x7 = core mask bit 1240*9d250f03SJiafei Pan */ 1241*9d250f03SJiafei Pan2: 1242*9d250f03SJiafei Pan /* Check if the core is to be disabled */ 1243*9d250f03SJiafei Pan tst x4, x7 1244*9d250f03SJiafei Pan b.eq 1f 1245*9d250f03SJiafei Pan 1246*9d250f03SJiafei Pan /* See if disabled cores have already been released from reset */ 1247*9d250f03SJiafei Pan tst x5, x7 1248*9d250f03SJiafei Pan b.ne 1f 1249*9d250f03SJiafei Pan 1250*9d250f03SJiafei Pan /* If core has not been released, then release it (0-3) */ 1251*9d250f03SJiafei Pan mov x0, x7 1252*9d250f03SJiafei Pan bl _soc_core_release 1253*9d250f03SJiafei Pan 1254*9d250f03SJiafei Pan /* Record the core state in the data area (0-3) */ 1255*9d250f03SJiafei Pan mov x0, x7 1256*9d250f03SJiafei Pan mov x1, #CORE_DISABLED 1257*9d250f03SJiafei Pan bl _setCoreState 1258*9d250f03SJiafei Pan1: 1259*9d250f03SJiafei Pan /* Decrement the counter */ 1260*9d250f03SJiafei Pan subs x6, x6, #1 1261*9d250f03SJiafei Pan b.le 3f 1262*9d250f03SJiafei Pan /* Shift the core mask to the next core */ 1263*9d250f03SJiafei Pan lsl x7, x7, #1 1264*9d250f03SJiafei Pan /* Continue */ 1265*9d250f03SJiafei Pan b 2b 1266*9d250f03SJiafei Pan3: 1267*9d250f03SJiafei Pan ldp x18, x30, [sp], #16 1268*9d250f03SJiafei Pan ret 1269*9d250f03SJiafei Pan 1270*9d250f03SJiafei Pan/* 1271*9d250f03SJiafei Pan * Write a register in the DCFG block 1272*9d250f03SJiafei Pan * in: x0 = offset 1273*9d250f03SJiafei Pan * in: w1 = value to write 1274*9d250f03SJiafei Pan * uses x0, x1, x2 1275*9d250f03SJiafei Pan */ 1276*9d250f03SJiafei Pan_write_reg_dcfg: 1277*9d250f03SJiafei Pan ldr x2, =NXP_DCFG_ADDR 1278*9d250f03SJiafei Pan str w1, [x2, x0] 1279*9d250f03SJiafei Pan ret 1280*9d250f03SJiafei Pan 1281*9d250f03SJiafei Pan/* 1282*9d250f03SJiafei Pan * Read a register in the DCFG block 1283*9d250f03SJiafei Pan * in: x0 = offset 1284*9d250f03SJiafei Pan * out: w0 = value read 1285*9d250f03SJiafei Pan * uses x0, x1, x2 1286*9d250f03SJiafei Pan */ 1287*9d250f03SJiafei Pan_read_reg_dcfg: 1288*9d250f03SJiafei Pan ldr x2, =NXP_DCFG_ADDR 1289*9d250f03SJiafei Pan ldr w1, [x2, x0] 1290*9d250f03SJiafei Pan mov w0, w1 1291*9d250f03SJiafei Pan ret 1292*9d250f03SJiafei Pan 1293*9d250f03SJiafei Pan/* 1294*9d250f03SJiafei Pan * This function returns an mpidr value for a core, given a core_mask_lsb 1295*9d250f03SJiafei Pan * in: x0 = core mask lsb 1296*9d250f03SJiafei Pan * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits 1297*9d250f03SJiafei Pan * uses x0, x1 1298*9d250f03SJiafei Pan */ 1299*9d250f03SJiafei Panget_mpidr_value: 1300*9d250f03SJiafei Pan /* Convert a core mask to an SoC core number */ 1301*9d250f03SJiafei Pan clz w0, w0 1302*9d250f03SJiafei Pan mov w1, #31 1303*9d250f03SJiafei Pan sub w0, w1, w0 1304*9d250f03SJiafei Pan 1305*9d250f03SJiafei Pan /* Get the mpidr core number from the SoC core number */ 1306*9d250f03SJiafei Pan mov w1, wzr 1307*9d250f03SJiafei Pan tst x0, #1 1308*9d250f03SJiafei Pan b.eq 1f 1309*9d250f03SJiafei Pan orr w1, w1, #1 1310*9d250f03SJiafei Pan1: 1311*9d250f03SJiafei Pan /* Extract the cluster number */ 1312*9d250f03SJiafei Pan lsr w0, w0, #1 1313*9d250f03SJiafei Pan orr w0, w1, w0, lsl #8 1314*9d250f03SJiafei Pan 1315*9d250f03SJiafei Pan ret 1316*9d250f03SJiafei Pan 1317*9d250f03SJiafei Pan/* 1318*9d250f03SJiafei Pan * This function returns the redistributor base address for the core specified 1319*9d250f03SJiafei Pan * in x1 1320*9d250f03SJiafei Pan * in: x0 - core mask lsb of specified core 1321*9d250f03SJiafei Pan * out: x0 = redistributor rd base address for specified core 1322*9d250f03SJiafei Pan * uses x0, x1, x2 1323*9d250f03SJiafei Pan */ 1324*9d250f03SJiafei Panget_gic_rd_base: 1325*9d250f03SJiafei Pan /* Get the 0-based core number */ 1326*9d250f03SJiafei Pan clz w1, w0 1327*9d250f03SJiafei Pan mov w2, #0x20 1328*9d250f03SJiafei Pan sub w2, w2, w1 1329*9d250f03SJiafei Pan sub w2, w2, #1 1330*9d250f03SJiafei Pan 1331*9d250f03SJiafei Pan /* x2 = core number / loop counter */ 1332*9d250f03SJiafei Pan ldr x0, =NXP_GICR_ADDR 1333*9d250f03SJiafei Pan mov x1, #GIC_RD_OFFSET 1334*9d250f03SJiafei Pan2: 1335*9d250f03SJiafei Pan cbz x2, 1f 1336*9d250f03SJiafei Pan add x0, x0, x1 1337*9d250f03SJiafei Pan sub x2, x2, #1 1338*9d250f03SJiafei Pan b 2b 1339*9d250f03SJiafei Pan1: 1340*9d250f03SJiafei Pan ret 1341*9d250f03SJiafei Pan 1342*9d250f03SJiafei Pan/* 1343*9d250f03SJiafei Pan * This function returns the redistributor base address for the core specified 1344*9d250f03SJiafei Pan * in x1 1345*9d250f03SJiafei Pan * in: x0 - core mask lsb of specified core 1346*9d250f03SJiafei Pan * out: x0 = redistributor sgi base address for specified core 1347*9d250f03SJiafei Pan * uses x0, x1, x2 1348*9d250f03SJiafei Pan */ 1349*9d250f03SJiafei Panget_gic_sgi_base: 1350*9d250f03SJiafei Pan /* Get the 0-based core number */ 1351*9d250f03SJiafei Pan clz w1, w0 1352*9d250f03SJiafei Pan mov w2, #0x20 1353*9d250f03SJiafei Pan sub w2, w2, w1 1354*9d250f03SJiafei Pan sub w2, w2, #1 1355*9d250f03SJiafei Pan 1356*9d250f03SJiafei Pan /* x2 = core number / loop counter */ 1357*9d250f03SJiafei Pan ldr x0, =NXP_GICR_SGI_ADDR 1358*9d250f03SJiafei Pan mov x1, #GIC_SGI_OFFSET 1359*9d250f03SJiafei Pan2: 1360*9d250f03SJiafei Pan cbz x2, 1f 1361*9d250f03SJiafei Pan add x0, x0, x1 1362*9d250f03SJiafei Pan sub x2, x2, #1 1363*9d250f03SJiafei Pan b 2b 1364*9d250f03SJiafei Pan1: 1365*9d250f03SJiafei Pan ret 1366*9d250f03SJiafei Pan 1367*9d250f03SJiafei Pan/* 1368*9d250f03SJiafei Pan * Write a register in the RESET block 1369*9d250f03SJiafei Pan * in: x0 = offset 1370*9d250f03SJiafei Pan * in: w1 = value to write 1371*9d250f03SJiafei Pan * uses x0, x1, x2 1372*9d250f03SJiafei Pan */ 1373*9d250f03SJiafei Pan_write_reg_reset: 1374*9d250f03SJiafei Pan ldr x2, =NXP_RESET_ADDR 1375*9d250f03SJiafei Pan str w1, [x2, x0] 1376*9d250f03SJiafei Pan ret 1377*9d250f03SJiafei Pan 1378*9d250f03SJiafei Pan/* 1379*9d250f03SJiafei Pan * Read a register in the RESET block 1380*9d250f03SJiafei Pan * in: x0 = offset 1381*9d250f03SJiafei Pan * out: w0 = value read 1382*9d250f03SJiafei Pan * uses x0, x1 1383*9d250f03SJiafei Pan */ 1384*9d250f03SJiafei Pan_read_reg_reset: 1385*9d250f03SJiafei Pan ldr x1, =NXP_RESET_ADDR 1386*9d250f03SJiafei Pan ldr w0, [x1, x0] 1387*9d250f03SJiafei Pan ret 1388