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