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