xref: /rk3399_ARM-atf/plat/xilinx/versal/plat_psci.c (revision 394a65aa96d6ce8cd55c0a824dc112d60ef97835)
1f91c3cb1SSiva Durga Prasad Paladugu /*
2d4821739STejas Patel  * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
3f91c3cb1SSiva Durga Prasad Paladugu  *
4f91c3cb1SSiva Durga Prasad Paladugu  * SPDX-License-Identifier: BSD-3-Clause
5f91c3cb1SSiva Durga Prasad Paladugu  */
6f91c3cb1SSiva Durga Prasad Paladugu 
7d4821739STejas Patel #include <plat_private.h>
8*394a65aaSTejas Patel #include <pm_common.h>
909d40e0eSAntonio Nino Diaz #include <common/debug.h>
1009d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1109d40e0eSAntonio Nino Diaz #include <lib/psci/psci.h>
1209d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
1309d40e0eSAntonio Nino Diaz 
14*394a65aaSTejas Patel #include "pm_api_sys.h"
15*394a65aaSTejas Patel #include "pm_client.h"
16*394a65aaSTejas Patel 
17f91c3cb1SSiva Durga Prasad Paladugu static uintptr_t versal_sec_entry;
18f91c3cb1SSiva Durga Prasad Paladugu 
19*394a65aaSTejas Patel static int versal_pwr_domain_on(u_register_t mpidr)
20f91c3cb1SSiva Durga Prasad Paladugu {
21f91c3cb1SSiva Durga Prasad Paladugu 	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
22*394a65aaSTejas Patel 	const struct pm_proc *proc;
23f91c3cb1SSiva Durga Prasad Paladugu 
24f91c3cb1SSiva Durga Prasad Paladugu 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
25f91c3cb1SSiva Durga Prasad Paladugu 
26f91c3cb1SSiva Durga Prasad Paladugu 	if (cpu_id == -1)
27f91c3cb1SSiva Durga Prasad Paladugu 		return PSCI_E_INTERN_FAIL;
28f91c3cb1SSiva Durga Prasad Paladugu 
29*394a65aaSTejas Patel 	proc = pm_get_proc(cpu_id);
30f91c3cb1SSiva Durga Prasad Paladugu 
31*394a65aaSTejas Patel 	/* Send request to PMC to wake up selected ACPU core */
32*394a65aaSTejas Patel 	pm_req_wakeup(proc->node_id, (versal_sec_entry & 0xFFFFFFFF) | 0x1,
33*394a65aaSTejas Patel 		      versal_sec_entry >> 32, 0);
34f91c3cb1SSiva Durga Prasad Paladugu 
35*394a65aaSTejas Patel 	/* Clear power down request */
36*394a65aaSTejas Patel 	pm_client_wakeup(proc);
37f91c3cb1SSiva Durga Prasad Paladugu 
38f91c3cb1SSiva Durga Prasad Paladugu 	return PSCI_E_SUCCESS;
39f91c3cb1SSiva Durga Prasad Paladugu }
40f91c3cb1SSiva Durga Prasad Paladugu 
41f91c3cb1SSiva Durga Prasad Paladugu void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
42f91c3cb1SSiva Durga Prasad Paladugu {
43f91c3cb1SSiva Durga Prasad Paladugu 	/* Enable the gic cpu interface */
44f91c3cb1SSiva Durga Prasad Paladugu 	plat_versal_gic_pcpu_init();
45f91c3cb1SSiva Durga Prasad Paladugu 
46f91c3cb1SSiva Durga Prasad Paladugu 	/* Program the gic per-cpu distributor or re-distributor interface */
47f91c3cb1SSiva Durga Prasad Paladugu 	plat_versal_gic_cpuif_enable();
48f91c3cb1SSiva Durga Prasad Paladugu }
49f91c3cb1SSiva Durga Prasad Paladugu 
50f91c3cb1SSiva Durga Prasad Paladugu static const struct plat_psci_ops versal_nopmc_psci_ops = {
51*394a65aaSTejas Patel 	.pwr_domain_on			= versal_pwr_domain_on,
52f91c3cb1SSiva Durga Prasad Paladugu 	.pwr_domain_on_finish		= versal_pwr_domain_on_finish,
53f91c3cb1SSiva Durga Prasad Paladugu };
54f91c3cb1SSiva Durga Prasad Paladugu 
55f91c3cb1SSiva Durga Prasad Paladugu /*******************************************************************************
56f91c3cb1SSiva Durga Prasad Paladugu  * Export the platform specific power ops.
57f91c3cb1SSiva Durga Prasad Paladugu  ******************************************************************************/
58f91c3cb1SSiva Durga Prasad Paladugu int plat_setup_psci_ops(uintptr_t sec_entrypoint,
59f91c3cb1SSiva Durga Prasad Paladugu 			const struct plat_psci_ops **psci_ops)
60f91c3cb1SSiva Durga Prasad Paladugu {
61f91c3cb1SSiva Durga Prasad Paladugu 	versal_sec_entry = sec_entrypoint;
62f91c3cb1SSiva Durga Prasad Paladugu 
63f91c3cb1SSiva Durga Prasad Paladugu 	*psci_ops = &versal_nopmc_psci_ops;
64f91c3cb1SSiva Durga Prasad Paladugu 
65f91c3cb1SSiva Durga Prasad Paladugu 	return 0;
66f91c3cb1SSiva Durga Prasad Paladugu }
67