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