1*dd4268a2SPankaj Gupta /* 2*dd4268a2SPankaj Gupta * Copyright 2018-2020 NXP 3*dd4268a2SPankaj Gupta * 4*dd4268a2SPankaj Gupta * SPDX-License-Identifier: BSD-3-Clause 5*dd4268a2SPankaj Gupta * 6*dd4268a2SPankaj Gupta */ 7*dd4268a2SPankaj Gupta 8*dd4268a2SPankaj Gupta #include <common/debug.h> 9*dd4268a2SPankaj Gupta 10*dd4268a2SPankaj Gupta #include <plat_gic.h> 11*dd4268a2SPankaj Gupta #include <plat_common.h> 12*dd4268a2SPankaj Gupta #include <plat_psci.h> 13*dd4268a2SPankaj Gupta #ifdef NXP_WARM_BOOT 14*dd4268a2SPankaj Gupta #include <plat_warm_rst.h> 15*dd4268a2SPankaj Gupta #endif 16*dd4268a2SPankaj Gupta 17*dd4268a2SPankaj Gupta #include <platform_def.h> 18*dd4268a2SPankaj Gupta 19*dd4268a2SPankaj Gupta #if (SOC_CORE_OFF || SOC_CORE_PWR_DWN) 20*dd4268a2SPankaj Gupta static void __dead2 _no_return_wfi(void) 21*dd4268a2SPankaj Gupta { 22*dd4268a2SPankaj Gupta _bl31_dead_wfi: 23*dd4268a2SPankaj Gupta wfi(); 24*dd4268a2SPankaj Gupta goto _bl31_dead_wfi; 25*dd4268a2SPankaj Gupta } 26*dd4268a2SPankaj Gupta #endif 27*dd4268a2SPankaj Gupta 28*dd4268a2SPankaj Gupta #if (SOC_CORE_RELEASE || SOC_CORE_PWR_DWN) 29*dd4268a2SPankaj Gupta /* the entry for core warm boot */ 30*dd4268a2SPankaj Gupta static uintptr_t warmboot_entry = (uintptr_t) NULL; 31*dd4268a2SPankaj Gupta #endif 32*dd4268a2SPankaj Gupta 33*dd4268a2SPankaj Gupta #if (SOC_CORE_RELEASE) 34*dd4268a2SPankaj Gupta static int _pwr_domain_on(u_register_t mpidr) 35*dd4268a2SPankaj Gupta { 36*dd4268a2SPankaj Gupta int core_pos = plat_core_pos(mpidr); 37*dd4268a2SPankaj Gupta int rc = PSCI_E_INVALID_PARAMS; 38*dd4268a2SPankaj Gupta u_register_t core_mask; 39*dd4268a2SPankaj Gupta 40*dd4268a2SPankaj Gupta if (core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT) { 41*dd4268a2SPankaj Gupta 42*dd4268a2SPankaj Gupta _soc_set_start_addr(warmboot_entry); 43*dd4268a2SPankaj Gupta 44*dd4268a2SPankaj Gupta dsb(); 45*dd4268a2SPankaj Gupta isb(); 46*dd4268a2SPankaj Gupta 47*dd4268a2SPankaj Gupta core_mask = (1 << core_pos); 48*dd4268a2SPankaj Gupta rc = _psci_cpu_on(core_mask); 49*dd4268a2SPankaj Gupta } 50*dd4268a2SPankaj Gupta 51*dd4268a2SPankaj Gupta return (rc); 52*dd4268a2SPankaj Gupta } 53*dd4268a2SPankaj Gupta #endif 54*dd4268a2SPankaj Gupta 55*dd4268a2SPankaj Gupta #if (SOC_CORE_OFF) 56*dd4268a2SPankaj Gupta static void _pwr_domain_off(const psci_power_state_t *target_state) 57*dd4268a2SPankaj Gupta { 58*dd4268a2SPankaj Gupta u_register_t core_mask = plat_my_core_mask(); 59*dd4268a2SPankaj Gupta u_register_t core_state = _getCoreState(core_mask); 60*dd4268a2SPankaj Gupta 61*dd4268a2SPankaj Gupta /* set core state in internal data */ 62*dd4268a2SPankaj Gupta core_state = CORE_OFF_PENDING; 63*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 64*dd4268a2SPankaj Gupta 65*dd4268a2SPankaj Gupta _psci_cpu_prep_off(core_mask); 66*dd4268a2SPankaj Gupta } 67*dd4268a2SPankaj Gupta #endif 68*dd4268a2SPankaj Gupta 69*dd4268a2SPankaj Gupta #if (SOC_CORE_OFF || SOC_CORE_PWR_DWN) 70*dd4268a2SPankaj Gupta static void __dead2 _pwr_down_wfi(const psci_power_state_t *target_state) 71*dd4268a2SPankaj Gupta { 72*dd4268a2SPankaj Gupta u_register_t core_mask = plat_my_core_mask(); 73*dd4268a2SPankaj Gupta u_register_t core_state = _getCoreState(core_mask); 74*dd4268a2SPankaj Gupta 75*dd4268a2SPankaj Gupta switch (core_state) { 76*dd4268a2SPankaj Gupta #if (SOC_CORE_OFF) 77*dd4268a2SPankaj Gupta case CORE_OFF_PENDING: 78*dd4268a2SPankaj Gupta /* set core state in internal data */ 79*dd4268a2SPankaj Gupta core_state = CORE_OFF; 80*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 81*dd4268a2SPankaj Gupta 82*dd4268a2SPankaj Gupta /* turn the core off */ 83*dd4268a2SPankaj Gupta _psci_cpu_off_wfi(core_mask, warmboot_entry); 84*dd4268a2SPankaj Gupta break; 85*dd4268a2SPankaj Gupta #endif 86*dd4268a2SPankaj Gupta #if (SOC_CORE_PWR_DWN) 87*dd4268a2SPankaj Gupta case CORE_PWR_DOWN: 88*dd4268a2SPankaj Gupta /* power-down the core */ 89*dd4268a2SPankaj Gupta _psci_cpu_pwrdn_wfi(core_mask, warmboot_entry); 90*dd4268a2SPankaj Gupta break; 91*dd4268a2SPankaj Gupta #endif 92*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_PWR_DWN) 93*dd4268a2SPankaj Gupta case SYS_OFF_PENDING: 94*dd4268a2SPankaj Gupta /* set core state in internal data */ 95*dd4268a2SPankaj Gupta core_state = SYS_OFF; 96*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 97*dd4268a2SPankaj Gupta 98*dd4268a2SPankaj Gupta /* power-down the system */ 99*dd4268a2SPankaj Gupta _psci_sys_pwrdn_wfi(core_mask, warmboot_entry); 100*dd4268a2SPankaj Gupta break; 101*dd4268a2SPankaj Gupta #endif 102*dd4268a2SPankaj Gupta default: 103*dd4268a2SPankaj Gupta _no_return_wfi(); 104*dd4268a2SPankaj Gupta break; 105*dd4268a2SPankaj Gupta } 106*dd4268a2SPankaj Gupta } 107*dd4268a2SPankaj Gupta #endif 108*dd4268a2SPankaj Gupta 109*dd4268a2SPankaj Gupta #if (SOC_CORE_RELEASE || SOC_CORE_RESTART) 110*dd4268a2SPankaj Gupta static void _pwr_domain_wakeup(const psci_power_state_t *target_state) 111*dd4268a2SPankaj Gupta { 112*dd4268a2SPankaj Gupta u_register_t core_mask = plat_my_core_mask(); 113*dd4268a2SPankaj Gupta u_register_t core_state = _getCoreState(core_mask); 114*dd4268a2SPankaj Gupta 115*dd4268a2SPankaj Gupta switch (core_state) { 116*dd4268a2SPankaj Gupta case CORE_PENDING: /* this core is coming out of reset */ 117*dd4268a2SPankaj Gupta 118*dd4268a2SPankaj Gupta /* soc per cpu setup */ 119*dd4268a2SPankaj Gupta soc_init_percpu(); 120*dd4268a2SPankaj Gupta 121*dd4268a2SPankaj Gupta /* gic per cpu setup */ 122*dd4268a2SPankaj Gupta plat_gic_pcpu_init(); 123*dd4268a2SPankaj Gupta 124*dd4268a2SPankaj Gupta /* set core state in internal data */ 125*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 126*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 127*dd4268a2SPankaj Gupta break; 128*dd4268a2SPankaj Gupta 129*dd4268a2SPankaj Gupta #if (SOC_CORE_RESTART) 130*dd4268a2SPankaj Gupta case CORE_WAKEUP: 131*dd4268a2SPankaj Gupta 132*dd4268a2SPankaj Gupta /* this core is waking up from OFF */ 133*dd4268a2SPankaj Gupta _psci_wakeup(core_mask); 134*dd4268a2SPankaj Gupta 135*dd4268a2SPankaj Gupta /* set core state in internal data */ 136*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 137*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 138*dd4268a2SPankaj Gupta 139*dd4268a2SPankaj Gupta break; 140*dd4268a2SPankaj Gupta #endif 141*dd4268a2SPankaj Gupta } 142*dd4268a2SPankaj Gupta } 143*dd4268a2SPankaj Gupta #endif 144*dd4268a2SPankaj Gupta 145*dd4268a2SPankaj Gupta #if (SOC_CORE_STANDBY) 146*dd4268a2SPankaj Gupta static void _pwr_cpu_standby(plat_local_state_t cpu_state) 147*dd4268a2SPankaj Gupta { 148*dd4268a2SPankaj Gupta u_register_t core_mask = plat_my_core_mask(); 149*dd4268a2SPankaj Gupta u_register_t core_state; 150*dd4268a2SPankaj Gupta 151*dd4268a2SPankaj Gupta if (cpu_state == PLAT_MAX_RET_STATE) { 152*dd4268a2SPankaj Gupta 153*dd4268a2SPankaj Gupta /* set core state to standby */ 154*dd4268a2SPankaj Gupta core_state = CORE_STANDBY; 155*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 156*dd4268a2SPankaj Gupta 157*dd4268a2SPankaj Gupta _psci_core_entr_stdby(core_mask); 158*dd4268a2SPankaj Gupta 159*dd4268a2SPankaj Gupta /* when we are here, the core is waking up 160*dd4268a2SPankaj Gupta * set core state to released 161*dd4268a2SPankaj Gupta */ 162*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 163*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 164*dd4268a2SPankaj Gupta } 165*dd4268a2SPankaj Gupta } 166*dd4268a2SPankaj Gupta #endif 167*dd4268a2SPankaj Gupta 168*dd4268a2SPankaj Gupta #if (SOC_CORE_PWR_DWN) 169*dd4268a2SPankaj Gupta static void _pwr_suspend(const psci_power_state_t *state) 170*dd4268a2SPankaj Gupta { 171*dd4268a2SPankaj Gupta 172*dd4268a2SPankaj Gupta u_register_t core_mask = plat_my_core_mask(); 173*dd4268a2SPankaj Gupta u_register_t core_state; 174*dd4268a2SPankaj Gupta 175*dd4268a2SPankaj Gupta if (state->pwr_domain_state[PLAT_MAX_LVL] == PLAT_MAX_OFF_STATE) { 176*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_PWR_DWN) 177*dd4268a2SPankaj Gupta _psci_sys_prep_pwrdn(core_mask); 178*dd4268a2SPankaj Gupta 179*dd4268a2SPankaj Gupta /* set core state */ 180*dd4268a2SPankaj Gupta core_state = SYS_OFF_PENDING; 181*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 182*dd4268a2SPankaj Gupta #endif 183*dd4268a2SPankaj Gupta } else if (state->pwr_domain_state[PLAT_MAX_LVL] 184*dd4268a2SPankaj Gupta == PLAT_MAX_RET_STATE) { 185*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_STANDBY) 186*dd4268a2SPankaj Gupta _psci_sys_prep_stdby(core_mask); 187*dd4268a2SPankaj Gupta 188*dd4268a2SPankaj Gupta /* set core state */ 189*dd4268a2SPankaj Gupta core_state = CORE_STANDBY; 190*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 191*dd4268a2SPankaj Gupta #endif 192*dd4268a2SPankaj Gupta } 193*dd4268a2SPankaj Gupta 194*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CLSTR_LVL] == 195*dd4268a2SPankaj Gupta PLAT_MAX_OFF_STATE) { 196*dd4268a2SPankaj Gupta #if (SOC_CLUSTER_PWR_DWN) 197*dd4268a2SPankaj Gupta _psci_clstr_prep_pwrdn(core_mask); 198*dd4268a2SPankaj Gupta 199*dd4268a2SPankaj Gupta /* set core state */ 200*dd4268a2SPankaj Gupta core_state = CORE_PWR_DOWN; 201*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 202*dd4268a2SPankaj Gupta #endif 203*dd4268a2SPankaj Gupta } 204*dd4268a2SPankaj Gupta 205*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CLSTR_LVL] == 206*dd4268a2SPankaj Gupta PLAT_MAX_RET_STATE) { 207*dd4268a2SPankaj Gupta #if (SOC_CLUSTER_STANDBY) 208*dd4268a2SPankaj Gupta _psci_clstr_prep_stdby(core_mask); 209*dd4268a2SPankaj Gupta 210*dd4268a2SPankaj Gupta /* set core state */ 211*dd4268a2SPankaj Gupta core_state = CORE_STANDBY; 212*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 213*dd4268a2SPankaj Gupta #endif 214*dd4268a2SPankaj Gupta } 215*dd4268a2SPankaj Gupta 216*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_OFF_STATE) { 217*dd4268a2SPankaj Gupta #if (SOC_CORE_PWR_DWN) 218*dd4268a2SPankaj Gupta /* prep the core for power-down */ 219*dd4268a2SPankaj Gupta _psci_core_prep_pwrdn(core_mask); 220*dd4268a2SPankaj Gupta 221*dd4268a2SPankaj Gupta /* set core state */ 222*dd4268a2SPankaj Gupta core_state = CORE_PWR_DOWN; 223*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 224*dd4268a2SPankaj Gupta #endif 225*dd4268a2SPankaj Gupta } 226*dd4268a2SPankaj Gupta 227*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_RET_STATE) { 228*dd4268a2SPankaj Gupta #if (SOC_CORE_STANDBY) 229*dd4268a2SPankaj Gupta _psci_core_prep_stdby(core_mask); 230*dd4268a2SPankaj Gupta 231*dd4268a2SPankaj Gupta /* set core state */ 232*dd4268a2SPankaj Gupta core_state = CORE_STANDBY; 233*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 234*dd4268a2SPankaj Gupta #endif 235*dd4268a2SPankaj Gupta } 236*dd4268a2SPankaj Gupta 237*dd4268a2SPankaj Gupta } 238*dd4268a2SPankaj Gupta #endif 239*dd4268a2SPankaj Gupta 240*dd4268a2SPankaj Gupta #if (SOC_CORE_PWR_DWN) 241*dd4268a2SPankaj Gupta static void _pwr_suspend_finish(const psci_power_state_t *state) 242*dd4268a2SPankaj Gupta { 243*dd4268a2SPankaj Gupta 244*dd4268a2SPankaj Gupta u_register_t core_mask = plat_my_core_mask(); 245*dd4268a2SPankaj Gupta u_register_t core_state; 246*dd4268a2SPankaj Gupta 247*dd4268a2SPankaj Gupta 248*dd4268a2SPankaj Gupta if (state->pwr_domain_state[PLAT_MAX_LVL] == PLAT_MAX_OFF_STATE) { 249*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_PWR_DWN) 250*dd4268a2SPankaj Gupta _psci_sys_exit_pwrdn(core_mask); 251*dd4268a2SPankaj Gupta 252*dd4268a2SPankaj Gupta /* when we are here, the core is back up 253*dd4268a2SPankaj Gupta * set core state to released 254*dd4268a2SPankaj Gupta */ 255*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 256*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 257*dd4268a2SPankaj Gupta #endif 258*dd4268a2SPankaj Gupta } else if (state->pwr_domain_state[PLAT_MAX_LVL] 259*dd4268a2SPankaj Gupta == PLAT_MAX_RET_STATE) { 260*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_STANDBY) 261*dd4268a2SPankaj Gupta _psci_sys_exit_stdby(core_mask); 262*dd4268a2SPankaj Gupta 263*dd4268a2SPankaj Gupta /* when we are here, the core is waking up 264*dd4268a2SPankaj Gupta * set core state to released 265*dd4268a2SPankaj Gupta */ 266*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 267*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 268*dd4268a2SPankaj Gupta #endif 269*dd4268a2SPankaj Gupta } 270*dd4268a2SPankaj Gupta 271*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CLSTR_LVL] == 272*dd4268a2SPankaj Gupta PLAT_MAX_OFF_STATE) { 273*dd4268a2SPankaj Gupta #if (SOC_CLUSTER_PWR_DWN) 274*dd4268a2SPankaj Gupta _psci_clstr_exit_pwrdn(core_mask); 275*dd4268a2SPankaj Gupta 276*dd4268a2SPankaj Gupta /* when we are here, the core is waking up 277*dd4268a2SPankaj Gupta * set core state to released 278*dd4268a2SPankaj Gupta */ 279*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 280*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 281*dd4268a2SPankaj Gupta #endif 282*dd4268a2SPankaj Gupta } 283*dd4268a2SPankaj Gupta 284*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CLSTR_LVL] == 285*dd4268a2SPankaj Gupta PLAT_MAX_RET_STATE) { 286*dd4268a2SPankaj Gupta #if (SOC_CLUSTER_STANDBY) 287*dd4268a2SPankaj Gupta _psci_clstr_exit_stdby(core_mask); 288*dd4268a2SPankaj Gupta 289*dd4268a2SPankaj Gupta /* when we are here, the core is waking up 290*dd4268a2SPankaj Gupta * set core state to released 291*dd4268a2SPankaj Gupta */ 292*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 293*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 294*dd4268a2SPankaj Gupta #endif 295*dd4268a2SPankaj Gupta } 296*dd4268a2SPankaj Gupta 297*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_OFF_STATE) { 298*dd4268a2SPankaj Gupta #if (SOC_CORE_PWR_DWN) 299*dd4268a2SPankaj Gupta _psci_core_exit_pwrdn(core_mask); 300*dd4268a2SPankaj Gupta 301*dd4268a2SPankaj Gupta /* when we are here, the core is back up 302*dd4268a2SPankaj Gupta * set core state to released 303*dd4268a2SPankaj Gupta */ 304*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 305*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 306*dd4268a2SPankaj Gupta #endif 307*dd4268a2SPankaj Gupta } 308*dd4268a2SPankaj Gupta 309*dd4268a2SPankaj Gupta else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_RET_STATE) { 310*dd4268a2SPankaj Gupta #if (SOC_CORE_STANDBY) 311*dd4268a2SPankaj Gupta _psci_core_exit_stdby(core_mask); 312*dd4268a2SPankaj Gupta 313*dd4268a2SPankaj Gupta /* when we are here, the core is waking up 314*dd4268a2SPankaj Gupta * set core state to released 315*dd4268a2SPankaj Gupta */ 316*dd4268a2SPankaj Gupta core_state = CORE_RELEASED; 317*dd4268a2SPankaj Gupta _setCoreState(core_mask, core_state); 318*dd4268a2SPankaj Gupta #endif 319*dd4268a2SPankaj Gupta } 320*dd4268a2SPankaj Gupta 321*dd4268a2SPankaj Gupta } 322*dd4268a2SPankaj Gupta #endif 323*dd4268a2SPankaj Gupta 324*dd4268a2SPankaj Gupta #if (SOC_CORE_STANDBY || SOC_CORE_PWR_DWN) 325*dd4268a2SPankaj Gupta 326*dd4268a2SPankaj Gupta #define PWR_STATE_TYPE_MASK 0x00010000 327*dd4268a2SPankaj Gupta #define PWR_STATE_TYPE_STNDBY 0x0 328*dd4268a2SPankaj Gupta #define PWR_STATE_TYPE_PWRDWN 0x00010000 329*dd4268a2SPankaj Gupta #define PWR_STATE_LVL_MASK 0x03000000 330*dd4268a2SPankaj Gupta #define PWR_STATE_LVL_CORE 0x0 331*dd4268a2SPankaj Gupta #define PWR_STATE_LVL_CLSTR 0x01000000 332*dd4268a2SPankaj Gupta #define PWR_STATE_LVL_SYS 0x02000000 333*dd4268a2SPankaj Gupta #define PWR_STATE_LVL_MAX 0x03000000 334*dd4268a2SPankaj Gupta 335*dd4268a2SPankaj Gupta /* turns a requested power state into a target power state 336*dd4268a2SPankaj Gupta * based on SoC capabilities 337*dd4268a2SPankaj Gupta */ 338*dd4268a2SPankaj Gupta static int _pwr_state_validate(uint32_t pwr_state, 339*dd4268a2SPankaj Gupta psci_power_state_t *state) 340*dd4268a2SPankaj Gupta { 341*dd4268a2SPankaj Gupta int stat = PSCI_E_INVALID_PARAMS; 342*dd4268a2SPankaj Gupta int pwrdn = (pwr_state & PWR_STATE_TYPE_MASK); 343*dd4268a2SPankaj Gupta int lvl = (pwr_state & PWR_STATE_LVL_MASK); 344*dd4268a2SPankaj Gupta 345*dd4268a2SPankaj Gupta switch (lvl) { 346*dd4268a2SPankaj Gupta case PWR_STATE_LVL_MAX: 347*dd4268a2SPankaj Gupta if (pwrdn && SOC_SYSTEM_PWR_DWN) 348*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_MAX_LVL] = 349*dd4268a2SPankaj Gupta PLAT_MAX_OFF_STATE; 350*dd4268a2SPankaj Gupta else if (SOC_SYSTEM_STANDBY) 351*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_MAX_LVL] = 352*dd4268a2SPankaj Gupta PLAT_MAX_RET_STATE; 353*dd4268a2SPankaj Gupta /* intentional fall-thru condition */ 354*dd4268a2SPankaj Gupta case PWR_STATE_LVL_SYS: 355*dd4268a2SPankaj Gupta if (pwrdn && SOC_SYSTEM_PWR_DWN) 356*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_SYS_LVL] = 357*dd4268a2SPankaj Gupta PLAT_MAX_OFF_STATE; 358*dd4268a2SPankaj Gupta else if (SOC_SYSTEM_STANDBY) 359*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_SYS_LVL] = 360*dd4268a2SPankaj Gupta PLAT_MAX_RET_STATE; 361*dd4268a2SPankaj Gupta /* intentional fall-thru condition */ 362*dd4268a2SPankaj Gupta case PWR_STATE_LVL_CLSTR: 363*dd4268a2SPankaj Gupta if (pwrdn && SOC_CLUSTER_PWR_DWN) 364*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_CLSTR_LVL] = 365*dd4268a2SPankaj Gupta PLAT_MAX_OFF_STATE; 366*dd4268a2SPankaj Gupta else if (SOC_CLUSTER_STANDBY) 367*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_CLSTR_LVL] = 368*dd4268a2SPankaj Gupta PLAT_MAX_RET_STATE; 369*dd4268a2SPankaj Gupta /* intentional fall-thru condition */ 370*dd4268a2SPankaj Gupta case PWR_STATE_LVL_CORE: 371*dd4268a2SPankaj Gupta stat = PSCI_E_SUCCESS; 372*dd4268a2SPankaj Gupta 373*dd4268a2SPankaj Gupta if (pwrdn && SOC_CORE_PWR_DWN) 374*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_CORE_LVL] = 375*dd4268a2SPankaj Gupta PLAT_MAX_OFF_STATE; 376*dd4268a2SPankaj Gupta else if (SOC_CORE_STANDBY) 377*dd4268a2SPankaj Gupta state->pwr_domain_state[PLAT_CORE_LVL] = 378*dd4268a2SPankaj Gupta PLAT_MAX_RET_STATE; 379*dd4268a2SPankaj Gupta break; 380*dd4268a2SPankaj Gupta } 381*dd4268a2SPankaj Gupta return (stat); 382*dd4268a2SPankaj Gupta } 383*dd4268a2SPankaj Gupta 384*dd4268a2SPankaj Gupta #endif 385*dd4268a2SPankaj Gupta 386*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_PWR_DWN) 387*dd4268a2SPankaj Gupta static void _pwr_state_sys_suspend(psci_power_state_t *req_state) 388*dd4268a2SPankaj Gupta { 389*dd4268a2SPankaj Gupta 390*dd4268a2SPankaj Gupta /* if we need to have per-SoC settings, then we need to 391*dd4268a2SPankaj Gupta * extend this by calling into psci_utils.S and from there 392*dd4268a2SPankaj Gupta * on down to the SoC.S files 393*dd4268a2SPankaj Gupta */ 394*dd4268a2SPankaj Gupta 395*dd4268a2SPankaj Gupta req_state->pwr_domain_state[PLAT_MAX_LVL] = PLAT_MAX_OFF_STATE; 396*dd4268a2SPankaj Gupta req_state->pwr_domain_state[PLAT_SYS_LVL] = PLAT_MAX_OFF_STATE; 397*dd4268a2SPankaj Gupta req_state->pwr_domain_state[PLAT_CLSTR_LVL] = PLAT_MAX_OFF_STATE; 398*dd4268a2SPankaj Gupta req_state->pwr_domain_state[PLAT_CORE_LVL] = PLAT_MAX_OFF_STATE; 399*dd4268a2SPankaj Gupta 400*dd4268a2SPankaj Gupta } 401*dd4268a2SPankaj Gupta #endif 402*dd4268a2SPankaj Gupta 403*dd4268a2SPankaj Gupta #if defined(NXP_WARM_BOOT) && (SOC_SYSTEM_RESET2) 404*dd4268a2SPankaj Gupta static int psci_system_reset2(int is_vendor, 405*dd4268a2SPankaj Gupta int reset_type, 406*dd4268a2SPankaj Gupta u_register_t cookie) 407*dd4268a2SPankaj Gupta { 408*dd4268a2SPankaj Gupta int ret = 0; 409*dd4268a2SPankaj Gupta 410*dd4268a2SPankaj Gupta INFO("Executing the sequence of warm reset.\n"); 411*dd4268a2SPankaj Gupta ret = prep_n_execute_warm_reset(); 412*dd4268a2SPankaj Gupta 413*dd4268a2SPankaj Gupta return ret; 414*dd4268a2SPankaj Gupta } 415*dd4268a2SPankaj Gupta #endif 416*dd4268a2SPankaj Gupta 417*dd4268a2SPankaj Gupta static plat_psci_ops_t _psci_pm_ops = { 418*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_OFF) 419*dd4268a2SPankaj Gupta .system_off = _psci_system_off, 420*dd4268a2SPankaj Gupta #endif 421*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_RESET) 422*dd4268a2SPankaj Gupta .system_reset = _psci_system_reset, 423*dd4268a2SPankaj Gupta #endif 424*dd4268a2SPankaj Gupta #if defined(NXP_WARM_BOOT) && (SOC_SYSTEM_RESET2) 425*dd4268a2SPankaj Gupta .system_reset2 = psci_system_reset2, 426*dd4268a2SPankaj Gupta #endif 427*dd4268a2SPankaj Gupta #if (SOC_CORE_RELEASE || SOC_CORE_RESTART) 428*dd4268a2SPankaj Gupta /* core released or restarted */ 429*dd4268a2SPankaj Gupta .pwr_domain_on_finish = _pwr_domain_wakeup, 430*dd4268a2SPankaj Gupta #endif 431*dd4268a2SPankaj Gupta #if (SOC_CORE_OFF) 432*dd4268a2SPankaj Gupta /* core shutting down */ 433*dd4268a2SPankaj Gupta .pwr_domain_off = _pwr_domain_off, 434*dd4268a2SPankaj Gupta #endif 435*dd4268a2SPankaj Gupta #if (SOC_CORE_OFF || SOC_CORE_PWR_DWN) 436*dd4268a2SPankaj Gupta .pwr_domain_pwr_down_wfi = _pwr_down_wfi, 437*dd4268a2SPankaj Gupta #endif 438*dd4268a2SPankaj Gupta #if (SOC_CORE_STANDBY || SOC_CORE_PWR_DWN) 439*dd4268a2SPankaj Gupta /* cpu_suspend */ 440*dd4268a2SPankaj Gupta .validate_power_state = _pwr_state_validate, 441*dd4268a2SPankaj Gupta #if (SOC_CORE_STANDBY) 442*dd4268a2SPankaj Gupta .cpu_standby = _pwr_cpu_standby, 443*dd4268a2SPankaj Gupta #endif 444*dd4268a2SPankaj Gupta #if (SOC_CORE_PWR_DWN) 445*dd4268a2SPankaj Gupta .pwr_domain_suspend = _pwr_suspend, 446*dd4268a2SPankaj Gupta .pwr_domain_suspend_finish = _pwr_suspend_finish, 447*dd4268a2SPankaj Gupta #endif 448*dd4268a2SPankaj Gupta #endif 449*dd4268a2SPankaj Gupta #if (SOC_SYSTEM_PWR_DWN) 450*dd4268a2SPankaj Gupta .get_sys_suspend_power_state = _pwr_state_sys_suspend, 451*dd4268a2SPankaj Gupta #endif 452*dd4268a2SPankaj Gupta #if (SOC_CORE_RELEASE) 453*dd4268a2SPankaj Gupta /* core executing psci_cpu_on */ 454*dd4268a2SPankaj Gupta .pwr_domain_on = _pwr_domain_on 455*dd4268a2SPankaj Gupta #endif 456*dd4268a2SPankaj Gupta }; 457*dd4268a2SPankaj Gupta 458*dd4268a2SPankaj Gupta #if (SOC_CORE_RELEASE || SOC_CORE_PWR_DWN) 459*dd4268a2SPankaj Gupta int plat_setup_psci_ops(uintptr_t sec_entrypoint, 460*dd4268a2SPankaj Gupta const plat_psci_ops_t **psci_ops) 461*dd4268a2SPankaj Gupta { 462*dd4268a2SPankaj Gupta warmboot_entry = sec_entrypoint; 463*dd4268a2SPankaj Gupta *psci_ops = &_psci_pm_ops; 464*dd4268a2SPankaj Gupta return 0; 465*dd4268a2SPankaj Gupta } 466*dd4268a2SPankaj Gupta 467*dd4268a2SPankaj Gupta #else 468*dd4268a2SPankaj Gupta 469*dd4268a2SPankaj Gupta int plat_setup_psci_ops(uintptr_t sec_entrypoint, 470*dd4268a2SPankaj Gupta const plat_psci_ops_t **psci_ops) 471*dd4268a2SPankaj Gupta { 472*dd4268a2SPankaj Gupta *psci_ops = &_psci_pm_ops; 473*dd4268a2SPankaj Gupta return 0; 474*dd4268a2SPankaj Gupta } 475*dd4268a2SPankaj Gupta #endif 476