xref: /rk3399_ARM-atf/plat/xilinx/versal/plat_psci.c (revision d4821739ef36f8fda5504fa5c57e0c41f0e09c24)
1f91c3cb1SSiva Durga Prasad Paladugu /*
2*d4821739STejas 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 
7*d4821739STejas Patel #include <plat_private.h>
809d40e0eSAntonio Nino Diaz #include <common/debug.h>
909d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1009d40e0eSAntonio Nino Diaz #include <lib/psci/psci.h>
1109d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
1209d40e0eSAntonio Nino Diaz 
13f91c3cb1SSiva Durga Prasad Paladugu static uintptr_t versal_sec_entry;
14f91c3cb1SSiva Durga Prasad Paladugu 
15f91c3cb1SSiva Durga Prasad Paladugu static int versal_nopmc_pwr_domain_on(u_register_t mpidr)
16f91c3cb1SSiva Durga Prasad Paladugu {
17f91c3cb1SSiva Durga Prasad Paladugu 	uint32_t r;
18f91c3cb1SSiva Durga Prasad Paladugu 	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
19f91c3cb1SSiva Durga Prasad Paladugu 
20f91c3cb1SSiva Durga Prasad Paladugu 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
21f91c3cb1SSiva Durga Prasad Paladugu 
22f91c3cb1SSiva Durga Prasad Paladugu 	if (cpu_id == -1)
23f91c3cb1SSiva Durga Prasad Paladugu 		return PSCI_E_INTERN_FAIL;
24f91c3cb1SSiva Durga Prasad Paladugu 
25f91c3cb1SSiva Durga Prasad Paladugu 	/*
26f91c3cb1SSiva Durga Prasad Paladugu 	 * program RVBAR
27f91c3cb1SSiva Durga Prasad Paladugu 	 */
28f91c3cb1SSiva Durga Prasad Paladugu 	mmio_write_32(FPD_APU_RVBAR_L_0 + (cpu_id << 3), versal_sec_entry);
29f91c3cb1SSiva Durga Prasad Paladugu 	mmio_write_32(FPD_APU_RVBAR_H_0 + (cpu_id << 3), versal_sec_entry >> 32);
30f91c3cb1SSiva Durga Prasad Paladugu 
31f91c3cb1SSiva Durga Prasad Paladugu 	/*
32f91c3cb1SSiva Durga Prasad Paladugu 	 * clear VINITHI
33f91c3cb1SSiva Durga Prasad Paladugu 	 */
34f91c3cb1SSiva Durga Prasad Paladugu 	r = mmio_read_32(FPD_APU_CONFIG_0);
35f91c3cb1SSiva Durga Prasad Paladugu 	r &= ~(1 << FPD_APU_CONFIG_0_VINITHI_SHIFT << cpu_id);
36f91c3cb1SSiva Durga Prasad Paladugu 	mmio_write_32(FPD_APU_CONFIG_0, r);
37f91c3cb1SSiva Durga Prasad Paladugu 
38f91c3cb1SSiva Durga Prasad Paladugu 	/*
39f91c3cb1SSiva Durga Prasad Paladugu 	 * FIXME: Add power up sequence, By default it works
40f91c3cb1SSiva Durga Prasad Paladugu 	 * now without the need of it as it was powered up by
41f91c3cb1SSiva Durga Prasad Paladugu 	 * default.
42f91c3cb1SSiva Durga Prasad Paladugu 	 */
43f91c3cb1SSiva Durga Prasad Paladugu 
44f91c3cb1SSiva Durga Prasad Paladugu 	/*
45f91c3cb1SSiva Durga Prasad Paladugu 	 * clear power down request
46f91c3cb1SSiva Durga Prasad Paladugu 	 */
47f91c3cb1SSiva Durga Prasad Paladugu 	r = mmio_read_32(FPD_APU_PWRCTL);
48f91c3cb1SSiva Durga Prasad Paladugu 	r &= ~(1 << cpu_id);
49f91c3cb1SSiva Durga Prasad Paladugu 	mmio_write_32(FPD_APU_PWRCTL, r);
50f91c3cb1SSiva Durga Prasad Paladugu 
51f91c3cb1SSiva Durga Prasad Paladugu 	/*
52f91c3cb1SSiva Durga Prasad Paladugu 	 * release core reset
53f91c3cb1SSiva Durga Prasad Paladugu 	 */
54f91c3cb1SSiva Durga Prasad Paladugu 	r = mmio_read_32(CRF_RST_APU);
55f91c3cb1SSiva Durga Prasad Paladugu 	r &= ~((CRF_RST_APU_ACPU_PWRON_RESET |
56f91c3cb1SSiva Durga Prasad Paladugu 			CRF_RST_APU_ACPU_RESET) << cpu_id);
57f91c3cb1SSiva Durga Prasad Paladugu 	mmio_write_32(CRF_RST_APU, r);
58f91c3cb1SSiva Durga Prasad Paladugu 
59f91c3cb1SSiva Durga Prasad Paladugu 	return PSCI_E_SUCCESS;
60f91c3cb1SSiva Durga Prasad Paladugu }
61f91c3cb1SSiva Durga Prasad Paladugu 
62f91c3cb1SSiva Durga Prasad Paladugu void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
63f91c3cb1SSiva Durga Prasad Paladugu {
64f91c3cb1SSiva Durga Prasad Paladugu 	/* Enable the gic cpu interface */
65f91c3cb1SSiva Durga Prasad Paladugu 	plat_versal_gic_pcpu_init();
66f91c3cb1SSiva Durga Prasad Paladugu 
67f91c3cb1SSiva Durga Prasad Paladugu 	/* Program the gic per-cpu distributor or re-distributor interface */
68f91c3cb1SSiva Durga Prasad Paladugu 	plat_versal_gic_cpuif_enable();
69f91c3cb1SSiva Durga Prasad Paladugu }
70f91c3cb1SSiva Durga Prasad Paladugu 
71f91c3cb1SSiva Durga Prasad Paladugu static const struct plat_psci_ops versal_nopmc_psci_ops = {
72f91c3cb1SSiva Durga Prasad Paladugu 	.pwr_domain_on			= versal_nopmc_pwr_domain_on,
73f91c3cb1SSiva Durga Prasad Paladugu 	.pwr_domain_on_finish		= versal_pwr_domain_on_finish,
74f91c3cb1SSiva Durga Prasad Paladugu };
75f91c3cb1SSiva Durga Prasad Paladugu 
76f91c3cb1SSiva Durga Prasad Paladugu /*******************************************************************************
77f91c3cb1SSiva Durga Prasad Paladugu  * Export the platform specific power ops.
78f91c3cb1SSiva Durga Prasad Paladugu  ******************************************************************************/
79f91c3cb1SSiva Durga Prasad Paladugu int plat_setup_psci_ops(uintptr_t sec_entrypoint,
80f91c3cb1SSiva Durga Prasad Paladugu 			const struct plat_psci_ops **psci_ops)
81f91c3cb1SSiva Durga Prasad Paladugu {
82f91c3cb1SSiva Durga Prasad Paladugu 	versal_sec_entry = sec_entrypoint;
83f91c3cb1SSiva Durga Prasad Paladugu 
84f91c3cb1SSiva Durga Prasad Paladugu 	*psci_ops = &versal_nopmc_psci_ops;
85f91c3cb1SSiva Durga Prasad Paladugu 
86f91c3cb1SSiva Durga Prasad Paladugu 	return 0;
87f91c3cb1SSiva Durga Prasad Paladugu }
88