100c7d5acSUsama Arif /* 200c7d5acSUsama Arif * Copyright (c) 2019, Arm Limited. All rights reserved. 300c7d5acSUsama Arif * 400c7d5acSUsama Arif * SPDX-License-Identifier: BSD-3-Clause 500c7d5acSUsama Arif */ 659ffec15SUsama Arif #include <assert.h> 7*c20c0525SVishnu Banavath #include <drivers/arm/gicv2.h> 800c7d5acSUsama Arif #include <lib/psci/psci.h> 900c7d5acSUsama Arif #include <plat/arm/common/plat_arm.h> 10ec885bacSUsama Arif #include <plat/common/platform.h> 11ec885bacSUsama Arif 12ec885bacSUsama Arif /******************************************************************************* 13ec885bacSUsama Arif * Platform handler called when a power domain is about to be turned on. The 14ec885bacSUsama Arif * mpidr determines the CPU to be turned on. 15ec885bacSUsama Arif ******************************************************************************/ a5ds_pwr_domain_on(u_register_t mpidr)16ec885bacSUsama Arifstatic int a5ds_pwr_domain_on(u_register_t mpidr) 17ec885bacSUsama Arif { 18ec885bacSUsama Arif unsigned int pos = plat_core_pos_by_mpidr(mpidr); 19ec885bacSUsama Arif uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE; 20ec885bacSUsama Arif 21ec885bacSUsama Arif hold_base[pos] = A5DS_HOLD_STATE_GO; 22ec885bacSUsama Arif dsbish(); 23ec885bacSUsama Arif sev(); 24ec885bacSUsama Arif 25ec885bacSUsama Arif return PSCI_E_SUCCESS; 26ec885bacSUsama Arif } 27ec885bacSUsama Arif 28ec885bacSUsama Arif /******************************************************************************* 29ec885bacSUsama Arif * Platform handler called when a power domain has just been powered on after 30ec885bacSUsama Arif * being turned off earlier. The target_state encodes the low power state that 31ec885bacSUsama Arif * each level has woken up from. 32ec885bacSUsama Arif ******************************************************************************/ a5ds_pwr_domain_on_finish(const psci_power_state_t * target_state)33ec885bacSUsama Arifvoid a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state) 34ec885bacSUsama Arif { 35ec885bacSUsama Arif /* TODO: This setup is needed only after a cold boot*/ 36ec885bacSUsama Arif gicv2_pcpu_distif_init(); 37ec885bacSUsama Arif 38ec885bacSUsama Arif /* Enable the gic cpu interface */ 39ec885bacSUsama Arif gicv2_cpuif_enable(); 40ec885bacSUsama Arif } 4100c7d5acSUsama Arif 4200c7d5acSUsama Arif /******************************************************************************* 4359ffec15SUsama Arif * Platform handler called when a power domain is about to be turned off. The 4459ffec15SUsama Arif * target_state encodes the power state that each level should transition to. 4559ffec15SUsama Arif * a5ds only has always-on power domain and there is no power control present. 4659ffec15SUsama Arif ******************************************************************************/ a5ds_pwr_domain_off(const psci_power_state_t * target_state)4759ffec15SUsama Arifvoid a5ds_pwr_domain_off(const psci_power_state_t *target_state) 4859ffec15SUsama Arif { 4959ffec15SUsama Arif ERROR("CPU_OFF not supported on this platform\n"); 5059ffec15SUsama Arif assert(false); 5159ffec15SUsama Arif panic(); 5259ffec15SUsama Arif } 5359ffec15SUsama Arif 5459ffec15SUsama Arif /******************************************************************************* 5500c7d5acSUsama Arif * Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard 5600c7d5acSUsama Arif * platform layer will take care of registering the handlers with PSCI. 5700c7d5acSUsama Arif ******************************************************************************/ 5800c7d5acSUsama Arif plat_psci_ops_t a5ds_psci_pm_ops = { 5900c7d5acSUsama Arif /* dummy struct */ 6000c7d5acSUsama Arif .validate_ns_entrypoint = NULL, 61ec885bacSUsama Arif .pwr_domain_on = a5ds_pwr_domain_on, 6259ffec15SUsama Arif .pwr_domain_on_finish = a5ds_pwr_domain_on_finish, 6359ffec15SUsama Arif .pwr_domain_off = a5ds_pwr_domain_off 6400c7d5acSUsama Arif }; 6500c7d5acSUsama Arif plat_setup_psci_ops(uintptr_t sec_entrypoint,const plat_psci_ops_t ** psci_ops)6600c7d5acSUsama Arifint __init plat_setup_psci_ops(uintptr_t sec_entrypoint, 6700c7d5acSUsama Arif const plat_psci_ops_t **psci_ops) 6800c7d5acSUsama Arif { 69ec885bacSUsama Arif uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE; 70ec885bacSUsama Arif *mailbox = sec_entrypoint; 71ec885bacSUsama Arif 7200c7d5acSUsama Arif *psci_ops = &a5ds_psci_pm_ops; 7300c7d5acSUsama Arif 7400c7d5acSUsama Arif return 0; 7500c7d5acSUsama Arif } 76