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