arm64: versal: Add support for new Xilinx Versal ACAPs

Xilinx is introducing Versal, an adaptive compute acceleration platform
(ACAP), built on 7nm FinFET process technology. Versal ACAPs combine Scalar
Processing Engines, Adaptable Hardware Engines, and Intelligent Engines with
leading-edge memory and interfacing technologies to deliver powerful
heterogeneous acceleration for any application. The Versal AI Core series has
five devices, offering 128 to 400 AI Engines. The series includes dual-core Arm
Cortex-A72 application processors, dual-core Arm Cortex-R5 real-time
processors, 256KB of on-chip memory with ECC, more than 1,900 DSP engines
optimized for high-precision floating point with low latency.

This patch adds Virtual QEMU platform support for
this SoC "versal_virt".

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
new file mode 100644
index 0000000..37d00f6
--- /dev/null
+++ b/plat/xilinx/versal/plat_psci.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <psci.h>
+#include "versal_private.h"
+
+static uintptr_t versal_sec_entry;
+
+static int versal_nopmc_pwr_domain_on(u_register_t mpidr)
+{
+	uint32_t r;
+	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
+
+	if (cpu_id == -1)
+		return PSCI_E_INTERN_FAIL;
+
+	/*
+	 * program RVBAR
+	 */
+	mmio_write_32(FPD_APU_RVBAR_L_0 + (cpu_id << 3), versal_sec_entry);
+	mmio_write_32(FPD_APU_RVBAR_H_0 + (cpu_id << 3), versal_sec_entry >> 32);
+
+	/*
+	 * clear VINITHI
+	 */
+	r = mmio_read_32(FPD_APU_CONFIG_0);
+	r &= ~(1 << FPD_APU_CONFIG_0_VINITHI_SHIFT << cpu_id);
+	mmio_write_32(FPD_APU_CONFIG_0, r);
+
+	/*
+	 * FIXME: Add power up sequence, By default it works
+	 * now without the need of it as it was powered up by
+	 * default.
+	 */
+
+	/*
+	 * clear power down request
+	 */
+	r = mmio_read_32(FPD_APU_PWRCTL);
+	r &= ~(1 << cpu_id);
+	mmio_write_32(FPD_APU_PWRCTL, r);
+
+	/*
+	 * release core reset
+	 */
+	r = mmio_read_32(CRF_RST_APU);
+	r &= ~((CRF_RST_APU_ACPU_PWRON_RESET |
+			CRF_RST_APU_ACPU_RESET) << cpu_id);
+	mmio_write_32(CRF_RST_APU, r);
+
+	return PSCI_E_SUCCESS;
+}
+
+void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	/* Enable the gic cpu interface */
+	plat_versal_gic_pcpu_init();
+
+	/* Program the gic per-cpu distributor or re-distributor interface */
+	plat_versal_gic_cpuif_enable();
+}
+
+static const struct plat_psci_ops versal_nopmc_psci_ops = {
+	.pwr_domain_on			= versal_nopmc_pwr_domain_on,
+	.pwr_domain_on_finish		= versal_pwr_domain_on_finish,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const struct plat_psci_ops **psci_ops)
+{
+	versal_sec_entry = sec_entrypoint;
+
+	*psci_ops = &versal_nopmc_psci_ops;
+
+	return 0;
+}