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 7baa7650bSAnson Huang #include <arch.h> 8baa7650bSAnson Huang #include <arch_helpers.h> 9baa7650bSAnson Huang #include <cci.h> 10baa7650bSAnson Huang #include <debug.h> 11baa7650bSAnson Huang #include <gicv3.h> 12baa7650bSAnson Huang #include <mmio.h> 13baa7650bSAnson Huang #include <plat_imx8.h> 14baa7650bSAnson Huang #include <psci.h> 15baa7650bSAnson Huang #include <sci/sci.h> 16baa7650bSAnson Huang #include <stdbool.h> 17baa7650bSAnson Huang 18baa7650bSAnson Huang const static int ap_core_index[PLATFORM_CORE_COUNT] = { 19baa7650bSAnson Huang SC_R_A53_0, SC_R_A53_1, SC_R_A53_2, 20baa7650bSAnson Huang SC_R_A53_3, SC_R_A72_0, SC_R_A72_1, 21baa7650bSAnson Huang }; 22baa7650bSAnson Huang 23baa7650bSAnson Huang /* need to enable USE_COHERENT_MEM to avoid coherence issue */ 24baa7650bSAnson Huang #if USE_COHERENT_MEM 25baa7650bSAnson Huang static unsigned int a53_cpu_on_number __section("tzfw_coherent_mem"); 26baa7650bSAnson Huang static unsigned int a72_cpu_on_number __section("tzfw_coherent_mem"); 27baa7650bSAnson Huang #endif 28baa7650bSAnson Huang 29baa7650bSAnson Huang int imx_pwr_domain_on(u_register_t mpidr) 30baa7650bSAnson Huang { 31baa7650bSAnson Huang int ret = PSCI_E_SUCCESS; 32baa7650bSAnson Huang unsigned int cluster_id, cpu_id; 33baa7650bSAnson Huang 34baa7650bSAnson Huang cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 35baa7650bSAnson Huang cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 36baa7650bSAnson Huang 37baa7650bSAnson Huang tf_printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id); 38baa7650bSAnson Huang 39baa7650bSAnson Huang if (cluster_id == 0) { 40baa7650bSAnson Huang if (a53_cpu_on_number == 0) 41baa7650bSAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON); 42baa7650bSAnson Huang 43baa7650bSAnson Huang if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id], 44baa7650bSAnson Huang SC_PM_PW_MODE_ON) != SC_ERR_NONE) { 45baa7650bSAnson Huang ERROR("cluster0 core %d power on failed!\n", cpu_id); 46baa7650bSAnson Huang ret = PSCI_E_INTERN_FAIL; 47baa7650bSAnson Huang } 48baa7650bSAnson Huang 49baa7650bSAnson Huang if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id], 50baa7650bSAnson Huang true, BL31_BASE) != SC_ERR_NONE) { 51baa7650bSAnson Huang ERROR("boot cluster0 core %d failed!\n", cpu_id); 52baa7650bSAnson Huang ret = PSCI_E_INTERN_FAIL; 53baa7650bSAnson Huang } 54baa7650bSAnson Huang } else { 55baa7650bSAnson Huang if (a72_cpu_on_number == 0) 56baa7650bSAnson Huang sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON); 57baa7650bSAnson Huang 58baa7650bSAnson Huang if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4], 59baa7650bSAnson Huang SC_PM_PW_MODE_ON) != SC_ERR_NONE) { 60baa7650bSAnson Huang ERROR(" cluster1 core %d power on failed!\n", cpu_id); 61baa7650bSAnson Huang ret = PSCI_E_INTERN_FAIL; 62baa7650bSAnson Huang } 63baa7650bSAnson Huang 64baa7650bSAnson Huang if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id + 4], 65baa7650bSAnson Huang true, BL31_BASE) != SC_ERR_NONE) { 66baa7650bSAnson Huang ERROR("boot cluster1 core %d failed!\n", cpu_id); 67baa7650bSAnson Huang ret = PSCI_E_INTERN_FAIL; 68baa7650bSAnson Huang } 69baa7650bSAnson Huang } 70baa7650bSAnson Huang 71baa7650bSAnson Huang return ret; 72baa7650bSAnson Huang } 73baa7650bSAnson Huang 74baa7650bSAnson Huang void imx_pwr_domain_on_finish(const psci_power_state_t *target_state) 75baa7650bSAnson Huang { 76baa7650bSAnson Huang uint64_t mpidr = read_mpidr_el1(); 77baa7650bSAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 78baa7650bSAnson Huang 79baa7650bSAnson Huang if (cluster_id == 0 && a53_cpu_on_number++ == 0) 80baa7650bSAnson Huang cci_enable_snoop_dvm_reqs(0); 81baa7650bSAnson Huang if (cluster_id == 1 && a72_cpu_on_number++ == 0) 82baa7650bSAnson Huang cci_enable_snoop_dvm_reqs(1); 83baa7650bSAnson Huang 84baa7650bSAnson Huang plat_gic_pcpu_init(); 85baa7650bSAnson Huang plat_gic_cpuif_enable(); 86baa7650bSAnson Huang } 87baa7650bSAnson Huang 88baa7650bSAnson Huang int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint) 89baa7650bSAnson Huang { 90baa7650bSAnson Huang return PSCI_E_SUCCESS; 91baa7650bSAnson Huang } 92baa7650bSAnson Huang 93baa7650bSAnson Huang static const plat_psci_ops_t imx_plat_psci_ops = { 94baa7650bSAnson Huang .pwr_domain_on = imx_pwr_domain_on, 95baa7650bSAnson Huang .pwr_domain_on_finish = imx_pwr_domain_on_finish, 96baa7650bSAnson Huang .validate_ns_entrypoint = imx_validate_ns_entrypoint, 97*db81c592SAnson Huang .system_off = imx_system_off, 98baa7650bSAnson Huang }; 99baa7650bSAnson Huang 100baa7650bSAnson Huang int plat_setup_psci_ops(uintptr_t sec_entrypoint, 101baa7650bSAnson Huang const plat_psci_ops_t **psci_ops) 102baa7650bSAnson Huang { 103baa7650bSAnson Huang uint64_t mpidr = read_mpidr_el1(); 104baa7650bSAnson Huang unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 105baa7650bSAnson Huang 106baa7650bSAnson Huang imx_mailbox_init(sec_entrypoint); 107baa7650bSAnson Huang *psci_ops = &imx_plat_psci_ops; 108baa7650bSAnson Huang 109baa7650bSAnson Huang if (cluster_id == 0) 110baa7650bSAnson Huang a53_cpu_on_number++; 111baa7650bSAnson Huang else 112baa7650bSAnson Huang a72_cpu_on_number++; 113baa7650bSAnson Huang 114baa7650bSAnson Huang return 0; 115baa7650bSAnson Huang } 116