1 /* 2 * Copyright (c) 2019, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <assert.h> 7 8 #include <lib/psci/psci.h> 9 #include <plat/arm/common/plat_arm.h> 10 #include <plat/common/platform.h> 11 #include <drivers/arm/gicv2.h> 12 13 /******************************************************************************* 14 * Platform handler called when a power domain is about to be turned on. The 15 * mpidr determines the CPU to be turned on. 16 ******************************************************************************/ 17 static int a5ds_pwr_domain_on(u_register_t mpidr) 18 { 19 unsigned int pos = plat_core_pos_by_mpidr(mpidr); 20 uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE; 21 22 hold_base[pos] = A5DS_HOLD_STATE_GO; 23 dsbish(); 24 sev(); 25 26 return PSCI_E_SUCCESS; 27 } 28 29 /******************************************************************************* 30 * Platform handler called when a power domain has just been powered on after 31 * being turned off earlier. The target_state encodes the low power state that 32 * each level has woken up from. 33 ******************************************************************************/ 34 void a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state) 35 { 36 /* TODO: This setup is needed only after a cold boot*/ 37 gicv2_pcpu_distif_init(); 38 39 /* Enable the gic cpu interface */ 40 gicv2_cpuif_enable(); 41 } 42 43 /******************************************************************************* 44 * Platform handler called when a power domain is about to be turned off. The 45 * target_state encodes the power state that each level should transition to. 46 * a5ds only has always-on power domain and there is no power control present. 47 ******************************************************************************/ 48 void a5ds_pwr_domain_off(const psci_power_state_t *target_state) 49 { 50 ERROR("CPU_OFF not supported on this platform\n"); 51 assert(false); 52 panic(); 53 } 54 55 /******************************************************************************* 56 * Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard 57 * platform layer will take care of registering the handlers with PSCI. 58 ******************************************************************************/ 59 plat_psci_ops_t a5ds_psci_pm_ops = { 60 /* dummy struct */ 61 .validate_ns_entrypoint = NULL, 62 .pwr_domain_on = a5ds_pwr_domain_on, 63 .pwr_domain_on_finish = a5ds_pwr_domain_on_finish, 64 .pwr_domain_off = a5ds_pwr_domain_off 65 }; 66 67 int __init plat_setup_psci_ops(uintptr_t sec_entrypoint, 68 const plat_psci_ops_t **psci_ops) 69 { 70 uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE; 71 *mailbox = sec_entrypoint; 72 73 *psci_ops = &a5ds_psci_pm_ops; 74 75 return 0; 76 } 77