1baa7650bSAnson Huang /* 2baa7650bSAnson Huang * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3baa7650bSAnson Huang * 4baa7650bSAnson Huang * SPDX-License-Identifier: BSD-3-Clause 5baa7650bSAnson Huang */ 6baa7650bSAnson Huang 709d40e0eSAntonio Nino Diaz #include <stdbool.h> 809d40e0eSAntonio Nino Diaz 9baa7650bSAnson Huang #include <arch.h> 10baa7650bSAnson Huang #include <arch_helpers.h> 1109d40e0eSAntonio Nino Diaz #include <common/debug.h> 1209d40e0eSAntonio Nino Diaz #include <drivers/arm/cci.h> 1309d40e0eSAntonio Nino Diaz #include <drivers/arm/gicv3.h> 1409d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 1509d40e0eSAntonio Nino Diaz #include <lib/psci/psci.h> 1609d40e0eSAntonio Nino Diaz 17baa7650bSAnson Huang #include <plat_imx8.h> 18baa7650bSAnson Huang #include <sci/sci.h> 19baa7650bSAnson Huang 20*3a2b5199SAnson Huang #include "../../common/sci/imx8_mu.h" 21*3a2b5199SAnson Huang 228ef9f860SAnson Huang #define CORE_PWR_STATE(state) \ 238ef9f860SAnson Huang ((state)->pwr_domain_state[MPIDR_AFFLVL0]) 248ef9f860SAnson Huang #define CLUSTER_PWR_STATE(state) \ 258ef9f860SAnson Huang ((state)->pwr_domain_state[MPIDR_AFFLVL1]) 268ef9f860SAnson Huang #define SYSTEM_PWR_STATE(state) \ 278ef9f860SAnson Huang ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL]) 288ef9f860SAnson Huang 29baa7650bSAnson Huang const static int ap_core_index[PLATFORM_CORE_COUNT] = { 30baa7650bSAnson Huang SC_R_A53_0, SC_R_A53_1, SC_R_A53_2, 31baa7650bSAnson Huang SC_R_A53_3, SC_R_A72_0, SC_R_A72_1, 32baa7650bSAnson Huang }; 33baa7650bSAnson Huang 34*3a2b5199SAnson Huang /* save gic dist/redist context when GIC is poewr down */ 35*3a2b5199SAnson Huang static struct plat_gic_ctx imx_gicv3_ctx; 36*3a2b5199SAnson Huang static unsigned int gpt_lpcg, gpt_reg[2]; 37*3a2b5199SAnson Huang 38*3a2b5199SAnson Huang static void imx_enable_irqstr_wakeup(void) 39*3a2b5199SAnson Huang { 40*3a2b5199SAnson Huang uint32_t irq_mask; 41*3a2b5199SAnson Huang gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx; 42*3a2b5199SAnson Huang 43*3a2b5199SAnson Huang /* put IRQSTR into ON mode */ 44*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON); 45*3a2b5199SAnson Huang 46*3a2b5199SAnson Huang /* enable the irqsteer to handle wakeup irq */ 47*3a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1); 48*3a2b5199SAnson Huang for (int i = 0; i < 15; i++) { 49*3a2b5199SAnson Huang irq_mask = dist_ctx->gicd_isenabler[i]; 50*3a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask); 51*3a2b5199SAnson Huang } 52*3a2b5199SAnson Huang 53*3a2b5199SAnson Huang /* set IRQSTR low power mode */ 54*3a2b5199SAnson Huang if (imx_is_wakeup_src_irqsteer()) 55*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY); 56*3a2b5199SAnson Huang else 57*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF); 58*3a2b5199SAnson Huang } 59*3a2b5199SAnson Huang 60*3a2b5199SAnson Huang static void imx_disable_irqstr_wakeup(void) 61*3a2b5199SAnson Huang { 62*3a2b5199SAnson Huang /* put IRQSTR into ON from STBY mode */ 63*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON); 64*3a2b5199SAnson Huang 65*3a2b5199SAnson Huang /* disable the irqsteer */ 66*3a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0); 67*3a2b5199SAnson Huang for (int i = 0; i < 16; i++) 68*3a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0); 69*3a2b5199SAnson Huang 70*3a2b5199SAnson Huang /* put IRQSTR into OFF mode */ 71*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF); 72*3a2b5199SAnson Huang } 73*3a2b5199SAnson Huang 74baa7650bSAnson Huang int imx_pwr_domain_on(u_register_t mpidr) 75baa7650bSAnson Huang { 76baa7650bSAnson Huang int ret = PSCI_E_SUCCESS; 77*3a2b5199SAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 78*3a2b5199SAnson Huang unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 79baa7650bSAnson Huang 80*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, cluster_id == 0 ? 81*3a2b5199SAnson Huang SC_R_A53 : SC_R_A72, SC_PM_PW_MODE_ON); 82baa7650bSAnson Huang 83*3a2b5199SAnson Huang if (cluster_id == 1) 84*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 85baa7650bSAnson Huang 86*3a2b5199SAnson Huang if (sc_pm_set_resource_power_mode(ipc_handle, 87*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 88baa7650bSAnson Huang SC_PM_PW_MODE_ON) != SC_ERR_NONE) { 89*3a2b5199SAnson Huang ERROR("core %d power on failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id); 90baa7650bSAnson Huang ret = PSCI_E_INTERN_FAIL; 91baa7650bSAnson Huang } 92baa7650bSAnson Huang 93*3a2b5199SAnson Huang if (sc_pm_cpu_start(ipc_handle, 94*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 95baa7650bSAnson Huang true, BL31_BASE) != SC_ERR_NONE) { 96*3a2b5199SAnson Huang ERROR("boot core %d failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id); 97baa7650bSAnson Huang ret = PSCI_E_INTERN_FAIL; 98baa7650bSAnson Huang } 99baa7650bSAnson Huang 100baa7650bSAnson Huang return ret; 101baa7650bSAnson Huang } 102baa7650bSAnson Huang 103baa7650bSAnson Huang void imx_pwr_domain_on_finish(const psci_power_state_t *target_state) 104baa7650bSAnson Huang { 105baa7650bSAnson Huang uint64_t mpidr = read_mpidr_el1(); 106baa7650bSAnson Huang 1078ef9f860SAnson Huang if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) 1088ef9f860SAnson Huang cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 109baa7650bSAnson Huang 110baa7650bSAnson Huang plat_gic_pcpu_init(); 111baa7650bSAnson Huang plat_gic_cpuif_enable(); 112baa7650bSAnson Huang } 113baa7650bSAnson Huang 1140f53bca0SAnson Huang void imx_pwr_domain_off(const psci_power_state_t *target_state) 1150f53bca0SAnson Huang { 1160f53bca0SAnson Huang u_register_t mpidr = read_mpidr_el1(); 1170f53bca0SAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 1180f53bca0SAnson Huang unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 1190f53bca0SAnson Huang 1200f53bca0SAnson Huang plat_gic_cpuif_disable(); 1210f53bca0SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 122*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 123*3a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_NONE); 124*3a2b5199SAnson Huang 125*3a2b5199SAnson Huang if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 126*3a2b5199SAnson Huang cci_disable_snoop_dvm_reqs(cluster_id); 127*3a2b5199SAnson Huang if (cluster_id == 1) 128*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF); 129*3a2b5199SAnson Huang } 13039b6cc66SAntonio Nino Diaz printf("turn off cluster:%d core:%d\n", cluster_id, cpu_id); 1310f53bca0SAnson Huang } 1320f53bca0SAnson Huang 1338ef9f860SAnson Huang void imx_domain_suspend(const psci_power_state_t *target_state) 1348ef9f860SAnson Huang { 1358ef9f860SAnson Huang u_register_t mpidr = read_mpidr_el1(); 1368ef9f860SAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 1378ef9f860SAnson Huang unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 1388ef9f860SAnson Huang 139*3a2b5199SAnson Huang if (is_local_state_off(CORE_PWR_STATE(target_state))) { 1408ef9f860SAnson Huang plat_gic_cpuif_disable(); 141*3a2b5199SAnson Huang sc_pm_set_cpu_resume(ipc_handle, 142*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 143*3a2b5199SAnson Huang true, BL31_BASE); 144*3a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 145*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 146*3a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC); 147*3a2b5199SAnson Huang } else { 148*3a2b5199SAnson Huang dsb(); 149*3a2b5199SAnson Huang write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 150*3a2b5199SAnson Huang isb(); 151*3a2b5199SAnson Huang } 152*3a2b5199SAnson Huang 153*3a2b5199SAnson Huang if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 154*3a2b5199SAnson Huang cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 155*3a2b5199SAnson Huang if (cluster_id == 1) 156*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF); 157*3a2b5199SAnson Huang } 158*3a2b5199SAnson Huang 159*3a2b5199SAnson Huang if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) { 160*3a2b5199SAnson Huang plat_gic_cpuif_disable(); 161*3a2b5199SAnson Huang 162*3a2b5199SAnson Huang /* save gic context */ 163*3a2b5199SAnson Huang plat_gic_save(cpu_id, &imx_gicv3_ctx); 164*3a2b5199SAnson Huang /* enable the irqsteer for wakeup */ 165*3a2b5199SAnson Huang imx_enable_irqstr_wakeup(); 1668ef9f860SAnson Huang 1678ef9f860SAnson Huang cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 1688ef9f860SAnson Huang 169*3a2b5199SAnson Huang /* Put GIC in LP mode. */ 170*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF); 171*3a2b5199SAnson Huang /* Save GPT clock and registers, then turn off its power */ 172*3a2b5199SAnson Huang gpt_lpcg = mmio_read_32(IMX_GPT_LPCG_BASE); 173*3a2b5199SAnson Huang gpt_reg[0] = mmio_read_32(IMX_GPT_BASE); 174*3a2b5199SAnson Huang gpt_reg[1] = mmio_read_32(IMX_GPT_BASE + 0x4); 175*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF); 176*3a2b5199SAnson Huang 177*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF); 178*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF); 179*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF); 180*3a2b5199SAnson Huang 181*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR, 182*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 183*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR, 184*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 185*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU, 186*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 187*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU, 188*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 189*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT, 190*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 191*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT, 192*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 193*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF); 194*3a2b5199SAnson Huang 195*3a2b5199SAnson Huang sc_pm_set_cpu_resume(ipc_handle, 196*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 197*3a2b5199SAnson Huang true, BL31_BASE); 198*3a2b5199SAnson Huang if (imx_is_wakeup_src_irqsteer()) 1998ef9f860SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 200*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 201*3a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER); 202*3a2b5199SAnson Huang else 203*3a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 204*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 205*3a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU); 206*3a2b5199SAnson Huang } 2078ef9f860SAnson Huang } 2088ef9f860SAnson Huang 2098ef9f860SAnson Huang void imx_domain_suspend_finish(const psci_power_state_t *target_state) 2108ef9f860SAnson Huang { 2118ef9f860SAnson Huang u_register_t mpidr = read_mpidr_el1(); 212*3a2b5199SAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 213*3a2b5199SAnson Huang unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 214*3a2b5199SAnson Huang 215*3a2b5199SAnson Huang /* check the system level status */ 216*3a2b5199SAnson Huang if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) { 217*3a2b5199SAnson Huang MU_Resume(SC_IPC_BASE); 218*3a2b5199SAnson Huang 219*3a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 220*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 221*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC); 222*3a2b5199SAnson Huang 223*3a2b5199SAnson Huang /* Put GIC/IRQSTR back to high power mode. */ 224*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON); 225*3a2b5199SAnson Huang 226*3a2b5199SAnson Huang /* Turn GPT power and restore its clock and registers */ 227*3a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON); 228*3a2b5199SAnson Huang sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0); 229*3a2b5199SAnson Huang mmio_write_32(IMX_GPT_BASE, gpt_reg[0]); 230*3a2b5199SAnson Huang mmio_write_32(IMX_GPT_BASE + 0x4, gpt_reg[1]); 231*3a2b5199SAnson Huang mmio_write_32(IMX_GPT_LPCG_BASE, gpt_lpcg); 232*3a2b5199SAnson Huang 233*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON); 234*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 235*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON); 236*3a2b5199SAnson Huang 237*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR, 238*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 239*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR, 240*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 241*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU, 242*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 243*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU, 244*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 245*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT, 246*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 247*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT, 248*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 249*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON); 2508ef9f860SAnson Huang 2518ef9f860SAnson Huang cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 2528ef9f860SAnson Huang 253*3a2b5199SAnson Huang /* restore gic context */ 254*3a2b5199SAnson Huang plat_gic_restore(cpu_id, &imx_gicv3_ctx); 255*3a2b5199SAnson Huang /* disable the irqsteer wakeup */ 256*3a2b5199SAnson Huang imx_disable_irqstr_wakeup(); 257*3a2b5199SAnson Huang 2588ef9f860SAnson Huang plat_gic_cpuif_enable(); 2598ef9f860SAnson Huang } 2608ef9f860SAnson Huang 261*3a2b5199SAnson Huang /* check the cluster level power status */ 262*3a2b5199SAnson Huang if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 263*3a2b5199SAnson Huang cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 264*3a2b5199SAnson Huang if (cluster_id == 1) 265*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 266*3a2b5199SAnson Huang } 267*3a2b5199SAnson Huang 268*3a2b5199SAnson Huang /* check the core level power status */ 269*3a2b5199SAnson Huang if (is_local_state_off(CORE_PWR_STATE(target_state))) { 270*3a2b5199SAnson Huang sc_pm_set_cpu_resume(ipc_handle, 271*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 272*3a2b5199SAnson Huang false, BL31_BASE); 273*3a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 274*3a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 275*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC); 276*3a2b5199SAnson Huang plat_gic_cpuif_enable(); 277*3a2b5199SAnson Huang } else { 278*3a2b5199SAnson Huang write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT)); 279*3a2b5199SAnson Huang isb(); 280*3a2b5199SAnson Huang } 281*3a2b5199SAnson Huang } 282*3a2b5199SAnson Huang 283baa7650bSAnson Huang int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint) 284baa7650bSAnson Huang { 285baa7650bSAnson Huang return PSCI_E_SUCCESS; 286baa7650bSAnson Huang } 287baa7650bSAnson Huang 288baa7650bSAnson Huang static const plat_psci_ops_t imx_plat_psci_ops = { 289baa7650bSAnson Huang .pwr_domain_on = imx_pwr_domain_on, 290baa7650bSAnson Huang .pwr_domain_on_finish = imx_pwr_domain_on_finish, 2910f53bca0SAnson Huang .pwr_domain_off = imx_pwr_domain_off, 2928ef9f860SAnson Huang .pwr_domain_suspend = imx_domain_suspend, 2938ef9f860SAnson Huang .pwr_domain_suspend_finish = imx_domain_suspend_finish, 2948ef9f860SAnson Huang .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, 2958ef9f860SAnson Huang .validate_power_state = imx_validate_power_state, 296baa7650bSAnson Huang .validate_ns_entrypoint = imx_validate_ns_entrypoint, 297db81c592SAnson Huang .system_off = imx_system_off, 298d31ffcf0SAnson Huang .system_reset = imx_system_reset, 299baa7650bSAnson Huang }; 300baa7650bSAnson Huang 301baa7650bSAnson Huang int plat_setup_psci_ops(uintptr_t sec_entrypoint, 302baa7650bSAnson Huang const plat_psci_ops_t **psci_ops) 303baa7650bSAnson Huang { 304baa7650bSAnson Huang imx_mailbox_init(sec_entrypoint); 305baa7650bSAnson Huang *psci_ops = &imx_plat_psci_ops; 306baa7650bSAnson Huang 307*3a2b5199SAnson Huang /* make sure system sources power ON in low power mode by default */ 308*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON); 309*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 310*3a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON); 3118ef9f860SAnson Huang 312*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR, 313*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 314*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR, 315*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 316*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU, 317*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 318*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU, 319*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 320*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT, 321*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 322*3a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT, 323*3a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 324baa7650bSAnson Huang 325baa7650bSAnson Huang return 0; 326baa7650bSAnson Huang } 327