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 203a2b5199SAnson Huang #include "../../common/sci/imx8_mu.h" 213a2b5199SAnson 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 29*f4b8470fSBoyan Karatotev static const 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 343a2b5199SAnson Huang /* save gic dist/redist context when GIC is poewr down */ 353a2b5199SAnson Huang static struct plat_gic_ctx imx_gicv3_ctx; 363a2b5199SAnson Huang static unsigned int gpt_lpcg, gpt_reg[2]; 373a2b5199SAnson Huang 383a2b5199SAnson Huang static void imx_enable_irqstr_wakeup(void) 393a2b5199SAnson Huang { 403a2b5199SAnson Huang uint32_t irq_mask; 413a2b5199SAnson Huang gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx; 423a2b5199SAnson Huang 433a2b5199SAnson Huang /* put IRQSTR into ON mode */ 443a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON); 453a2b5199SAnson Huang 463a2b5199SAnson Huang /* enable the irqsteer to handle wakeup irq */ 473a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1); 483a2b5199SAnson Huang for (int i = 0; i < 15; i++) { 493a2b5199SAnson Huang irq_mask = dist_ctx->gicd_isenabler[i]; 503a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask); 513a2b5199SAnson Huang } 523a2b5199SAnson Huang 533a2b5199SAnson Huang /* set IRQSTR low power mode */ 543a2b5199SAnson Huang if (imx_is_wakeup_src_irqsteer()) 553a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY); 563a2b5199SAnson Huang else 573a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF); 583a2b5199SAnson Huang } 593a2b5199SAnson Huang 603a2b5199SAnson Huang static void imx_disable_irqstr_wakeup(void) 613a2b5199SAnson Huang { 623a2b5199SAnson Huang /* put IRQSTR into ON from STBY mode */ 633a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON); 643a2b5199SAnson Huang 653a2b5199SAnson Huang /* disable the irqsteer */ 663a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0); 673a2b5199SAnson Huang for (int i = 0; i < 16; i++) 683a2b5199SAnson Huang mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0); 693a2b5199SAnson Huang 703a2b5199SAnson Huang /* put IRQSTR into OFF mode */ 713a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF); 723a2b5199SAnson Huang } 733a2b5199SAnson Huang 74baa7650bSAnson Huang int imx_pwr_domain_on(u_register_t mpidr) 75baa7650bSAnson Huang { 76baa7650bSAnson Huang int ret = PSCI_E_SUCCESS; 773a2b5199SAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 783a2b5199SAnson Huang unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 79baa7650bSAnson Huang 803a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, cluster_id == 0 ? 813a2b5199SAnson Huang SC_R_A53 : SC_R_A72, SC_PM_PW_MODE_ON); 82baa7650bSAnson Huang 833a2b5199SAnson Huang if (cluster_id == 1) 843a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 85baa7650bSAnson Huang 863a2b5199SAnson Huang if (sc_pm_set_resource_power_mode(ipc_handle, 873a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 88baa7650bSAnson Huang SC_PM_PW_MODE_ON) != SC_ERR_NONE) { 893a2b5199SAnson 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 933a2b5199SAnson Huang if (sc_pm_cpu_start(ipc_handle, 943a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 95baa7650bSAnson Huang true, BL31_BASE) != SC_ERR_NONE) { 963a2b5199SAnson 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, 1223a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 1233a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_NONE); 1243a2b5199SAnson Huang 1253a2b5199SAnson Huang if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 1263a2b5199SAnson Huang cci_disable_snoop_dvm_reqs(cluster_id); 1273a2b5199SAnson Huang if (cluster_id == 1) 1283a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF); 1293a2b5199SAnson 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 1393a2b5199SAnson Huang if (is_local_state_off(CORE_PWR_STATE(target_state))) { 1408ef9f860SAnson Huang plat_gic_cpuif_disable(); 1413a2b5199SAnson Huang sc_pm_set_cpu_resume(ipc_handle, 1423a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 1433a2b5199SAnson Huang true, BL31_BASE); 1443a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 1453a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 1463a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC); 1473a2b5199SAnson Huang } else { 1483a2b5199SAnson Huang dsb(); 1493a2b5199SAnson Huang write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 1503a2b5199SAnson Huang isb(); 1513a2b5199SAnson Huang } 1523a2b5199SAnson Huang 1533a2b5199SAnson Huang if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 1543a2b5199SAnson Huang cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 1553a2b5199SAnson Huang if (cluster_id == 1) 1563a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF); 1573a2b5199SAnson Huang } 1583a2b5199SAnson Huang 1593a2b5199SAnson Huang if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) { 1603a2b5199SAnson Huang plat_gic_cpuif_disable(); 1613a2b5199SAnson Huang 1623a2b5199SAnson Huang /* save gic context */ 1633a2b5199SAnson Huang plat_gic_save(cpu_id, &imx_gicv3_ctx); 1643a2b5199SAnson Huang /* enable the irqsteer for wakeup */ 1653a2b5199SAnson Huang imx_enable_irqstr_wakeup(); 1668ef9f860SAnson Huang 1678ef9f860SAnson Huang cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 1688ef9f860SAnson Huang 1693a2b5199SAnson Huang /* Put GIC in LP mode. */ 1703a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF); 1713a2b5199SAnson Huang /* Save GPT clock and registers, then turn off its power */ 1723a2b5199SAnson Huang gpt_lpcg = mmio_read_32(IMX_GPT_LPCG_BASE); 1733a2b5199SAnson Huang gpt_reg[0] = mmio_read_32(IMX_GPT_BASE); 1743a2b5199SAnson Huang gpt_reg[1] = mmio_read_32(IMX_GPT_BASE + 0x4); 1753a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF); 1763a2b5199SAnson Huang 1773a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF); 1783a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF); 1793a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF); 1803a2b5199SAnson Huang 1813a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR, 1823a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 1833a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR, 1843a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 1853a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU, 1863a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 1873a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU, 1883a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 1893a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT, 1903a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 1913a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT, 1923a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF); 1933a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF); 1943a2b5199SAnson Huang 1953a2b5199SAnson Huang sc_pm_set_cpu_resume(ipc_handle, 1963a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 1973a2b5199SAnson Huang true, BL31_BASE); 1983a2b5199SAnson Huang if (imx_is_wakeup_src_irqsteer()) 1998ef9f860SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 2003a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 2013a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER); 2023a2b5199SAnson Huang else 2033a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 2043a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 2053a2b5199SAnson Huang SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU); 2063a2b5199SAnson 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(); 2123a2b5199SAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 2133a2b5199SAnson Huang unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 2143a2b5199SAnson Huang 2153a2b5199SAnson Huang /* check the system level status */ 2163a2b5199SAnson Huang if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) { 2173a2b5199SAnson Huang MU_Resume(SC_IPC_BASE); 2183a2b5199SAnson Huang 2193a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 2203a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 2213a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC); 2223a2b5199SAnson Huang 2233a2b5199SAnson Huang /* Put GIC/IRQSTR back to high power mode. */ 2243a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON); 2253a2b5199SAnson Huang 2263a2b5199SAnson Huang /* Turn GPT power and restore its clock and registers */ 2273a2b5199SAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON); 2283a2b5199SAnson Huang sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0); 2293a2b5199SAnson Huang mmio_write_32(IMX_GPT_BASE, gpt_reg[0]); 2303a2b5199SAnson Huang mmio_write_32(IMX_GPT_BASE + 0x4, gpt_reg[1]); 2313a2b5199SAnson Huang mmio_write_32(IMX_GPT_LPCG_BASE, gpt_lpcg); 2323a2b5199SAnson Huang 2333a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON); 2343a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 2353a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON); 2363a2b5199SAnson Huang 2373a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR, 2383a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 2393a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR, 2403a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 2413a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU, 2423a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 2433a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU, 2443a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 2453a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT, 2463a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 2473a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT, 2483a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 2493a2b5199SAnson 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 2533a2b5199SAnson Huang /* restore gic context */ 2543a2b5199SAnson Huang plat_gic_restore(cpu_id, &imx_gicv3_ctx); 2553a2b5199SAnson Huang /* disable the irqsteer wakeup */ 2563a2b5199SAnson Huang imx_disable_irqstr_wakeup(); 2573a2b5199SAnson Huang 2588ef9f860SAnson Huang plat_gic_cpuif_enable(); 2598ef9f860SAnson Huang } 2608ef9f860SAnson Huang 2613a2b5199SAnson Huang /* check the cluster level power status */ 2623a2b5199SAnson Huang if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 2633a2b5199SAnson Huang cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr)); 2643a2b5199SAnson Huang if (cluster_id == 1) 2653a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 2663a2b5199SAnson Huang } 2673a2b5199SAnson Huang 2683a2b5199SAnson Huang /* check the core level power status */ 2693a2b5199SAnson Huang if (is_local_state_off(CORE_PWR_STATE(target_state))) { 2703a2b5199SAnson Huang sc_pm_set_cpu_resume(ipc_handle, 2713a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 2723a2b5199SAnson Huang false, BL31_BASE); 2733a2b5199SAnson Huang sc_pm_req_cpu_low_power_mode(ipc_handle, 2743a2b5199SAnson Huang ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id], 2753a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC); 2763a2b5199SAnson Huang plat_gic_cpuif_enable(); 2773a2b5199SAnson Huang } else { 2783a2b5199SAnson Huang write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT)); 2793a2b5199SAnson Huang isb(); 2803a2b5199SAnson Huang } 2813a2b5199SAnson Huang } 2823a2b5199SAnson 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 3073a2b5199SAnson Huang /* make sure system sources power ON in low power mode by default */ 3083a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON); 3093a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 3103a2b5199SAnson Huang sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON); 3118ef9f860SAnson Huang 3123a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR, 3133a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 3143a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR, 3153a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 3163a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU, 3173a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 3183a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU, 3193a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 3203a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT, 3213a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 3223a2b5199SAnson Huang sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT, 3233a2b5199SAnson Huang SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON); 324baa7650bSAnson Huang 325baa7650bSAnson Huang return 0; 326baa7650bSAnson Huang } 327