feat(zynqmp): introduce platform support

Introduce platform support for AMD-Xilinx zynqmp, an adaptive
compute acceleration platform (ACAP).

- TF-A cadence driver is used for console.
- TTC is used for Timers.

summary:
=================================
Tests Skipped : 193
Tests Passed  : 29
Tests Failed  : 0
Tests Crashed : 0
Total tests   : 222
=================================
NOTICE:  Exiting tests.

Change-Id: Ia63df682f8e97cc3a5d88468bf0df71f6bb3fc26
Signed-off-by: Akshay Belsare <akshay.belsare@amd.com>
Signed-off-by: Amit Nagal <amit.nagal@amd.com>
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
new file mode 100644
index 0000000..c88990e
--- /dev/null
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <drivers/console.h>
+#include <drivers/cadence/cdns_uart.h>
+#include <platform_def.h>
+
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl console_core_init
+	.globl console_core_putc
+	.globl console_core_getc
+	.globl console_core_flush
+
+	.globl  console_init
+	.globl  console_putc
+	.globl  console_getc
+	.globl  console_flush
+
+        /*
+         *  The console base is in the data section and not in .bss
+         *  even though it is zero-init. In particular, this allows
+         *  the console functions to start using this variable before
+         *  the runtime memory is initialized for images which do not
+         *  need to copy the .data section from ROM to RAM.
+         */
+        .section .data.console_base
+        .align 3
+console_base: .quad 0x0
+
+
+func console_init
+	adrp x3, console_base
+	str	x0, [x3, :lo12:console_base]
+	b	console_core_init
+endfunc console_init
+
+	/* -----------------------------------------------
+	 * int console_core_init(uintptr_t base_addr)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * We assume that the bootloader already set up
+	 * the HW (baud, ...) and only enable the trans-
+	 * mitter and receiver here.
+	 * In: x0 - console base address
+	 * Out: return 1 on success else 0 on error
+	 * Clobber list : x1, x2, x3
+	 * -----------------------------------------------
+	 */
+func console_core_init
+	/* Check the input base address */
+	cbz	x0, core_init_fail
+
+	/* RX/TX enabled & reset */
+	mov	w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST)
+	str	w3, [x0, #R_UART_CR]
+
+	mov	w0, #1
+	ret
+core_init_fail:
+	mov	w0, wzr
+	ret
+endfunc console_core_init
+
+
+	/* --------------------------------------------------------
+	 * int console_cdns_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_core_putc
+	cbz	x1, putc_error
+	/* Prepend '\r' to '\n' */
+	cmp	w0, #0xA
+	b.ne	2f
+1:
+	/* Check if the transmit FIFO is empty */
+	ldr	w2, [x1, #R_UART_SR]
+	tbz	w2, #UART_SR_INTR_TEMPTY_BIT, 1b
+	mov	w2, #0xD
+	str	w2, [x1, #R_UART_TX]
+2:
+	/* Check if the transmit FIFO is empty */
+	ldr	w2, [x1, #R_UART_SR]
+	tbz	w2, #UART_SR_INTR_TEMPTY_BIT, 2b
+	str	w0, [x1, #R_UART_TX]
+	ret
+putc_error:
+	mov	w0, #ERROR_NO_VALID_CONSOLE
+	ret
+endfunc console_core_putc
+
+	/* --------------------------------------------------------
+	 * int console_cdns_putc(int c, console_t *cdns)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_putc
+	adrp x1, console_base
+	ldr	x1, [x1, :lo12:console_base]
+	b	console_core_putc
+endfunc console_putc
+
+	/* ---------------------------------------------
+	 * int console_cdns_core_getc(uintptr_t base_addr)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 if no character is available.
+	 * In : x0 - console base address
+	 * Out: w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_core_getc
+	adr	x0, console_base
+	ldr	x0, [x0]
+
+	/* Check if the receive FIFO is empty */
+	ldr	w1, [x0, #R_UART_SR]
+	tbnz	w1, #UART_SR_INTR_REMPTY_BIT, no_char
+	ldr	w1, [x0, #R_UART_RX]
+	mov	w0, w1
+	ret
+no_char:
+	mov	w0, #ERROR_NO_PENDING_CHAR
+	ret
+endfunc console_core_getc
+
+	/* ---------------------------------------------
+	 * int console_cdns_getc(console_t *console)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 if no character is available.
+	 * In : x0 - pointer to console_t structure
+	 * Out: w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_getc
+	adrp	x0, console_base
+	ldr	x0, [x0, :lo12:console_base]
+	b	console_core_getc
+endfunc console_getc
+
+	/* ---------------------------------------------
+	 * int console_cdns_core_flush(uintptr_t base_addr)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - console base address
+	 * Out : void
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_core_flush
+	cbz	x0, flush_error
+	/* Loop until the transmit FIFO is empty */
+1:
+	ldr     w2, [x1, #R_UART_SR]
+	tbz     w2, #UART_SR_INTR_TEMPTY_BIT, 1b
+	str     w0, [x1, #R_UART_TX]
+	ret
+flush_error:
+	mov     w0, #ERROR_NO_VALID_CONSOLE
+	ret
+endfunc console_core_flush
+
+	/* ---------------------------------------------
+	 * void console_cdns_flush(console_t *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - pointer to console_t structure
+	 * Out : void.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_flush
+	adrp	x0, console_base
+	ldr	x0, [x0, :lo12:console_base]
+	b	console_core_flush
+endfunc console_flush
diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h
new file mode 100644
index 0000000..87e98ea
--- /dev/null
+++ b/include/drivers/cadence/cdns_uart.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDNS_UART_H
+#define CDNS_UART_H
+
+#include <drivers/console.h>
+#include <lib/utils_def.h>
+/* This is very minimalistic and will only work in QEMU.  */
+
+/* CADENCE Registers */
+#define R_UART_CR	0
+#define R_UART_CR_RXRST	(1 << 0) /* RX logic reset */
+#define R_UART_CR_TXRST	(1 << 1) /* TX logic reset */
+#define R_UART_CR_RX_EN	(1 << 2) /* RX enabled */
+#define R_UART_CR_TX_EN	(1 << 4) /* TX enabled */
+
+#define R_UART_SR		0x2C
+#define UART_SR_INTR_REMPTY_BIT	1
+#define UART_SR_INTR_TFUL_BIT	4
+#define UART_SR_INTR_TEMPTY_BIT	3
+
+#define R_UART_TX	0x30
+#define R_UART_RX	0x30
+
+#define CONSOLE_T_BASE		(U(5) * REGSZ)
+
+#endif /* CDNS_UART_H */
diff --git a/plat/xilinx/zynqmp/aarch64/plat_helpers.S b/plat/xilinx/zynqmp/aarch64/plat_helpers.S
new file mode 100644
index 0000000..48155bb
--- /dev/null
+++ b/plat/xilinx/zynqmp/aarch64/plat_helpers.S
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <drivers/console.h>
+
+	.globl	platform_get_core_pos
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+
+/*----------------------------------------------------------------------
+ * unsigned int platform_get_core_pos(unsigned long mpid)
+ *
+ * Function to calculate the core position.
+ * Return 0 to 3 as logical CPU ID.
+*/
+func platform_get_core_pos
+	lsr	x1, x0, #MPIDR_AFF0_SHIFT
+	and	x1, x1, #MPIDR_AFFLVL_MASK /* core id */
+	lsr	x2, x0, #MPIDR_AFF1_SHIFT
+	and	x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
+
+	/* core_id > PLATFORM_CORES_CLUSTER */
+	mov	x0, #-1
+	cmp	x1, #(PLATFORM_CORES_PER_CLUSTER - 1)
+	b.hi	1f
+
+	/* cluster_id > PLATFORM_CLUSTER_COUNT */
+	cmp	x2, #(PLATFORM_CLUSTER_COUNT - 1)
+	b.hi	1f
+
+	/* CorePos = CoreId + (ClusterId * cpus per cluster) */
+	mov	x3, #PLATFORM_CORES_PER_CLUSTER
+	mul	x3, x2, x3
+	add	x0, x1, x3
+
+1:
+	ret
+endfunc platform_get_core_pos
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0 - x4
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, ZYNQMP_UART_BASE
+	mov_imm	x1, ZYNQMP_CRASH_UART_CLK_IN_HZ
+	mov_imm	x2, ZYNQMP_UART_BAUDRATE
+	b	console_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, ZYNQMP_UART_BASE
+	b	console_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_flush()
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : r0 - r1
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	mov_imm	x1, ZYNQMP_UART_BASE
+	b	console_flush
+endfunc plat_crash_console_flush
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
new file mode 100644
index 0000000..cb3a707
--- /dev/null
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <utils_def.h>
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define TFTF_BASE			U(0x8000000)
+
+#define DRAM_BASE			0x0
+#define DRAM_SIZE			0x80000000
+
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	4
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
+					 PLATFORM_CORE_COUNT_PER_CLUSTER)
+#define PLATFORM_CORES_PER_CLUSTER	PLATFORM_CORE_COUNT_PER_CLUSTER
+
+#define PLATFORM_NUM_AFFS		(PLATFORM_CORE_COUNT + \
+					PLATFORM_CLUSTER_COUNT + 1)
+
+#define PLATFORM_MAX_AFFLVL		MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LEVEL		MPIDR_AFFLVL2
+
+#define PLAT_MAX_PWR_STATES_PER_LVL	2
+
+#define PLATFORM_STACK_SIZE		0x440
+#define PCPU_DV_MEM_STACK_SIZE		0x100
+
+#define TFTF_NVM_SIZE			0x600000
+#define TFTF_NVM_OFFSET			0x20000000
+
+/* total number of system nodes implemented by the platform */
+#define PLATFORM_SYSTEM_COUNT		U(1)
+
+/* UG1085 - system interrupts table */
+#define PLAT_MAX_SPI_OFFSET_ID		229
+
+/* Local state bit width for each level in the state-ID field of power state */
+#define PLAT_LOCAL_PSTATE_WIDTH		4
+
+#define PLAT_MAX_PWR_STATES_PER_LVL	2
+
+#define IRQ_PCPU_NS_TIMER		51
+
+#define IRQ_CNTPSIRQ1			80
+
+#define PLAT_SUSPEND_ENTRY_TIME		15
+#define PLAT_SUSPEND_ENTRY_EXIT_TIME	30
+
+#define IRQ_PCPU_HP_TIMER		26
+
+#define ZYNQMP_UART0_BASE		0xFF000000
+#define ZYNQMP_UART1_BASE		0xFF010000
+
+#define ZYNQMP_UART_BASE		ZYNQMP_UART0_BASE
+#define CRASH_CONSOLE_SIZE		0x1000
+
+#define ZYNQMP_CRASH_UART_CLK_IN_HZ	100000000
+#define ZYNQMP_UART_BAUDRATE		115200
+
+#define CACHE_WRITEBACK_SHIFT		6
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+/* Non-Secure Software Generated Interrupts IDs */
+
+#define IRQ_NS_SGI_0			0
+#define IRQ_NS_SGI_1			1
+#define IRQ_NS_SGI_2			2
+#define IRQ_NS_SGI_3			3
+#define IRQ_NS_SGI_4			4
+#define IRQ_NS_SGI_5			5
+#define IRQ_NS_SGI_6			6
+#define IRQ_NS_SGI_7			7
+
+/* Platform specific page table and MMU setup constants */
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
+
+/* Translation table constants */
+#define MAX_XLAT_TABLES			8
+#define MAX_MMAP_REGIONS		16
+
+/* ZYNQMP memory map related constants */
+
+/* Aggregate of all devices in the first GB */
+#define DEVICE0_BASE		U(0xFF000000)
+#define DEVICE0_SIZE		U(0x00E00000)
+#define DEVICE1_BASE		U(0xF9000000)
+#define DEVICE1_SIZE		U(0x00800000)
+
+/* GIC-400 & interrupt handling related constants */
+
+#define GIC_BASE		DEVICE1_BASE
+#define GIC_SIZE		0x00080000
+#define BASE_GICD_BASE		0xF9010000
+#define BASE_GICC_BASE		0xF9020000
+#define BASE_GICH_BASE		0xF9040000
+#define BASE_GICV_BASE		0xF9060000
+
+#define TTC_BASE		U(0xff140000)
+#define TTC_SIZE		U(0x00010000)
+
+#define SYS_CNT_BASE1		TTC_BASE
+#define SYS_CNT_SIZE		TTC_SIZE
+
+/* timer */
+#define LPD_IOU_SLCR		U(0xff180000)
+#define LPD_IOU_SLCR_SIZE	U(0x00010000)
+#define TTC_TIMER_IRQ		U(77)
+#define TTC_CLK_SEL_OFFSET	U(0x380)
+#define IRQ_TWDOG_INTID		TTC_TIMER_IRQ
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
new file mode 100644
index 0000000..201c2ee
--- /dev/null
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+XLNX_COMMON_PATH :=     plat/xilinx/common
+ZYNQMP_PATH     :=      plat/xilinx/zynqmp
+
+PLAT_INCLUDES	+=	-Iplat/xilinx/zynqmp/include/
+
+PLAT_SOURCES	:=	drivers/arm/gic/arm_gic_v2.c                    \
+			drivers/arm/gic/gic_common.c                    \
+			drivers/arm/gic/gic_v2.c			\
+			drivers/arm/timer/private_timer.c               \
+			drivers/cadence/uart/aarch64/cdns_console.S	\
+			plat/xilinx/zynqmp/aarch64/plat_helpers.S	\
+			plat/xilinx/zynqmp/zynqmp_pwr_state.c		\
+			plat/xilinx/zynqmp/zynqmp_topology.c		\
+			plat/xilinx/zynqmp/zynqmp_setup.c		\
+			${XLNX_COMMON_PATH}/timer/timers.c
+
+PLAT_TESTS_SKIP_LIST	:=	plat/xilinx/zynqmp/tests_to_skip.txt
+
+TFTF_CFLAGS             +=      -Wno-maybe-uninitialized -Wno-unused-variable
+
+ENABLE_ASSERTIONS       :=      1
+
+PLAT_SUPPORTS_NS_RESET  :=      1
+
+# Process PLAT_SUPPORTS_NS_RESET flag
+$(eval $(call assert_boolean,PLAT_SUPPORTS_NS_RESET))
+$(eval $(call add_define,TFTF_DEFINES,PLAT_SUPPORTS_NS_RESET))
+
+ifeq ($(USE_NVM),1)
+$(error "zynqmp port of TFTF doesn't currently support USE_NVM=1")
+endif
diff --git a/plat/xilinx/zynqmp/tests_to_skip.txt b/plat/xilinx/zynqmp/tests_to_skip.txt
new file mode 100644
index 0000000..9c32ae2
--- /dev/null
+++ b/plat/xilinx/zynqmp/tests_to_skip.txt
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+################################################################################
+# Disable the listed tests for zynqmp platform
+################################################################################
+#TESTS: tftf-validation
+Framework Validation/IRQ handling
+Framework Validation/Events API
+
+#TESTS: Timer framework Validation
+Timer framework Validation/Target timer to a power down cpu
+Timer framework Validation/Test scenario where multiple CPUs call same timeout
+Timer framework Validation/Stress test the timer framework
+
+#TESTS: Boot requirement tests
+Boot requirement tests
+
+#TESTS: CPU Hotplug/
+CPU Hotplug
+
+#TESTS: PSCI System Suspend Validation
+PSCI System Suspend Validation
+
+#TESTS: psci
+PSCI Affinity Info/Affinity info level0 powerdown
+PSCI CPU Suspend/CPU suspend to powerdown at level 0
+PSCI CPU Suspend/CPU suspend to powerdown at level 1
+PSCI CPU Suspend/CPU suspend to powerdown at level 2
+PSCI CPU Suspend/CPU suspend to standby at level 0
+PSCI CPU Suspend/CPU suspend to standby at level 1
+PSCI CPU Suspend/CPU suspend to standby at level 2
+PSCI CPU Suspend in OSI mode/CPU suspend to powerdown at level 0 in OSI mode
+PSCI CPU Suspend in OSI mode/CPU suspend to powerdown at level 1 in OSI mode
+PSCI CPU Suspend in OSI mode/CPU suspend to powerdown at level 2 in OSI mode
+PSCI CPU Suspend in OSI mode/CPU suspend to powerdown at level 3 in OSI mode
+PSCI CPU Suspend in OSI mode/CPU suspend to standby at level 0 in OSI mode
+PSCI CPU Suspend in OSI mode/CPU suspend to standby at level 1 in OSI mode
+PSCI CPU Suspend in OSI mode/CPU suspend to standby at level 2 in OSI mode
+PSCI System Suspend Validation/System suspend multiple times
+PSCI System Suspend Validation/system suspend from all cores
+PSCI System Suspend Validation/Validate suspend to RAM functionality
+
+#TESTS: psci stat
+PSCI STAT/Stats test cases for CPU OFF
+PSCI STAT/Stats test cases after system suspend
+
+#TESTS: el3-power-state
+EL3 power state parser validation
+
+#TESTS: SIMD
+SIMD,SVE Registers context/Check that SIMD registers context is preserved
+
+#TESTS: psci-extensive
+PSCI CPU ON OFF Stress Tests/Repeated shutdown of all cores to stress test CPU_ON, CPU_SUSPEND and CPU_OFF
+PSCI CPU ON OFF Stress Tests/PSCI CPU ON OFF stress test
+PSCI CPU ON OFF Stress Tests/Repeated hotplug of all cores to stress test CPU_ON and CPU_OFF
+PSCI CPU ON OFF Stress Tests/Random hotplug cores in a large iteration to stress boot path code
+
+#TESTS: SDEI
+SDEI
diff --git a/plat/xilinx/zynqmp/zynqmp_pwr_state.c b/plat/xilinx/zynqmp/zynqmp_pwr_state.c
new file mode 100644
index 0000000..4f3bc4b
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_pwr_state.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <arch.h>
+#include <platform.h>
+#include <psci.h>
+
+/*
+ * State IDs for local power states.
+ */
+#define ZYNQMP_RETENTION_STATE_ID	1	/* Valid for only CPUs */
+#define ZYNQMP_OFF_STATE_ID		0	/* Valid for CPUs and Clusters */
+
+/*
+ * Suspend depth definitions for each power state
+ */
+typedef enum {
+	ZYNQMP_RUN_DEPTH = 0,
+	ZYNQMP_RETENTION_DEPTH,
+	ZYNQMP_OFF_DEPTH,
+} suspend_depth_t;
+
+/* The state property array with details of idle state possible for the core */
+static const plat_state_prop_t core_state_prop[] = {
+	{ZYNQMP_RETENTION_DEPTH, ZYNQMP_RETENTION_STATE_ID, PSTATE_TYPE_STANDBY},
+	{ZYNQMP_OFF_DEPTH, ZYNQMP_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+	{0},
+};
+
+/* The state property array with details of idle state possible for the cluster */
+static const plat_state_prop_t cluster_state_prop[] = {
+	{ZYNQMP_OFF_DEPTH, ZYNQMP_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+	{0},
+};
+
+/* The state property array with details of idle state possible for the system level */
+static const plat_state_prop_t system_state_prop[] = {
+	{ZYNQMP_OFF_DEPTH, ZYNQMP_OFF_STATE_ID, PSTATE_TYPE_POWERDOWN},
+	{0},
+};
+
+const plat_state_prop_t *plat_get_state_prop(unsigned int level)
+{
+	switch (level) {
+	case MPIDR_AFFLVL0:
+		return core_state_prop;
+	case MPIDR_AFFLVL1:
+		return cluster_state_prop;
+	case MPIDR_AFFLVL2:
+		return system_state_prop;
+	default:
+		return NULL;
+	}
+}
diff --git a/plat/xilinx/zynqmp/zynqmp_setup.c b/plat/xilinx/zynqmp/zynqmp_setup.c
new file mode 100644
index 0000000..4a7d371
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_setup.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/console.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gic_v2.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_tables_v2.h>
+#include <drivers/console.h>
+#include <debug.h>
+#include <drivers/arm/arm_gic.h>
+
+static const mmap_region_t zynqmp_mmap[] = {
+	MAP_REGION_FLAT(DRAM_BASE + TFTF_NVM_OFFSET, TFTF_NVM_SIZE, MT_MEMORY | MT_RW | MT_NS),
+	MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(ZYNQMP_UART_BASE, CRASH_CONSOLE_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(TTC_BASE, TTC_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(LPD_IOU_SLCR, LPD_IOU_SLCR_SIZE, MT_DEVICE | MT_RW | MT_NS),
+	{0}
+};
+
+const mmap_region_t *tftf_platform_get_mmap(void)
+{
+	return zynqmp_mmap;
+}
+
+void tftf_plat_arch_setup(void)
+{
+	tftf_plat_configure_mmu();
+}
+
+void tftf_early_platform_setup(void)
+{
+	console_init(ZYNQMP_UART_BASE, ZYNQMP_CRASH_UART_CLK_IN_HZ,
+		     ZYNQMP_UART_BAUDRATE);
+}
+
+void plat_arm_gic_init(void)
+{
+	arm_gic_init(BASE_GICC_BASE, BASE_GICD_BASE, 0);
+}
+
+void tftf_platform_setup(void)
+{
+	plat_arm_gic_init();
+	arm_gic_setup_global();
+	arm_gic_setup_local();
+}
diff --git a/plat/xilinx/zynqmp/zynqmp_topology.c b/plat/xilinx/zynqmp/zynqmp_topology.c
new file mode 100644
index 0000000..f8262a8
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_topology.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <mmio.h>
+#include <plat_topology.h>
+#include <platform_def.h>
+#include <stddef.h>
+#include <tftf_lib.h>
+
+static const struct {
+	unsigned int cluster_id;
+	unsigned int cpu_id;
+} zynqmp_cores[PLATFORM_CORE_COUNT] = {
+	{ 0, 0 },
+	{ 0, 1 },
+	{ 0, 2 },
+	{ 0, 3 }
+};
+
+static const unsigned char zynqmp_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* Number of children of root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the cluster */
+	PLATFORM_CORES_PER_CLUSTER
+};
+
+const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void)
+{
+	return zynqmp_power_domain_tree_desc;
+}
+
+uint64_t tftf_plat_get_mpidr(unsigned int core_pos)
+{
+	assert(core_pos < PLATFORM_CORE_COUNT);
+
+	return make_mpid(zynqmp_cores[core_pos].cluster_id,
+			 zynqmp_cores[core_pos].cpu_id);
+}