xref: /rk3399_ARM-atf/plat/arm/board/a5ds/a5ds_pm.c (revision 22d12c4148c373932a7a81e5d1c59a767e143ac2)
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 Arif static 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 Arif void 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 Arif void 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 Arif int __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