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