Merge "docs: remove deprecated tc0 from list of supported FVPs" into integration
diff --git a/Makefile b/Makefile
index 03f9320..8d3ffe1 100644
--- a/Makefile
+++ b/Makefile
@@ -217,18 +217,16 @@
 ################################################################################
 ifeq (${ARM_ARCH_MAJOR},7)
 	target32-directive	= 	-target arm-none-eabi
-# Will set march32-directive from platform configuration
+# Will set march-directive from platform configuration
 else
 	target32-directive	= 	-target armv8a-none-eabi
 
 # Set the compiler's target architecture profile based on
 # ARM_ARCH_MAJOR ARM_ARCH_MINOR options
 	ifeq (${ARM_ARCH_MINOR},0)
-		march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
-		march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
+		march-directive	= 	-march=armv${ARM_ARCH_MAJOR}-a
 	else
-		march32-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
-		march64-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
+		march-directive	= 	-march=armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
 	endif #(ARM_ARCH_MINOR)
 endif #(ARM_ARCH_MAJOR)
 
@@ -273,24 +271,20 @@
 # Set the compiler's architecture feature modifiers
 ifneq ($(arch-features), none)
 	# Strip "none+" from arch-features
-	arch-features		:=	$(subst none+,,$(arch-features))
-	ifeq ($(ARCH), aarch32)
-		march32-directive	:=	$(march32-directive)+$(arch-features)
-	else
-		march64-directive	:=	$(march64-directive)+$(arch-features)
-	endif
+	arch-features	:=	$(subst none+,,$(arch-features))
+	march-directive	:=	$(march-directive)+$(arch-features)
 # Print features
         $(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
 endif #(arch-features)
 
 ifneq ($(findstring clang,$(notdir $(CC))),)
 	ifneq ($(findstring armclang,$(notdir $(CC))),)
-		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi $(march32-directive)
-		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi $(march64-directive)
+		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi $(march-directive)
+		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi $(march-directive)
 		LD			:=	$(LINKER)
 	else
-		TF_CFLAGS_aarch32	=	$(target32-directive) $(march32-directive)
-		TF_CFLAGS_aarch64	:=	-target aarch64-elf $(march64-directive)
+		TF_CFLAGS_aarch32	=	$(target32-directive) $(march-directive)
+		TF_CFLAGS_aarch64	:=	-target aarch64-elf $(march-directive)
 		LD			:=	$(shell $(CC) --print-prog-name ld.lld)
 
 		AR			:=	$(shell $(CC) --print-prog-name llvm-ar)
@@ -302,8 +296,8 @@
 	PP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
 	AS		:=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
 else ifneq ($(findstring gcc,$(notdir $(CC))),)
-	TF_CFLAGS_aarch32	=	$(march32-directive)
-	TF_CFLAGS_aarch64	=	$(march64-directive)
+	TF_CFLAGS_aarch32	=	$(march-directive)
+	TF_CFLAGS_aarch64	=	$(march-directive)
 	ifeq ($(ENABLE_LTO),1)
 		# Enable LTO only for aarch64
 		ifeq (${ARCH},aarch64)
@@ -314,8 +308,8 @@
 	endif
 	LD			=	$(LINKER)
 else
-	TF_CFLAGS_aarch32	=	$(march32-directive)
-	TF_CFLAGS_aarch64	=	$(march64-directive)
+	TF_CFLAGS_aarch32	=	$(march-directive)
+	TF_CFLAGS_aarch64	=	$(march-directive)
 	LD			=	$(LINKER)
 endif #(clang)
 
@@ -355,8 +349,7 @@
 	TF_CFLAGS_aarch64	+=	-mbranch-protection=${BP_OPTION}
 endif #(BP_OPTION)
 
-ASFLAGS_aarch32		=	$(march32-directive)
-ASFLAGS_aarch64		=	$(march64-directive)
+ASFLAGS		+=	$(march-directive)
 
 ##############################################################################
 # WARNINGS Configuration
@@ -444,7 +437,7 @@
 ################################################################################
 CPPFLAGS		=	${DEFINES} ${INCLUDES} ${MBEDTLS_INC} -nostdinc	\
 				$(ERRORS) $(WARNINGS)
-ASFLAGS			+=	$(CPPFLAGS) $(ASFLAGS_$(ARCH))			\
+ASFLAGS			+=	$(CPPFLAGS)                 			\
 				-ffreestanding -Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
 				-ffunction-sections -fdata-sections		\
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 268d329..1c8c68f 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -91,7 +91,7 @@
 	smc_args_t ffa_forward_result;
 	ffa_endpoint_id16_t receiver = arg5;
 
-	ffa_forward_result = ffa_msg_send_direct_req(ffa_endpoint_source(arg1),
+	ffa_forward_result = ffa_msg_send_direct_req(tsp_id,
 						     receiver,
 						     FF_A_ECHO_MESSAGE, arg4,
 						     0, 0, 0);
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 131cca1..3d648c4 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -2733,12 +2733,12 @@
 the toolchain  target architecture directive.
 
 Platform may choose to not define straight the toolchain target architecture
-directive by defining ``MARCH32_DIRECTIVE``.
+directive by defining ``MARCH_DIRECTIVE``.
 I.e:
 
 .. code:: make
 
-   MARCH32_DIRECTIVE := -mach=armv7-a
+   MARCH_DIRECTIVE := -mach=armv7-a
 
 Code Structure
 --------------
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index c8ff7d5..7ca8aa9 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -648,12 +648,6 @@
    invert this behavior. Lower addresses will be printed at the top and higher
    addresses at the bottom.
 
--  ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
-   runtime software in AArch32 mode, which is required to run AArch32 on Juno.
-   By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
-   AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
-   images.
-
 -  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
    used for generating the PKCS keys and subsequent signing of the certificate.
    It accepts 5 values: ``rsa``, ``rsa_1_5``, ``ecdsa``, ``ecdsa-brainpool-regular``
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index e7e7ee7..e0b9242 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -169,6 +169,21 @@
    require all the CPUs to execute the CPU specific power down sequence to
    complete a warm reboot sequence in which only the CPUs are power cycled.
 
+Arm FVP Build Options
+---------------------
+
+- ``FVP_TRUSTED_SRAM_SIZE``: Size (in kilobytes) of the Trusted SRAM region to
+  utilize when building for the FVP platform. This option defaults to 256.
+
+Arm Juno Build Options
+----------------------
+
+-  ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
+   runtime software in AArch32 mode, which is required to run AArch32 on Juno.
+   By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
+   AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
+   images.
+
 --------------
 
 .. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png
diff --git a/docs/plat/qti-msm8916.rst b/docs/plat/qti-msm8916.rst
index 09a79b7..d7c3642 100644
--- a/docs/plat/qti-msm8916.rst
+++ b/docs/plat/qti-msm8916.rst
@@ -7,7 +7,7 @@
 is the `DragonBoard 410c`_ single-board computer, but the SoC is also used in
 various mid-range smartphones/tablets.
 
-The TF-A/BL31 port for MSM8916 provides a minimal, community-maintained
+The TF-A port for MSM8916 provides a minimal, community-maintained
 EL3 firmware. It is primarily based on information from the public
 `Snapdragon 410E Technical Reference Manual`_ combined with a lot of
 trial and error to actually make it work.
@@ -20,8 +20,7 @@
 
 Functionality
 -------------
-
-The BL31 port is much more minimal compared to the original firmware and
+The TF-A port is much more minimal compared to the original firmware and
 therefore expects the non-secure world (e.g. Linux) to manage more hardware,
 such as the SMMUs and all remote processors (RPM, WCNSS, Venus, Modem).
 Everything except modem is currently functional with a slightly modified version
@@ -41,28 +40,74 @@
 
 Boot Flow
 ---------
-BL31 replaces the original ``tz`` firmware in the boot flow::
+BL31 (AArch64) or BL32/SP_MIN (AArch32) replaces the original ``tz`` firmware
+in the boot flow::
 
 	Boot ROM (PBL) -> SBL -> BL31 (EL3) -> U-Boot (EL2) -> Linux (EL2)
 
-By default, BL31 enters the non-secure world in EL2 AArch64 state at address
-``0x8f600000``. The original hypervisor firmware (``hyp``) is not used, you can
-use KVM or another hypervisor. The entry address is fixed in the BL31 binary
-but can be changed using the ``PRELOADED_BL33_BASE`` make file parameter.
+After initialization the normal world starts at a fixed entry address in EL2/HYP
+mode, configured using ``PRELOADED_BL33_BASE``. At runtime, it is expected that
+the normal world bootloader was already loaded into RAM by a previous firmware
+component (usually SBL) and that it is capable of running in EL2/HYP mode.
 
-Using an AArch64 bootloader (such as `U-Boot for DragonBoard 410c`_) is
-recommended. AArch32 bootloaders (such as the original Little Kernel bootloader
-from Qualcomm) are not directly supported, although it is possible to use an EL2
-shim loader to temporarily switch to AArch32 state.
+`U-Boot for DragonBoard 410c`_ is recommended if possible. The original Little
+Kernel-based bootloader from Qualcomm does not support EL2/HYP, but can be
+booted using an additional shim loader such as `tfalkstub`_.
+
+Build
+-----
+It is possible to build for either AArch64 or AArch32. AArch64 is the preferred
+build option.
+
+AArch64 (BL31)
+^^^^^^^^^^^^^^
+Setup the cross compiler for AArch64 and build BL31 for ``msm8916``::
+
+	$ make CROSS_COMPILE=aarch64-none-elf- PLAT=msm8916
+
+The BL31 ELF image is generated in ``build/msm8916/release/bl31/bl31.elf``.
+
+AArch32 (BL32/SP_MIN)
+^^^^^^^^^^^^^^^^^^^^^
+Setup the cross compiler for AArch32 and build BL32 with SP_MIN for ``msm8916``::
+
+	$ make CROSS_COMPILE=arm-none-eabi- PLAT=msm8916 ARCH=aarch32 AARCH32_SP=sp_min
+
+The BL32 ELF image is generated in ``build/msm8916/release/bl32/bl32.elf``.
+
+Build Options
+-------------
+Some options can be changed at build time by adding them to the make command line:
+
+ * ``QTI_UART_NUM``: Number of UART controller to use for debug output and crash
+   reports. This must be the same UART as used by earlier boot firmware since
+   the UART controller does not get fully initialized at the moment. Defaults to
+   the usual debug UART used for the platform (see ``platform.mk``).
+ * ``QTI_RUNTIME_UART``: By default (``0``) the UART is only used for the boot
+   process and critical crashes. If set to ``1`` it is also used for runtime
+   messages. Note that this option can only be used if the UART is reserved in
+   the normal world and the necessary clocks remain enabled.
+
+The memory region used for the different firmware components is not fixed and
+can be changed on the make command line. The default values match the addresses
+used by the original firmware (see ``platform.mk``):
+
+ * ``PRELOADED_BL33_BASE``: The entry address for the normal world. Usually
+   refers to the first bootloader (e.g. U-Boot).
+ * ``BL31_BASE``: Base address for the BL31 firmware component. Must point to
+   a 64K-aligned memory region with at least 128 KiB space that is permanently
+   reserved in the normal world.
+ * ``BL32_BASE``: Base address for the BL32 firmware component.
+
+   * **AArch32:** BL32 is used in place of BL31, so the option is equivalent to
+     ``BL31_BASE``.
+   * **AArch64:** Secure-EL1 Payload. Defaults to using 128 KiB of space
+     directly after BL31. For testing only, the port is primarily intended as
+     a minimal PSCI implementation without a separate secure world.
 
 Installation
 ------------
-First, setup the cross compiler for AArch64 and build TF-A for ``msm8916``::
-
-	$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=msm8916
-
-The BL31 ELF image is generated in ``build/msm8916/release/bl31/bl31.elf``.
-This image must be "signed" before flashing it, even if the board has secure
+The ELF image must be "signed" before flashing it, even if the board has secure
 boot disabled. In this case the signature does not provide any security,
 but it provides the firmware with required metadata.
 
@@ -75,6 +120,10 @@
 Then install the resulting ``build/msm8916/release/bl31/bl31-test-signed.mbn``
 to the ``tz`` partition on the device. BL31 should be running after a reboot.
 
+.. note::
+	On AArch32 the ELF image is called ``bl32.elf``.
+	The installation procedure is identical.
+
 .. warning::
 	Do not flash incorrectly signed firmware on devices that have secure
 	boot enabled! Make sure that you have a way to recover the board in case
@@ -82,8 +131,11 @@
 
 Boot Trace
 ----------
-BL31 prints some lines on the debug console UART2, which will usually look like
-this (with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown)::
+
+AArch64 (BL31)
+^^^^^^^^^^^^^^
+BL31 prints some lines on the debug console, which will usually look like this
+(with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown)::
 
 	...
 	S - DDR Frequency, 400 MHz
@@ -109,8 +161,34 @@
 	Qualcomm-DragonBoard 410C
 	...
 
+AArch32 (BL32/SP_MIN)
+^^^^^^^^^^^^^^^^^^^^^
+BL32/SP_MIN prints some lines on the debug console, which will usually look like
+this (with ``DEBUG=1``, otherwise only the ``NOTICE`` lines are shown)::
+
+	...
+	S - DDR Frequency, 400 MHz
+	NOTICE:  SP_MIN: v2.8(debug):v2.8
+	NOTICE:  SP_MIN: Built : 23:03:31, Mar 31 2023
+	INFO:    SP_MIN: Platform setup start
+	INFO:    ARM GICv2 driver initialized
+	INFO:    SP_MIN: Platform setup done
+	INFO:    SP_MIN: Initializing runtime services
+	INFO:    BL32: cortex_a53: CPU workaround for 819472 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for 824069 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for 826319 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for 827319 was applied
+	INFO:    BL32: cortex_a53: CPU workaround for disable_non_temporal_hint was applied
+	INFO:    SP_MIN: Preparing exit to normal world
+	INFO:    Entry point address = 0x86400000
+	INFO:    SPSR = 0x1da
+	Android Bootloader - UART_DM Initialized!!!
+	[0] welcome to lk
+	...
+
 .. _Qualcomm Snapdragon 410: https://www.qualcomm.com/products/snapdragon-processors-410
 .. _DragonBoard 410c: https://www.96boards.org/product/dragonboard410c/
 .. _Snapdragon 410E Technical Reference Manual: https://developer.qualcomm.com/download/sd410/snapdragon-410e-technical-reference-manual.pdf
 .. _U-Boot for DragonBoard 410c: https://u-boot.readthedocs.io/en/latest/board/qualcomm/dragonboard410c.html
 .. _qtestsign: https://github.com/msm8916-mainline/qtestsign
+.. _tfalkstub: https://github.com/msm8916-mainline/tfalkstub
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index b16510f..abbf976 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,7 +49,7 @@
 
 static inline uint32_t fdt_blob_size(const void *dtb)
 {
-	const uint32_t *dtb_header = dtb;
+	const uint32_t *dtb_header = (const uint32_t *)dtb;
 
 	return fdt32_to_cpu(dtb_header[1]);
 }
@@ -60,7 +60,8 @@
 	const void *prop = fdt_getprop(fdt, node, "status", &len);
 
 	/* A non-existing status property means the device is enabled. */
-	return (prop == NULL) || (len == 5 && strcmp(prop, "okay") == 0);
+	return (prop == NULL) || (len == 5 && strcmp((const char *)prop,
+		"okay") == 0);
 }
 
 #define fdt_for_each_compatible_node(dtb, node, compatible_str)       \
diff --git a/include/lib/cpus/aarch64/neoverse_hermes.h b/include/lib/cpus/aarch64/neoverse_hermes.h
new file mode 100644
index 0000000..22492c3
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_hermes.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_HERMES_H
+#define NEOVERSE_HERMES_H
+
+#define NEOVERSE_HERMES_MIDR				U(0x410FD8E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_HERMES_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_HERMES_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* NEOVERSE_HERMES_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 16be971..6be6ffd 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -775,7 +775,9 @@
 #define PLAT_PERCPU_BAKERY_LOCK_SIZE		(1 * CACHE_WRITEBACK_GRANULE)
 
 /* Priority levels for ARM platforms */
+#if RAS_FFH_SUPPORT
 #define PLAT_RAS_PRI			0x10
+#endif
 #define PLAT_SDEI_CRITICAL_PRI		0x60
 #define PLAT_SDEI_NORMAL_PRI		0x70
 
diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S
index c262276..dfa159f 100644
--- a/lib/cpus/aarch32/cortex_a32.S
+++ b/lib/cpus/aarch32/cortex_a32.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -117,14 +117,7 @@
 	b	cortex_a32_disable_smp
 endfunc cortex_a32_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A32. Must follow AAPCS.
- */
-func cortex_a32_errata_report
-	bx	lr
-endfunc cortex_a32_errata_report
-#endif
+errata_report_shim cortex_a32
 
 declare_cpu_ops cortex_a32, CORTEX_A32_MIDR, \
 	cortex_a32_reset_func, \
diff --git a/lib/cpus/aarch64/neoverse_hermes.S b/lib/cpus/aarch64/neoverse_hermes.S
new file mode 100644
index 0000000..cb90b71
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_hermes.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_hermes.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse Hermes must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse Hermes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start neoverse_hermes
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end neoverse_hermes
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func neoverse_hermes_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set NEOVERSE_HERMES_CPUPWRCTLR_EL1, NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc neoverse_hermes_core_pwr_dwn
+
+errata_report_shim neoverse_hermes
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse Hermes specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.neoverse_hermes_regs, "aS"
+neoverse_hermes_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_hermes_cpu_reg_dump
+	adr	x6, neoverse_hermes_regs
+	mrs	x8, NEOVERSE_HERMES_CPUECTLR_EL1
+	ret
+endfunc neoverse_hermes_cpu_reg_dump
+
+declare_cpu_ops neoverse_hermes, NEOVERSE_HERMES_MIDR, \
+	neoverse_hermes_reset_func, \
+	neoverse_hermes_core_pwr_dwn
diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk
index eec85cc..a8e9d50 100644
--- a/make_helpers/armv7-a-cpus.mk
+++ b/make_helpers/armv7-a-cpus.mk
@@ -15,9 +15,9 @@
 # armClang requires -march=armv7-a for all ARMv7 Cortex-A. To comply with
 # all, just drop -march and supply only -mcpu.
 
-# Platform can override march32-directive through MARCH32_DIRECTIVE
-ifdef MARCH32_DIRECTIVE
-march32-directive		:= $(MARCH32_DIRECTIVE)
+# Platform can override march-directive through MARCH_DIRECTIVE
+ifdef MARCH_DIRECTIVE
+march-directive		:= $(MARCH_DIRECTIVE)
 else
 march32-set-${ARM_CORTEX_A5}	:= -mcpu=cortex-a5
 march32-set-${ARM_CORTEX_A7}	:= -mcpu=cortex-a7
@@ -29,7 +29,7 @@
 
 # default to -march=armv7-a as target directive
 march32-set-yes			?= -march=armv7-a
-march32-directive		:= ${march32-set-yes} ${march32-neon-yes}
+march-directive		:= ${march32-set-yes} ${march32-neon-yes}
 endif
 
 # Platform may override these extension support directives:
diff --git a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
index b9e4f86..72dfa30 100644
--- a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
+++ b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
@@ -27,6 +27,7 @@
 					  void *handle, uint64_t flags)
 {
 	uint64_t ret;
+	uint32_t src_dst;
 
 	/* Determine if we have a 64 or 32 direct request. */
 	if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) {
@@ -36,18 +37,22 @@
 	} else {
 		panic(); /* Unknown SMC. */
 	}
+
 	/*
 	 * Handle the incoming request. For testing purposes we echo the
 	 * incoming message.
 	 */
-	INFO("Logical Partition: Received Direct Request from %s world!\n",
-	     secure_origin ? "Secure" : "Normal");
+	INFO("LSP: Received Direct Request from %s world (0x%x)\n",
+	     secure_origin ? "Secure" : "Normal", ffa_endpoint_source(x1));
 
+	/* Populate the source and destination IDs. */
+	src_dst = (uint32_t) LP_PARTITION_ID << FFA_DIRECT_MSG_SOURCE_SHIFT |
+		  ffa_endpoint_source(x1) << FFA_DIRECT_MSG_DESTINATION_SHIFT;
 	/*
 	 * Logical SP's must always send a direct response so we can populate
 	 * our response directly.
 	 */
-	SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0);
+	SMC_RET8(handle, ret, src_dst, 0, x4, 0, 0, 0, 0);
 }
 
 /* Register logical partition  */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 9e72ba0..cd468e1 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -43,7 +43,7 @@
  */
 #define PLAT_ARM_CLUSTER_COUNT		U(FVP_CLUSTER_COUNT)
 
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	UL(0x00040000)	/* 256 KB */
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	(FVP_TRUSTED_SRAM_SIZE * UL(1024))
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	UL(0x00000000)
 #define PLAT_ARM_TRUSTED_ROM_SIZE	UL(0x04000000)	/* 64 MB */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 25c963b..436cab3 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -24,6 +24,10 @@
 
 FVP_DT_PREFIX		:= fvp-base-gicv3-psci
 
+# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
+# the FVP platform. This option defaults to 256.
+FVP_TRUSTED_SRAM_SIZE	:= 256
+
 # This is a very trickly TEMPORARY fix. Enabling ALL features exceeds BL31's
 # progbits limit. We need a way to build all useful configurations while waiting
 # on the fvp to increase its SRAM size. The problem is twofild:
@@ -104,6 +108,9 @@
 # Pass FVP_GICR_REGION_PROTECTION to the build system.
 $(eval $(call add_define,FVP_GICR_REGION_PROTECTION))
 
+# Pass FVP_TRUSTED_SRAM_SIZE to the build system.
+$(eval $(call add_define,FVP_TRUSTED_SRAM_SIZE))
+
 # Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2,
 # choose the CCI driver , else the CCN driver
 ifeq ($(FVP_CLUSTER_COUNT), 0)
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
index 76e63aa..993aa46 100644
--- a/plat/arm/board/morello/include/platform_def.h
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -163,7 +163,59 @@
 #define PLAT_MHUV2_BASE				PLAT_CSS_MHU_BASE
 #define PLAT_MAX_PWR_LVL			U(2)
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
+/* Interrupt handling constants */
+#define MORELLO_IRQ_SEC_UART			U(87)
+#define MORELLO_IRQ_DISPLAY_TCU_EVENT_Q		U(107)
+#define MORELLO_IRQ_DISPLAY_TCU_CMD_SYNC	U(111)
+#define MORELLO_IRQ_DISPLAY_TCU_GLOBAL		U(113)
+#define MORELLO_IRQ_MMU_TCU1_EVENT_Q		U(257)
+#define MORELLO_IRQ_MMU_TCU1_CMD_SYNC		U(258)
+#define MORELLO_IRQ_MMU_TCU1_GLOBAL		U(259)
+#define MORELLO_IRQ_MMU_TCU2_EVENT_Q		U(264)
+#define MORELLO_IRQ_MMU_TCU2_CMD_SYNC		U(265)
+#define MORELLO_IRQ_MMU_TCU2_GLOBAL		U(266)
+#define MORELLO_IRQ_CLUSTER0_MHU		U(349)
+#define MORELLO_IRQ_CLUSTER1_MHU		U(351)
+#define MORELLO_IRQ_P0_REFCLK			U(412)
+#define MORELLO_IRQ_P1_REFCLK			U(413)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+	ARM_G1S_IRQ_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_SEC_UART, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_DISPLAY_TCU_EVENT_Q, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_DISPLAY_TCU_CMD_SYNC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_DISPLAY_TCU_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU1_EVENT_Q, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU1_CMD_SYNC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU1_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU2_EVENT_Q, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU2_CMD_SYNC, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_MMU_TCU2_GLOBAL, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_CLUSTER0_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_CLUSTER1_MHU, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_P0_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(MORELLO_IRQ_P1_REFCLK, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL)
+
 #define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
 
 #define MORELLO_DEVICE_BASE			ULL(0x08000000)
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 8e63de5..ff1a437 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -8,7 +8,7 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
-
+#include <sgi_sdei.h>
 #include <sgi_soc_platform_def_v2.h>
 
 #if (CSS_SGI_PLATFORM_VARIANT == 1)
diff --git a/plat/arm/board/rdn2/include/rdn2_ras.h b/plat/arm/board/rdn2/include/rdn2_ras.h
new file mode 100644
index 0000000..1d9af60
--- /dev/null
+++ b/plat/arm/board/rdn2/include/rdn2_ras.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDN2_RAS_H
+#define RDN2_RAS_H
+
+#include <sgi_ras.h>
+
+extern struct plat_sgi_ras_config ras_config;
+
+#endif /* RDN2_RAS_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index ca55036..9ebca23 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -69,6 +69,12 @@
 BL31_CFLAGS		+=	-DPLAT_XLAT_TABLES_DYNAMIC
 endif
 
+ifeq (${RAS_FFH_SUPPORT},1)
+BL31_SOURCES		+=	${RDN2_BASE}/rdn2_ras.c			\
+				${CSS_ENT_BASE}/ras/sgi_ras_common.c	\
+				${CSS_ENT_BASE}/ras/sgi_ras_sram.c
+endif
+
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${RDN2_BASE}/fdts/${PLAT}_fw_config.dts	\
 				${RDN2_BASE}/fdts/${PLAT}_tb_fw_config.dts
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index a5564ce..e8a967e 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -8,6 +8,7 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <rdn2_ras.h>
 #include <sgi_soc_platform_def_v2.h>
 #include <sgi_plat.h>
 
@@ -134,5 +135,9 @@
 #endif
 
 	sgi_bl31_common_platform_setup();
+
+#if RAS_FFH_SUPPORT
+	sgi_ras_platform_setup(&ras_config);
+#endif
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn2/rdn2_ras.c b/plat/arm/board/rdn2/rdn2_ras.c
new file mode 100644
index 0000000..c1e5ab6
--- /dev/null
+++ b/plat/arm/board/rdn2/rdn2_ras.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+#include <sgi_ras.h>
+#include <sgi_sdei.h>
+
+struct sgi_ras_ev_map plat_ras_map[] = {
+	/* Non Secure base RAM ECC CE interrupt */
+	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_CE_INT, SGI_RAS_INTR_TYPE_SPI},
+
+	/* Non Secure base RAM ECC UE interrupt */
+	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_UE_INT, SGI_RAS_INTR_TYPE_SPI},
+};
+
+/* RAS error record list definition, used by the common RAS framework. */
+struct err_record_info plat_err_records[] = {
+	/* Base element RAM Non-secure error record. */
+	ERR_RECORD_MEMMAP_V1(SOC_NS_RAM_ERR_REC_BASE, 4, NULL,
+				&sgi_ras_sram_intr_handler, 0),
+};
+
+/* RAS error interrupt list definition, used by the common RAS framework. */
+struct ras_interrupt plat_ras_interrupts[] = {
+	{
+		.intr_number = NS_RAM_ECC_CE_INT,
+		.err_record = &plat_err_records[0],
+	}, {
+		.intr_number = NS_RAM_ECC_UE_INT,
+		.err_record = &plat_err_records[0],
+	},
+};
+
+/* Registers the RAS error record list with common RAS framework. */
+REGISTER_ERR_RECORD_INFO(plat_err_records);
+/* Registers the RAS error interrupt info list with common RAS framework. */
+REGISTER_RAS_INTERRUPTS(plat_ras_interrupts);
+
+/* Platform RAS handling config data definition */
+struct plat_sgi_ras_config ras_config = {
+	plat_ras_map,
+	ARRAY_SIZE(plat_ras_map)
+};
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
index dff6a19..b836a7f 100644
--- a/plat/arm/board/rdn2/rdn2_security.c
+++ b/plat/arm/board/rdn2/rdn2_security.c
@@ -8,8 +8,16 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
+#define RDN2_TZC_CPER_REGION					\
+	{CSS_SGI_SP_CPER_BUF_BASE, (CSS_SGI_SP_CPER_BUF_BASE +	\
+	CSS_SGI_SP_CPER_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+	PLAT_ARM_TZC_NS_DEV_ACCESS}
+
 static const arm_tzc_regions_info_t tzc_regions[] = {
 	ARM_TZC_REGIONS_DEF,
+#if RAS_FFH_SUPPORT
+	RDN2_TZC_CPER_REGION,
+#endif
 	{}
 };
 
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index c6cf0e6..b9c785f 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -204,7 +204,11 @@
 					SOC_CSS_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#if RAS_FFH_SUPPORT
 #define PLAT_SP_PRI				PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI				0x10
+#endif
 
 #if SPM_MM && RAS_FFH_SUPPORT
 /*
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/css/sgi/include/sgi_ras.h
index e69a684..24bbfa7 100644
--- a/plat/arm/css/sgi/include/sgi_ras.h
+++ b/plat/arm/css/sgi/include/sgi_ras.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,15 +7,57 @@
 #ifndef SGI_RAS_H
 #define SGI_RAS_H
 
+#include <lib/extensions/ras.h>
+#include <plat/common/platform.h>
+
 /*
- * Mapping the RAS interrupt with SDEI event number and the event
- * id used with Standalone MM code
+ * Interrupt type supported.
+ * - SGI_RAS_INTR_TYPE_SPI: Denotes a SPI interrupt
+ * - SGI_RAS_INTR_TYPE_PPI: Denotes a PPI interrupt
  */
+#define SGI_RAS_INTR_TYPE_SPI 0
+#define SGI_RAS_INTR_TYPE_PPI 1
+
+/*
+ * MM Communicate information structure. Required to generate MM Communicate
+ * payload to be shared with Standalone MM.
+ */
+typedef struct mm_communicate_header {
+	struct efi_guid	header_guid;
+	size_t		message_len;
+	uint8_t		data[1];
+} mm_communicate_header_t;
+
+/* RAS error info data structure. */
 struct sgi_ras_ev_map {
 	int sdei_ev_num;	/* SDEI Event number */
 	int intr;		/* Physical intr number */
+	int intr_type;          /* Interrupt Type (SPI or PPI)*/
 };
 
-int sgi_ras_intr_handler_setup(void);
+/* RAS config data structure. Must be defined by each platform. */
+struct plat_sgi_ras_config {
+	struct sgi_ras_ev_map *ev_map;
+	int ev_map_size;
+};
+
+/*
+ * Find event map for a given interrupt number. On success, returns pointer
+ * to the event map. On error, returns NULL.
+ */
+struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num);
+
+/*
+ * Initialization function for the framework.
+ *
+ * Registers RAS config provided by the platform and then configures and
+ * enables interrupt for each registered error. On success, return 0.
+ */
+int sgi_ras_platform_setup(struct plat_sgi_ras_config *config);
+
+/* Base element RAM RAS interrupt handler function. */
+int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data);
 
 #endif /* SGI_RAS_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
index acf31eb..d659ae5 100644
--- a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
@@ -58,6 +58,11 @@
 #define END_KEY_BASE			(SOC_KEYS_BASE + 0x0044)
 #define END_KEY_SIZE			U(32)
 
+/* Base Element RAM error definitions */
+#define SOC_NS_RAM_ERR_REC_BASE		UL(0x2A4C0000)
+#define NS_RAM_ECC_CE_INT		U(87)
+#define NS_RAM_ECC_UE_INT		U(88)
+
 #define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
 						SOC_PLATFORM_PERIPH_BASE, 	\
 						SOC_PLATFORM_PERIPH_SIZE, 	\
diff --git a/plat/arm/css/sgi/ras/sgi_ras_common.c b/plat/arm/css/sgi/ras/sgi_ras_common.c
new file mode 100644
index 0000000..9789670
--- /dev/null
+++ b/plat/arm/css/sgi/ras/sgi_ras_common.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <bl31/interrupt_mgmt.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <sgi_ras.h>
+
+static struct plat_sgi_ras_config *sgi_ras_config;
+
+/*
+ * Find event map for a given interrupt number. On success, returns pointer to
+ * the event map. On error, returns NULL.
+ */
+struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
+{
+	struct sgi_ras_ev_map *map;
+	int size;
+	int i;
+
+	if (sgi_ras_config == NULL) {
+		ERROR("RAS config is NULL\n");
+		return NULL;
+	}
+
+	map = sgi_ras_config->ev_map;
+	size = sgi_ras_config->ev_map_size;
+
+	for (i = 0; i < size; i++) {
+		if (map->intr == intr_num)
+			return map;
+
+		map++;
+	}
+
+	return NULL;
+}
+
+/*
+ * Programs GIC registers and configures interrupt ID's as Group0 EL3
+ * interrupts. Current support is to register PPI and SPI interrupts.
+ */
+static void sgi_ras_intr_configure(int intr, int intr_type)
+{
+	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
+	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
+	plat_ic_clear_interrupt_pending(intr);
+
+	/* Routing mode option available only for SPI interrupts */
+	if (intr_type == SGI_RAS_INTR_TYPE_SPI) {
+		plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
+					(u_register_t)read_mpidr_el1());
+	}
+	plat_ic_enable_interrupt(intr);
+}
+
+/*
+ * Initialization function for the framework.
+ *
+ * Registers RAS config provided by the platform and then configures and
+ * enables interrupt for each registered error. On success, return 0.
+ */
+int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
+{
+	struct sgi_ras_ev_map *map;
+	int size;
+	int i;
+
+	/* Check if parameter is valid. */
+	if (config == NULL) {
+		ERROR("SGI: Failed to register RAS config\n");
+		return -1;
+	}
+
+	/*
+	 * Maintain a reference to the platform RAS config data for later
+	 * use.
+	 */
+	sgi_ras_config = config;
+
+	map = sgi_ras_config->ev_map;
+	size = sgi_ras_config->ev_map_size;
+
+	for (i = 0; i < size; i++) {
+		sgi_ras_intr_configure(map->intr, map->intr_type);
+		map++;
+	}
+
+	INFO("SGI: Platform RAS setup successful\n");
+
+	return 0;
+}
diff --git a/plat/arm/css/sgi/ras/sgi_ras_sram.c b/plat/arm/css/sgi/ras/sgi_ras_sram.c
new file mode 100644
index 0000000..b100700
--- /dev/null
+++ b/plat/arm/css/sgi/ras/sgi_ras_sram.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <plat/common/platform.h>
+#include <services/sdei.h>
+#include <services/spm_mm_svc.h>
+
+#include <platform_def.h>
+#include <sgi_ras.h>
+
+/* Base Element RAM Error Record offsets. */
+#define ERRSTATUS	U(0)
+#define ERRCODE		U(8)
+#define ERRADDR		U(12)
+
+/*
+ * Base Element RAM error information data structure communicated as part of MM
+ * Communication data payload.
+ */
+typedef struct sgi_sram_err_info {
+	uint32_t err_status;
+	uint32_t err_code;
+	uint32_t err_addr;
+} sgi_sram_err_info_t;
+
+/*
+ * MM Communicate message header GUID to indicate the payload is intended for
+ * base element RAM MM driver.
+ */
+struct efi_guid sram_ecc_event_guid = {
+	0x7312db4f, 0xd0c4, 0x4fb5,
+	{ 0x81, 0x2c, 0xb7, 0x4b, 0xc6, 0xc4, 0xa9, 0x38 }
+};
+
+/* Base element RAM RAS error interrupt handler */
+int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data)
+{
+	struct sgi_ras_ev_map *ras_map;
+	mm_communicate_header_t *header;
+	sgi_sram_err_info_t sram_info;
+	uintptr_t base_addr;
+	uint32_t clear_status, intr;
+	int ret;
+
+	cm_el1_sysregs_context_save(NON_SECURE);
+	intr = data->interrupt;
+
+	INFO("SGI: Base element RAM interrupt [%d] handler\n", intr);
+
+	/* Determine error record base address to read. */
+	base_addr = 0;
+	if (intr == NS_RAM_ECC_CE_INT || intr == NS_RAM_ECC_UE_INT) {
+		base_addr = SOC_NS_RAM_ERR_REC_BASE;
+	}
+	sram_info.err_status = mmio_read_32(base_addr + ERRSTATUS);
+	sram_info.err_code = mmio_read_32(base_addr + ERRCODE);
+	sram_info.err_addr = mmio_read_32(base_addr + ERRADDR);
+
+	/* Clear the interrupt. */
+	clear_status = mmio_read_32(base_addr + ERRSTATUS);
+	mmio_write_32((base_addr + ERRSTATUS), clear_status);
+
+	/*
+	 * Prepare the MM Communication buffer to pass the base element RAM
+	 * error information to Secure Partition.
+	 */
+	header = (void *)PLAT_SPM_BUF_BASE;
+	memset(header, 0, sizeof(*header));
+	memcpy(&header->data, &sram_info, sizeof(sram_info));
+	header->message_len = sizeof(sram_info);
+	memcpy(&header->header_guid, (void *)&sram_ecc_event_guid,
+		sizeof(struct efi_guid));
+
+	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+			plat_my_core_pos());
+
+	plat_ic_end_of_interrupt(intr);
+
+	/*
+	 * Find if this is a RAS interrupt. There must be an event against
+	 * this interrupt
+	 */
+	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	if (ras_map == NULL) {
+		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+			intr);
+		return -1;
+	}
+
+	/* Dispatch the event to the SDEI client */
+	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+	if (ret != 0) {
+		/*
+		 * sdei_dispatch_event() may return failing result in some
+		 * cases, for example kernel may not have registered a handler
+		 * or RAS event may happen early during boot. We restore the NS
+		 * context when sdei_dispatch_event() returns failing result.
+		 */
+		ERROR("SDEI dispatch failed: %d", ret);
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+	}
+
+	return ret;
+}
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 6d17bc2..358316c 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -54,10 +54,6 @@
 				${CSS_ENT_BASE}/sgi_bl31_setup.c	\
 				${CSS_ENT_BASE}/sgi_topology.c
 
-ifeq (${RAS_FFH_SUPPORT},1)
-BL31_SOURCES		+=	${CSS_ENT_BASE}/sgi_ras.c
-endif
-
 ifneq (${RESET_TO_BL31},0)
   $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
   Please set RESET_TO_BL31 to 0.")
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 9c8d163..7aa7b34 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -106,10 +106,6 @@
 {
 	arm_bl31_platform_setup();
 
-#if RAS_FFH_SUPPORT
-	sgi_ras_intr_handler_setup();
-#endif
-
 	/* Configure the warm reboot SGI for primary core */
 	css_setup_cpu_pwr_down_intr();
 
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 8d38108..8de0efe 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -87,6 +87,9 @@
 	SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
+#if RAS_FFH_SUPPORT
+	CSS_SGI_SP_CPER_BUF_MMAP,
+#endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
 	{0}
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
deleted file mode 100644
index 4f03ac4..0000000
--- a/plat/arm/css/sgi/sgi_ras.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <bl31/interrupt_mgmt.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/extensions/ras.h>
-#include <plat/arm/common/arm_spm_def.h>
-#include <plat/common/platform.h>
-#include <services/sdei.h>
-#include <services/spm_mm_svc.h>
-
-#include <sgi_ras.h>
-
-static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
-				int probe_data,
-				const struct err_handler_data *const data);
-typedef struct mm_communicate_header {
-	struct efi_guid	header_guid;
-	size_t		message_len;
-	uint8_t		data[8];
-} mm_communicate_header_t;
-
-/*
- * GUID to indicate that the MM communication message is intended for DMC-620
- * MM driver.
- */
-const struct efi_guid dmc620_ecc_event_guid = {
-	0x5ef0afd5, 0xe01a, 0x4c30,
-	{0x86, 0x19, 0x45, 0x46, 0x26, 0x91, 0x80, 0x98}
-};
-
-struct sgi_ras_ev_map sgi575_ras_map[] = {
-
-	/* DMC 0 error ECC error interrupt*/
-	{SGI_SDEI_DS_EVENT_0, 35},
-
-	/* DMC 1 error ECC error interrupt*/
-	{SGI_SDEI_DS_EVENT_1, 39},
-};
-
-#define SGI575_RAS_MAP_SIZE	ARRAY_SIZE(sgi575_ras_map)
-
-struct err_record_info sgi_err_records[] = {
-	{
-		/* DMC 0 error record info */
-		.handler = &sgi_ras_intr_handler,
-		.aux_data = (void *)0,
-	}, {
-		/* DMC 1 error record info */
-		.handler = &sgi_ras_intr_handler,
-		.aux_data = (void *)1,
-	},
-};
-
-struct ras_interrupt sgi_ras_interrupts[] = {
-	{
-		.intr_number = 35,
-		.err_record = &sgi_err_records[0],
-	}, {
-		.intr_number = 39,
-		.err_record = &sgi_err_records[1],
-	}
-};
-
-REGISTER_ERR_RECORD_INFO(sgi_err_records);
-REGISTER_RAS_INTERRUPTS(sgi_ras_interrupts);
-
-static struct sgi_ras_ev_map *plat_sgi_get_ras_ev_map(void)
-{
-	return sgi575_ras_map;
-}
-
-static int plat_sgi_get_ras_ev_map_size(void)
-{
-	return SGI575_RAS_MAP_SIZE;
-}
-
-/*
- * Find event mapping for a given interrupt number: On success, returns pointer
- * to the event mapping. On error, returns NULL.
- */
-static struct sgi_ras_ev_map *find_ras_event_map_by_intr(uint32_t intr_num)
-{
-	struct sgi_ras_ev_map *map = plat_sgi_get_ras_ev_map();
-	int i;
-	int size = plat_sgi_get_ras_ev_map_size();
-
-	for (i = 0; i < size; i++) {
-		if (map->intr == intr_num)
-			return map;
-
-		map++;
-	}
-
-	return NULL;
-}
-
-static void sgi_ras_intr_configure(int intr)
-{
-	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
-	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
-	plat_ic_clear_interrupt_pending(intr);
-	plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
-				(u_register_t)read_mpidr_el1());
-	plat_ic_enable_interrupt(intr);
-}
-
-static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
-				int probe_data,
-				const struct err_handler_data *const data)
-{
-	struct sgi_ras_ev_map *ras_map;
-	mm_communicate_header_t *header;
-	uint32_t intr;
-	int ret;
-
-	cm_el1_sysregs_context_save(NON_SECURE);
-	intr = data->interrupt;
-
-	/*
-	 * Find if this is a RAS interrupt. There must be an event against
-	 * this interrupt
-	 */
-	ras_map = find_ras_event_map_by_intr(intr);
-	assert(ras_map != NULL);
-
-	/*
-	 * Populate the MM_COMMUNICATE payload to share the
-	 * event info with StandaloneMM code. This allows us to use
-	 * MM_COMMUNICATE as a common entry mechanism into S-EL0. The
-	 * header data will be parsed in StandaloneMM to process the
-	 * corresponding event.
-	 *
-	 * TBD - Currently, the buffer allocated by SPM for communication
-	 * between EL3 and S-EL0 is being used(PLAT_SPM_BUF_BASE). But this
-	 * should happen via a dynamic mem allocation, which should be
-	 * managed by SPM -- the individual platforms then call the mem
-	 * alloc api to get memory for the payload.
-	 */
-	header = (void *) PLAT_SPM_BUF_BASE;
-	memset(header, 0, sizeof(*header));
-	memcpy(&header->data, &err_rec->aux_data, sizeof(err_rec->aux_data));
-	header->message_len = sizeof(err_rec->aux_data);
-	memcpy(&header->header_guid, (void *) &dmc620_ecc_event_guid,
-			sizeof(const struct efi_guid));
-
-	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
-		       plat_my_core_pos());
-
-	/*
-	 * Do an EOI of the RAS interrupt. This allows the
-	 * sdei event to be dispatched at the SDEI event's
-	 * priority.
-	 */
-	plat_ic_end_of_interrupt(intr);
-
-	/* Dispatch the event to the SDEI client */
-	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
-	if (ret != 0) {
-		/*
-		 * sdei_dispatch_event() may return failing result in some cases,
-		 * for example kernel may not have registered a handler or RAS event
-		 * may happen early during boot. We restore the NS context when
-		 * sdei_dispatch_event() returns failing result.
-		 */
-		ERROR("SDEI dispatch failed: %d", ret);
-		cm_el1_sysregs_context_restore(NON_SECURE);
-		cm_set_next_eret_context(NON_SECURE);
-	}
-
-	return ret;
-}
-
-int sgi_ras_intr_handler_setup(void)
-{
-	int i;
-	struct sgi_ras_ev_map *map = plat_sgi_get_ras_ev_map();
-	int size = plat_sgi_get_ras_ev_map_size();
-
-	for (i = 0; i < size; i++) {
-		sgi_ras_intr_configure(map->intr);
-		map++;
-	}
-
-	INFO("SGI: RAS Interrupt Handler successfully registered\n");
-
-	return 0;
-}
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
index 4ec69b1..be0fac1 100644
--- a/plat/common/aarch64/plat_ehf.c
+++ b/plat/common/aarch64/plat_ehf.c
@@ -24,9 +24,17 @@
 	/* Normal priority SDEI */
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
+
 #if SPM_MM
+#if RAS_FFH_SUPPORT
+#if (PLAT_SP_PRI != PLAT_RAS_PRI)
 	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
 #endif
+#else
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
+#endif
+#endif
+
 	/* Platform specific exceptions description */
 #ifdef PLAT_EHF_DESC
 	PLAT_EHF_DESC,
diff --git a/plat/qemu/common/qemu_sdei.c b/plat/qemu/common/qemu_sdei.c
new file mode 100644
index 0000000..820567e
--- /dev/null
+++ b/plat/qemu/common/qemu_sdei.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for ARM platforms */
+
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+#include <platform_def.h>
+
+/* Private event mappings */
+static sdei_ev_map_t qemu_sdei_private[] = {
+	SDEI_DEFINE_EVENT_0(PLAT_SDEI_SGI_PRIVATE),
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t qemu_sdei_shared[] = {
+};
+
+void plat_sdei_setup(void)
+{
+	INFO("SDEI platform setup\n");
+}
+
+/* Export Arm SDEI events */
+REGISTER_SDEI_MAP(qemu_sdei_private, qemu_sdei_shared);
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 98b8254..93a3ce8 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -244,8 +244,7 @@
  * interrupts.
  *****************************************************************************/
 #define PLATFORM_G1S_PROPS(grp)						\
-	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,	\
-					   grp, GIC_INTR_CFG_EDGE),	\
+	DESC_G1S_IRQ_SEC_SGI_0(grp)					\
 	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,	\
 					   grp, GIC_INTR_CFG_EDGE),	\
 	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,	\
@@ -261,7 +260,19 @@
 	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,	\
 					   grp, GIC_INTR_CFG_EDGE)
 
-#define PLATFORM_G0_PROPS(grp)
+#if SDEI_SUPPORT
+#define DESC_G0_IRQ_SEC_SGI(grp)					\
+	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \
+					   GIC_INTR_CFG_EDGE)
+#define DESC_G1S_IRQ_SEC_SGI_0(grp)
+#else
+#define DESC_G0_IRQ_SEC_SGI(grp)
+#define DESC_G1S_IRQ_SEC_SGI_0(grp)					\
+	INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp),	\
+					   GIC_INTR_CFG_EDGE),
+#endif
+
+#define PLATFORM_G0_PROPS(grp)		DESC_G0_IRQ_SEC_SGI(grp)
 
 /*
  * DT related constants
@@ -270,6 +281,14 @@
 #define PLAT_QEMU_DT_MAX_SIZE		0x100000
 
 /*
+ * Platforms macros to support SDEI
+ */
+#define PLAT_PRI_BITS			U(3)
+#define PLAT_SDEI_CRITICAL_PRI		0x60
+#define PLAT_SDEI_NORMAL_PRI		0x70
+#define PLAT_SDEI_SGI_PRIVATE		QEMU_IRQ_SEC_SGI_0
+
+/*
  * System counter
  */
 #define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 3a0e1c0..56c96a1 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -12,7 +12,7 @@
 # Qemu Cortex-A15 model does not implement the virtualization extension.
 # For this reason, we cannot set ARM_CORTEX_A15=yes and must define all
 # the ARMv7 build directives.
-MARCH32_DIRECTIVE 	:= 	-mcpu=cortex-a15
+MARCH_DIRECTIVE 	:= 	-mcpu=cortex-a15
 $(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
 $(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
 $(eval $(call add_define,ARMV7_SUPPORTS_VFP))
@@ -230,6 +230,10 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c		\
 				${QEMU_GIC_SOURCES}
 
+ifeq (${SDEI_SUPPORT}, 1)
+BL31_SOURCES		+=	plat/qemu/common/qemu_sdei.c
+endif
+
 # Pointer Authentication sources
 ifeq (${ENABLE_PAUTH}, 1)
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c	\
@@ -323,3 +327,7 @@
 ifneq (${BL33},)
 all: qemu_fw.bios qemu_fw.rom
 endif
+
+ifeq (${EL3_EXCEPTION_HANDLING},1)
+BL31_SOURCES		+=	plat/common/aarch64/plat_ehf.c
+endif
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index 37460d7..05ebec4 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -26,8 +26,10 @@
  * need version of whole 'virtual hardware platform'.
  */
 #define SIP_SVC_VERSION  SIP_FUNCTION_ID(1)
-
 #define SIP_SVC_GET_GIC  SIP_FUNCTION_ID(100)
+#define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
+
+static uint64_t gic_its_addr;
 
 void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
 uintptr_t sbsa_get_gicd(void);
@@ -45,9 +47,12 @@
 	 * QEMU gives us this DeviceTree node:
 	 *
 	 * intc {
-		reg = < 0x00 0x40060000 0x00 0x10000
-			0x00 0x40080000 0x00 0x4000000>;
-	};
+	 *	 reg = < 0x00 0x40060000 0x00 0x10000
+	 *		 0x00 0x40080000 0x00 0x4000000>;
+	 *       its {
+	 *               reg = <0x00 0x44081000 0x00 0x20000>;
+	 *       };
+	 * };
 	 */
 	node = fdt_path_offset(dtb, "/intc");
 	if (node < 0) {
@@ -74,6 +79,18 @@
 	INFO("GICR base = 0x%lx\n", gicr_base);
 
 	sbsa_set_gic_bases(gicd_base, gicr_base);
+
+	node = fdt_path_offset(dtb, "/intc/its");
+	if (node < 0) {
+		return;
+	}
+
+	err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL);
+	if (err < 0) {
+		ERROR("Failed to read GICI reg property of GIC node\n");
+		return;
+	}
+	INFO("GICI base = 0x%lx\n", gic_its_addr);
 }
 
 void read_platform_version(void *dtb)
@@ -143,6 +160,9 @@
 	case SIP_SVC_GET_GIC:
 		SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr());
 
+	case SIP_SVC_GET_GIC_ITS:
+		SMC_RET2(handle, NULL, gic_its_addr);
+
 	default:
 		ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
 		      smc_fid - SIP_FUNCTION);
diff --git a/plat/qti/msm8916/aarch32/msm8916_helpers.S b/plat/qti/msm8916/aarch32/msm8916_helpers.S
new file mode 100644
index 0000000..ea39663
--- /dev/null
+++ b/plat/qti/msm8916/aarch32/msm8916_helpers.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <msm8916_mmap.h>
+
+#define APCS_TCM_START_ADDR	0x10
+#define APCS_TCM_REDIRECT_EN_0	BIT_32(0)
+
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+	.globl	plat_panic_handler
+	.globl	plat_my_core_pos
+	.globl	plat_get_my_entrypoint
+	.globl	plat_reset_handler
+	.globl	platform_mem_init
+	.globl	msm8916_entry_point
+
+	/* -------------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Initialize the crash console.
+	 * Out: r0 - 1 on success, 0 on error
+	 * Clobber list : r0 - r4
+	 * -------------------------------------------------
+	 */
+func plat_crash_console_init
+	ldr	r1, =BLSP_UART_BASE
+	mov	r0, #1
+	b	console_uartdm_core_init
+endfunc plat_crash_console_init
+
+	/* -------------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Print a character on the crash console.
+	 * In : r0 - character to be printed
+	 * Out: r0 - printed character on success
+	 * Clobber list : r1, r2
+	 * -------------------------------------------------
+	 */
+func plat_crash_console_putc
+	ldr	r1, =BLSP_UART_BASE
+	b	console_uartdm_core_putc
+endfunc plat_crash_console_putc
+
+	/* -------------------------------------------------
+	 * void plat_crash_console_flush(void)
+	 * Force a write of all buffered data that has not
+	 * been output.
+	 * Clobber list : r1, r2
+	 * -------------------------------------------------
+	 */
+func plat_crash_console_flush
+	ldr	r1, =BLSP_UART_BASE
+	b	console_uartdm_core_flush
+endfunc plat_crash_console_flush
+
+	/* -------------------------------------------------
+	 * void plat_panic_handler(void) __dead
+	 * Called when an unrecoverable error occurs.
+	 * -------------------------------------------------
+	 */
+func plat_panic_handler
+	/* Try to shutdown/reset */
+	ldr	r0, =MPM_PS_HOLD
+	mov	r1, #0
+	str	r1, [r0]
+1:	b	1b
+endfunc plat_panic_handler
+
+	/* -------------------------------------------------
+	 * unsigned int plat_my_core_pos(void)
+	 * Out: r0 - index of the calling CPU
+	 * -------------------------------------------------
+	 */
+func plat_my_core_pos
+	/* There is just a single cluster so this is very simple */
+	ldcopr	r0, MPIDR
+	and	r0, r0, #MPIDR_CPU_MASK
+	bx	lr
+endfunc plat_my_core_pos
+
+	/* -------------------------------------------------
+	 * uintptr_t plat_get_my_entrypoint(void)
+	 * Distinguish cold and warm boot and return warm boot
+	 * entry address if available.
+	 * Out: r0 - warm boot entry point or 0 on cold boot
+	 * -------------------------------------------------
+	 */
+func plat_get_my_entrypoint
+	ldr	r0, =msm8916_entry_point
+	ldr	r0, [r0]
+	cmp	r0, #0
+	bxne	lr
+
+	/*
+	 * Cold boot: Disable TCM redirect to L2 cache as early as
+	 * possible to avoid crashes when making use of the cache.
+	 */
+	ldr	r1, =APCS_CFG
+	ldr	r2, [r1, #APCS_TCM_START_ADDR]
+	and	r2, r2, #~APCS_TCM_REDIRECT_EN_0
+	str	r2, [r1, #APCS_TCM_START_ADDR]
+	bx	lr
+endfunc plat_get_my_entrypoint
+
+	/* -------------------------------------------------
+	 * void platform_mem_init(void)
+	 * Performs additional memory initialization early
+	 * in the boot process.
+	 * -------------------------------------------------
+	 */
+func platform_mem_init
+	/* Nothing to do here, all memory is already initialized */
+	bx	lr
+endfunc platform_mem_init
+
+	.data
+	.align	3
+
+	/* -------------------------------------------------
+	 * Warm boot entry point for CPU. Set by PSCI code.
+	 * -------------------------------------------------
+	 */
+msm8916_entry_point:
+	.word	0
diff --git a/plat/qti/msm8916/aarch32/uartdm_console.S b/plat/qti/msm8916/aarch32/uartdm_console.S
new file mode 100644
index 0000000..a19776a
--- /dev/null
+++ b/plat/qti/msm8916/aarch32/uartdm_console.S
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * Based on aarch32/skeleton_console.S:
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <console_macros.S>
+
+/* UART DM registers */
+#define UART_DM_DMEN		0x03c		/* DMA / data packing */
+#define UART_DM_SR		0x0a4		/* status register */
+#define UART_DM_CR		0x0a8		/* command register */
+#define UART_DM_TF		0x100		/* transmit FIFO */
+
+#define UART_DM_DMEN_TX_SC	BIT_32(4)	/* TX single character mode */
+
+#define UART_DM_SR_TXRDY	BIT_32(2)	/* TX FIFO has space */
+#define UART_DM_SR_TXEMT	BIT_32(3)	/* TX FIFO is empty */
+
+#define UART_DM_CR_RESET_RX	(U(0x01) << 4)	/* reset receiver */
+#define UART_DM_CR_RESET_TX	(U(0x02) << 4)	/* reset transmitter */
+#define UART_DM_CR_TX_ENABLE	BIT_32(2)	/* enable transmitter */
+
+	.globl	console_uartdm_register
+	.globl	console_uartdm_core_init
+	.globl	console_uartdm_putc
+	.globl	console_uartdm_core_putc
+	.globl	console_uartdm_flush
+	.globl	console_uartdm_core_flush
+
+	/* -----------------------------------------------------------
+	 * int console_uartdm_register(console_t *console,
+	 * 	uintptr_t base_addr)
+	 * Function to initialize and register the console. The caller
+	 * needs to pass an empty console_t structure in which *MUST*
+	 * be allocated in persistent memory (e.g. a global or static
+	 * local variable, *NOT* on the stack).
+	 * In : r0 - pointer to empty console_t structure
+	 *      r1 - base address
+	 * Out: r0 - 1 on success, 0 on error
+	 * Clobber list : r0 - r7
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_register
+	str	r1, [r0, #CONSOLE_T_BASE]
+	mov	r7, lr
+	bl	console_uartdm_core_init
+	mov	lr, r7
+
+	/* Register the new console */
+	finish_console_register uartdm putc=1, flush=1
+endfunc console_uartdm_register
+
+	/* -----------------------------------------------------------
+	 * void console_uartdm_core_init(unused, uintptr_t base_addr)
+	 * Function to initialize the console.
+	 * In : r0 - unused
+	 *      r1 - base address
+	 * Out: void
+	 * Clobber list : r1, r2, r3
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_core_init
+	/*
+	 * Try to flush remaining characters from the TX FIFO before resetting
+	 * the transmitter. Unfortunately there is no good way to check if
+	 * the transmitter is actually enabled (and will finish eventually),
+	 * so use a timeout to avoid looping forever.
+	 */
+	mov	r2, #65536
+1:
+	ldr	r3, [r1, #UART_DM_SR]
+	tst	r3, #UART_DM_SR_TXEMT
+	bne	2f
+	subs	r2, r2, #1
+	bne	1b
+	/* Timeout */
+
+2:	/* Reset receiver */
+	mov	r3, #UART_DM_CR_RESET_RX
+	str	r3, [r1, #UART_DM_CR]
+
+	/* Reset transmitter */
+	mov	r3, #UART_DM_CR_RESET_TX
+	str	r3, [r1, #UART_DM_CR]
+
+	/*
+	 * Disable BAM/DMA modes but enable single-character mode for TX.
+	 * The single character mode allows simplifying the putc implementation
+	 * since characters can be written directly to the FIFO instead of
+	 * having to initiate a new transfer and waiting for its completion.
+	 */
+	mov	r3, #UART_DM_DMEN_TX_SC
+	str	r3, [r1, #UART_DM_DMEN]
+
+	/* Enable transmitter */
+	mov	r3, #UART_DM_CR_TX_ENABLE
+	str	r3, [r1, #UART_DM_CR]
+
+	bx	lr
+endfunc console_uartdm_core_init
+
+	/* -----------------------------------------------------------
+	 * int console_uartdm_putc(int c, console_t *console)
+	 * Function to output a character over the console.
+	 * In : r0 - character to be printed
+	 *      r1 - pointer to console_t struct
+	 * Out: r0 - printed character on success, < 0 on error.
+	 * Clobber list : r0, r1, r2
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_putc
+	ldr	r1, [r1, #CONSOLE_T_BASE]
+	b	console_uartdm_core_putc
+endfunc console_uartdm_putc
+
+	/* -----------------------------------------------------------
+	 * int console_uartdm_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console.
+	 * In : r0 - character to be printed
+	 *      r1 - base address
+	 * Out: r0 - printed character on success, < 0 on error.
+	 * Clobber list : r2
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_core_putc
+	cmp	r0, #'\n'
+	bne	2f
+
+1:	/* Loop until TX FIFO has space */
+	ldr	r2, [r1, #UART_DM_SR]
+	tst	r2, #UART_DM_SR_TXRDY
+	beq	1b
+
+	/* Prepend '\r' to '\n' */
+	mov	r2, #'\r'
+	str	r2, [r1, #UART_DM_TF]
+
+2:	/* Loop until TX FIFO has space */
+	ldr	r2, [r1, #UART_DM_SR]
+	tst	r2, #UART_DM_SR_TXRDY
+	beq	2b
+
+	/* Write character to FIFO */
+	str	r0, [r1, #UART_DM_TF]
+	bx	lr
+endfunc console_uartdm_core_putc
+
+	/* -----------------------------------------------------------
+	 * void console_uartdm_flush(console_t *console)
+	 * Function to force a write of all buffered data
+	 * that has not been output.
+	 * In : r0 - pointer to console_t struct
+	 * Out: void
+	 * Clobber list : r0, r1, r2, r3, r4, r5
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_flush
+	ldr	r1, [r0, #CONSOLE_T_BASE]
+	b	console_uartdm_core_flush
+endfunc console_uartdm_flush
+
+	/* -----------------------------------------------------------
+	 * void console_uartdm_core_flush(unused, uintptr_t base_addr)
+	 * Function to force a write of all buffered data
+	 * that has not been output.
+	 * In : r0 - unused
+	 *      r1 - base address
+	 * Out: void
+	 * Clobber list : r2
+	 * -----------------------------------------------------------
+	 */
+func console_uartdm_core_flush
+1:	/* Loop until TX FIFO is empty */
+	ldr	r2, [r1, #UART_DM_SR]
+	tst	r2, #UART_DM_SR_TXEMT
+	beq	1b
+	bx	lr
+endfunc console_uartdm_core_flush
diff --git a/plat/qti/msm8916/aarch64/msm8916_helpers.S b/plat/qti/msm8916/aarch64/msm8916_helpers.S
index 528c5a4..bccc5e5 100644
--- a/plat/qti/msm8916/aarch64/msm8916_helpers.S
+++ b/plat/qti/msm8916/aarch64/msm8916_helpers.S
@@ -30,7 +30,7 @@
 	 * -------------------------------------------------
 	 */
 func plat_crash_console_init
-	mov	x1, #BLSP_UART2_BASE
+	mov_imm	x1, BLSP_UART_BASE
 	mov	x0, #1
 	b	console_uartdm_core_init
 endfunc plat_crash_console_init
@@ -44,7 +44,7 @@
 	 * -------------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov	x1, #BLSP_UART2_BASE
+	mov_imm	x1, BLSP_UART_BASE
 	b	console_uartdm_core_putc
 endfunc plat_crash_console_putc
 
@@ -56,7 +56,7 @@
 	 * -------------------------------------------------
 	 */
 func plat_crash_console_flush
-	mov	x1, #BLSP_UART2_BASE
+	mov_imm	x1, BLSP_UART_BASE
 	b	console_uartdm_core_flush
 endfunc plat_crash_console_flush
 
@@ -93,45 +93,44 @@
 	 */
 func plat_get_my_entrypoint
 	ldr	x0, msm8916_entry_point
+	cbz	x0, 1f
+	ret
+1:
+	/*
+	 * Cold boot: Disable TCM redirect to L2 cache as early as
+	 * possible to avoid crashes when making use of the cache.
+	 */
+	mov_imm	x1, APCS_CFG
+	ldr	w2, [x1, #APCS_TCM_START_ADDR]
+	and	w2, w2, #~APCS_TCM_REDIRECT_EN_0
+	str	w2, [x1, #APCS_TCM_START_ADDR]
+
+	/*
+	 * After reset the CPU always starts executing at the fixed reset
+	 * address (0x0), which does not match the link address of BL31.
+	 * The "boot remapper" redirects all memory accesses to the real
+	 * physical address in DRAM.
+	 *
+	 * For warm boots, this is already handled by loading the real
+	 * entry point address above.
+	 *
+	 * For cold boots, check if the CPU is using the boot remapper,
+	 * i.e. if bl31_entrypoint appears to be at the reset address (0x0).
+	 */
+	adr	x1, bl31_entrypoint
+	cbnz	x1, 2f
+
+	/*
+	 * Add the real BL31_BASE offset to the return address in the link
+	 * register so the CPU will continue at the real address after return.
+	 */
+	mov_imm	x1, BL31_BASE
+	add	lr, lr, x1
+2:
 	ret
 endfunc plat_get_my_entrypoint
 
 	/* -------------------------------------------------
-	 * void plat_reset_handler(void)
-	 * Perform additional initialization after reset.
-	 * Clobber list : x0 - x18, x30
-	 * -------------------------------------------------
-	 */
-func plat_reset_handler
-	/*
-	 * Check if the CPU is running at the correct address.
-	 * During cold boot the CPU enters here at the wrong address
-	 * using the "boot remapper". (It remaps the BL31_BASE to
-	 * the CPU reset address 0x0).
-	 */
-	mov	x0, #BL31_BASE
-	adr	x1, bl31_entrypoint
-	cmp	x0, x1
-	b.ne	_remapped_cold_boot
-	/* Already running at correct address, just return directly */
-	ret
-
-_remapped_cold_boot:
-	/*
-	 * The previous boot stage seems to use the L2 cache as TCM.
-	 * Disable the TCM redirect before enabling caches to avoid
-	 * strange crashes.
-	 */
-	mov	x2, #APCS_CFG
-	ldr	w3, [x2, #APCS_TCM_START_ADDR]
-	and	w3, w3, #~APCS_TCM_REDIRECT_EN_0
-	str	w3, [x2, #APCS_TCM_START_ADDR]
-
-	/* Enter BL31 again at the real address */
-	br	x0
-endfunc plat_reset_handler
-
-	/* -------------------------------------------------
 	 * void platform_mem_init(void)
 	 * Performs additional memory initialization early
 	 * in the boot process.
diff --git a/plat/qti/msm8916/include/msm8916_mmap.h b/plat/qti/msm8916/include/msm8916_mmap.h
index d201536..35e3b86 100644
--- a/plat/qti/msm8916/include/msm8916_mmap.h
+++ b/plat/qti/msm8916/include/msm8916_mmap.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,8 +23,9 @@
 #define APPS_SMMU_BASE		(PCNOC_BASE + 0x1e00000)
 #define APPS_SMMU_QCOM		(APPS_SMMU_BASE + 0xf0000)
 
-#define BLSP_UART1_BASE		(PCNOC_BASE + 0x78af000)
-#define BLSP_UART2_BASE		(PCNOC_BASE + 0x78b0000)
+#define BLSP1_BASE		(PCNOC_BASE + 0x7880000)
+#define BLSP1_UART_BASE(n)	(BLSP1_BASE + 0x2f000 + (((n) - 1) * 0x1000))
+#define BLSP_UART_BASE		BLSP1_UART_BASE(QTI_UART_NUM)
 
 #define APCS_QGIC2_BASE		(APCS_BASE + 0x00000)
 #define APCS_QGIC2_GICD		(APCS_QGIC2_BASE + 0x0000)
diff --git a/plat/qti/msm8916/include/platform_def.h b/plat/qti/msm8916/include/platform_def.h
index 6d5ff2b..f6ba1cc 100644
--- a/plat/qti/msm8916/include/platform_def.h
+++ b/plat/qti/msm8916/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <plat/common/common_def.h>
 
+#ifdef __aarch64__
 /*
  * There is at least 1 MiB available for BL31. However, at the moment the
  * "msm8916_entry_point" variable in the data section is read through the
@@ -18,6 +19,8 @@
  */
 #define BL31_LIMIT			(BL31_BASE + SZ_128K)
 #define BL31_PROGBITS_LIMIT		(BL31_BASE + SZ_64K)
+#endif
+#define BL32_LIMIT			(BL32_BASE + SZ_128K)
 
 #define CACHE_WRITEBACK_GRANULE		U(64)
 #define PLATFORM_STACK_SIZE		SZ_4K
@@ -44,8 +47,9 @@
 #define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
 
-/* Timer frequency */
+/* Timer */
 #define PLAT_SYSCNT_FREQ		19200000
+#define IRQ_SEC_PHY_TIMER		(16 + 2)	/* PPI #2 */
 
 /*
  * The Qualcomm QGIC2 implementation seems to have PIDR0-4 and PIDR4-7
@@ -54,4 +58,9 @@
  */
 #define GICD_PIDR2_GICV2		U(0xFD8)
 
+/* TSP */
+#define TSP_IRQ_SEC_PHY_TIMER		IRQ_SEC_PHY_TIMER
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/msm8916/msm8916_bl31_setup.c b/plat/qti/msm8916/msm8916_bl31_setup.c
index 8cba5c5..449be7f 100644
--- a/plat/qti/msm8916/msm8916_bl31_setup.c
+++ b/plat/qti/msm8916/msm8916_bl31_setup.c
@@ -8,25 +8,10 @@
 
 #include <arch.h>
 #include <common/debug.h>
-#include <drivers/console.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_mmu_helpers.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
-#include "msm8916_gicv2.h"
-#include <msm8916_mmap.h>
-#include <platform_def.h>
-#include <uartdm_console.h>
-
-static const mmap_region_t msm8916_mmap[] = {
-	MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
-	MAP_REGION_FLAT(APCS_BASE, APCS_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
-	{},
-};
+#include "msm8916_config.h"
+#include "msm8916_setup.h"
 
 static struct {
 	entry_point_info_t bl32;
@@ -44,160 +29,23 @@
 	.bl33.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
 };
 
-static console_t console;
-
-unsigned int plat_get_syscnt_freq2(void)
-{
-	return PLAT_SYSCNT_FREQ;
-}
-
-#define CLK_ENABLE			BIT_32(0)
-#define CLK_OFF				BIT_32(31)
-
-#define GPIO_BLSP_UART2_TX		4
-#define GPIO_BLSP_UART2_RX		5
-#define GPIO_CFG_FUNC_BLSP_UART2	(U(0x2) << 2)
-#define GPIO_CFG_DRV_STRENGTH_16MA	(U(0x7) << 6)
-
-#define GCC_BLSP1_AHB_CBCR		(GCC_BASE + 0x01008)
-#define GCC_BLSP1_UART2_APPS_CBCR	(GCC_BASE + 0x0302c)
-#define GCC_APCS_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x45004)
-#define BLSP1_AHB_CLK_ENA		BIT_32(10)
-
-/*
- * The previous boot stage seems to disable most of the UART setup before exit
- * so it must be enabled here again before the UART console can be used.
- */
-static void msm8916_enable_blsp_uart2(void)
-{
-	/* Route GPIOs to BLSP UART2 */
-	mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_TX),
-		      GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
-	mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_RX),
-		      GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
-
-	/* Enable AHB clock */
-	mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
-	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
-		;
-
-	/* Enable BLSP UART2 clock */
-	mmio_setbits_32(GCC_BLSP1_UART2_APPS_CBCR, CLK_ENABLE);
-	while (mmio_read_32(GCC_BLSP1_UART2_APPS_CBCR) & CLK_OFF)
-		;
-}
-
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	/* Initialize the debug console as early as possible */
-	msm8916_enable_blsp_uart2();
-	console_uartdm_register(&console, BLSP_UART2_BASE);
+	msm8916_early_platform_setup();
 }
 
 void bl31_plat_arch_setup(void)
 {
-	mmap_add_region(BL31_BASE, BL31_BASE, BL31_END - BL31_BASE,
-			MT_RW_DATA | MT_SECURE);
-	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
-			BL_CODE_END - BL_CODE_BASE,
-			MT_CODE | MT_SECURE);
-	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
-			BL_RO_DATA_END - BL_RO_DATA_BASE,
-			MT_RO_DATA | MT_SECURE);
-	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
-			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
-			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
-
-	mmap_add(msm8916_mmap);
-	init_xlat_tables();
+	msm8916_plat_arch_setup(BL31_BASE, BL31_END - BL31_BASE);
 	enable_mmu_el3(0);
 }
 
-static void msm8916_configure_timer(void)
-{
-	/* Set timer frequency */
-	mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, plat_get_syscnt_freq2());
-
-	/* Make all timer frames available to non-secure world */
-	mmio_write_32(APCS_QTMR + CNTNSAR, GENMASK_32(7, 0));
-}
-
-/*
- * The APCS register regions always start with a SECURE register that should
- * be cleared to 0 to only allow secure access. Since BL31 handles most of
- * the CPU power management, most of them can be cleared to secure access only.
- */
-#define APCS_GLB_SECURE_STS_NS		BIT_32(0)
-#define APCS_GLB_SECURE_PWR_NS		BIT_32(1)
-#define APCS_BOOT_START_ADDR_SEC	(APCS_CFG + 0x04)
-#define REMAP_EN			BIT_32(0)
-#define APCS_AA64NAA32_REG		(APCS_CFG + 0x0c)
-
-static void msm8916_configure_cpu_pm(void)
-{
-	unsigned int cpu;
-
-	/* Disallow non-secure access to boot remapper / TCM registers */
-	mmio_write_32(APCS_CFG, 0);
-
-	/*
-	 * Disallow non-secure access to power management registers.
-	 * However, allow STS and PWR since those also seem to control access
-	 * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
-	 * bits are not set, CPU frequency control fails in the non-secure world.
-	 */
-	mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
-
-	/* Disallow non-secure access to L2 SAW2 */
-	mmio_write_32(APCS_L2_SAW2, 0);
-
-	/* Disallow non-secure access to CPU ACS and SAW2 */
-	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
-		mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
-		mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
-	}
-
-	/* Make sure all further warm boots end up in BL31 and aarch64 state */
-	CASSERT((BL31_BASE & 0xffff) == 0, assert_bl31_base_64k_aligned);
-	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
-	mmio_write_32(APCS_AA64NAA32_REG, 1);
-}
-
-/*
- * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
- * which allows routing context bank interrupts to one of 3 interrupt numbers
- * ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number
- * by default to avoid special setup on the non-secure side.
- */
-#define GCC_SMMU_CFG_CBCR			(GCC_BASE + 0x12038)
-#define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x4500c)
-#define SMMU_CFG_CLK_ENA			BIT_32(12)
-#define APPS_SMMU_INTR_SEL_NS			(APPS_SMMU_QCOM + 0x2000)
-#define APPS_SMMU_INTR_SEL_NS_EN_ALL		U(0xffffffff)
-
-static void msm8916_configure_smmu(void)
-{
-	/* Enable SMMU configuration clock to enable register access */
-	mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
-	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
-		;
-
-	/* Route all context bank interrupts to non-secure interrupt */
-	mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
-
-	/* Disable configuration clock again */
-	mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
-}
-
 void bl31_platform_setup(void)
 {
 	INFO("BL31: Platform setup start\n");
-	generic_delay_timer_init();
-	msm8916_configure_timer();
-	msm8916_gicv2_init();
-	msm8916_configure_cpu_pm();
-	msm8916_configure_smmu();
+	msm8916_platform_setup();
+	msm8916_configure();
 	INFO("BL31: Platform setup done\n");
 }
 
diff --git a/plat/qti/msm8916/msm8916_config.c b/plat/qti/msm8916/msm8916_config.c
new file mode 100644
index 0000000..350ed5c
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_config.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <lib/mmio.h>
+
+#include "msm8916_config.h"
+#include "msm8916_gicv2.h"
+#include <msm8916_mmap.h>
+#include <platform_def.h>
+
+static void msm8916_configure_timer(void)
+{
+	/* Set timer frequency */
+	mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, PLAT_SYSCNT_FREQ);
+
+	/* Make all timer frames available to non-secure world */
+	mmio_write_32(APCS_QTMR + CNTNSAR, GENMASK_32(7, 0));
+}
+
+/*
+ * The APCS register regions always start with a SECURE register that should
+ * be cleared to 0 to only allow secure access. Since BL31 handles most of
+ * the CPU power management, most of them can be cleared to secure access only.
+ */
+#define APCS_GLB_SECURE_STS_NS		BIT_32(0)
+#define APCS_GLB_SECURE_PWR_NS		BIT_32(1)
+#define APCS_BOOT_START_ADDR_SEC	(APCS_CFG + 0x04)
+#define REMAP_EN			BIT_32(0)
+#define APCS_AA64NAA32_REG		(APCS_CFG + 0x0c)
+
+static void msm8916_configure_cpu_pm(void)
+{
+	unsigned int cpu;
+
+	/* Disallow non-secure access to boot remapper / TCM registers */
+	mmio_write_32(APCS_CFG, 0);
+
+	/*
+	 * Disallow non-secure access to power management registers.
+	 * However, allow STS and PWR since those also seem to control access
+	 * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
+	 * bits are not set, CPU frequency control fails in the non-secure world.
+	 */
+	mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
+
+	/* Disallow non-secure access to L2 SAW2 */
+	mmio_write_32(APCS_L2_SAW2, 0);
+
+	/* Disallow non-secure access to CPU ACS and SAW2 */
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+		mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
+		mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
+	}
+
+#ifdef __aarch64__
+	/* Make sure all further warm boots end up in BL31 and aarch64 state */
+	CASSERT((BL31_BASE & 0xffff) == 0, assert_bl31_base_64k_aligned);
+	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL31_BASE | REMAP_EN);
+	mmio_write_32(APCS_AA64NAA32_REG, 1);
+#else
+	/* Make sure all further warm boots end up in BL32 */
+	CASSERT((BL32_BASE & 0xffff) == 0, assert_bl32_base_64k_aligned);
+	mmio_write_32(APCS_BOOT_START_ADDR_SEC, BL32_BASE | REMAP_EN);
+#endif
+}
+
+/*
+ * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
+ * which allows routing context bank interrupts to one of 3 interrupt numbers
+ * ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number
+ * by default to avoid special setup on the non-secure side.
+ */
+#define CLK_OFF					BIT_32(31)
+#define GCC_SMMU_CFG_CBCR			(GCC_BASE + 0x12038)
+#define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x4500c)
+#define SMMU_CFG_CLK_ENA			BIT_32(12)
+#define APPS_SMMU_INTR_SEL_NS			(APPS_SMMU_QCOM + 0x2000)
+#define APPS_SMMU_INTR_SEL_NS_EN_ALL		U(0xffffffff)
+
+static void msm8916_configure_smmu(void)
+{
+	/* Enable SMMU configuration clock to enable register access */
+	mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
+	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
+		;
+
+	/* Route all context bank interrupts to non-secure interrupt */
+	mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
+
+	/* Disable configuration clock again */
+	mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
+}
+
+void msm8916_configure(void)
+{
+	msm8916_gicv2_configure();
+	msm8916_configure_timer();
+	msm8916_configure_cpu_pm();
+	msm8916_configure_smmu();
+}
diff --git a/plat/qti/msm8916/msm8916_config.h b/plat/qti/msm8916/msm8916_config.h
new file mode 100644
index 0000000..992625b
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_config.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MSM8916_CONFIG_H
+#define MSM8916_CONFIG_H
+
+void msm8916_configure(void);
+
+#endif /* MSM8916_CONFIG_H */
diff --git a/plat/qti/msm8916/msm8916_gicv2.c b/plat/qti/msm8916/msm8916_gicv2.c
index 25a6628..82cecf2 100644
--- a/plat/qti/msm8916/msm8916_gicv2.c
+++ b/plat/qti/msm8916/msm8916_gicv2.c
@@ -10,6 +10,7 @@
 
 #include "msm8916_gicv2.h"
 #include <msm8916_mmap.h>
+#include <platform_def.h>
 
 #define IRQ_SEC_SGI_0		8
 #define IRQ_SEC_SGI_1		9
@@ -20,8 +21,6 @@
 #define IRQ_SEC_SGI_6		14
 #define IRQ_SEC_SGI_7		15
 
-#define IRQ_SEC_PHY_TIMER	(16 + 2)	/* PPI #2 */
-
 static const interrupt_prop_t msm8916_interrupt_props[] = {
 	INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
 		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
@@ -53,6 +52,10 @@
 void msm8916_gicv2_init(void)
 {
 	gicv2_driver_init(&msm8916_gic_data);
+}
+
+void msm8916_gicv2_configure(void)
+{
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
diff --git a/plat/qti/msm8916/msm8916_gicv2.h b/plat/qti/msm8916/msm8916_gicv2.h
index 99db0d3..919e294 100644
--- a/plat/qti/msm8916/msm8916_gicv2.h
+++ b/plat/qti/msm8916/msm8916_gicv2.h
@@ -8,5 +8,6 @@
 #define MSM8916_GICV2_H
 
 void msm8916_gicv2_init(void);
+void msm8916_gicv2_configure(void);
 
 #endif /* MSM8916_GICV2_H */
diff --git a/plat/qti/msm8916/msm8916_setup.c b/plat/qti/msm8916/msm8916_setup.c
new file mode 100644
index 0000000..26039a9
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_setup.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "msm8916_gicv2.h"
+#include <msm8916_mmap.h>
+#include "msm8916_setup.h"
+#include <uartdm_console.h>
+
+static const mmap_region_t msm8916_mmap[] = {
+	MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
+	MAP_REGION_FLAT(APCS_BASE, APCS_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
+	{},
+};
+
+static console_t console;
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return PLAT_SYSCNT_FREQ;
+}
+
+#define GPIO_CFG_FUNC(n)		((n) << 2)
+#define GPIO_CFG_DRV_STRENGTH_MA(ma)	(((ma) / 2 - 1) << 6)
+
+#define CLK_ENABLE			BIT_32(0)
+#define CLK_OFF				BIT_32(31)
+#define GCC_BLSP1_AHB_CBCR		(GCC_BASE + 0x01008)
+#define GCC_BLSP1_UART_APPS_CBCR(n)	(GCC_BASE + \
+	(((n) == 2) ? (0x0302c) : (0x0203c + (((n) - 1) * 0x1000))))
+#define GCC_APCS_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x45004)
+#define BLSP1_AHB_CLK_ENA		BIT_32(10)
+
+struct uartdm_gpios {
+	unsigned int tx, rx, func;
+};
+
+static const struct uartdm_gpios uartdm_gpio_map[] = {
+	{0, 1, 0x2}, {4, 5, 0x2},
+};
+
+/*
+ * The previous boot stage seems to disable most of the UART setup before exit
+ * so it must be enabled here again before the UART console can be used.
+ */
+static void msm8916_enable_blsp_uart(void)
+{
+	const struct uartdm_gpios *gpios = &uartdm_gpio_map[QTI_UART_NUM - 1];
+
+	CASSERT(QTI_UART_NUM > 0 && QTI_UART_NUM <= ARRAY_SIZE(uartdm_gpio_map),
+		assert_qti_blsp_uart_valid);
+
+	/* Route GPIOs to BLSP UART */
+	mmio_write_32(TLMM_GPIO_CFG(gpios->tx), GPIO_CFG_FUNC(gpios->func) |
+		      GPIO_CFG_DRV_STRENGTH_MA(8));
+	mmio_write_32(TLMM_GPIO_CFG(gpios->rx), GPIO_CFG_FUNC(gpios->func) |
+		      GPIO_CFG_DRV_STRENGTH_MA(8));
+
+	/* Enable AHB clock */
+	mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
+	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
+		;
+
+	/* Enable BLSP UART clock */
+	mmio_setbits_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM), CLK_ENABLE);
+	while (mmio_read_32(GCC_BLSP1_UART_APPS_CBCR(QTI_UART_NUM)) & CLK_OFF)
+		;
+}
+
+void msm8916_early_platform_setup(void)
+{
+	/* Initialize the debug console as early as possible */
+	msm8916_enable_blsp_uart();
+	console_uartdm_register(&console, BLSP_UART_BASE);
+
+	if (QTI_RUNTIME_UART) {
+		/* Mark UART as runtime usable */
+		console_set_scope(&console, CONSOLE_FLAG_BOOT |
+				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
+}
+
+void msm8916_plat_arch_setup(uintptr_t base, size_t size)
+{
+	mmap_add_region(base, base, size, MT_RW_DATA | MT_SECURE);
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
+			BL_RO_DATA_END - BL_RO_DATA_BASE,
+			MT_RO_DATA | MT_SECURE);
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
+
+	mmap_add(msm8916_mmap);
+	init_xlat_tables();
+}
+
+void msm8916_platform_setup(void)
+{
+	generic_delay_timer_init();
+	msm8916_gicv2_init();
+}
diff --git a/plat/qti/msm8916/msm8916_setup.h b/plat/qti/msm8916/msm8916_setup.h
new file mode 100644
index 0000000..d2de943
--- /dev/null
+++ b/plat/qti/msm8916/msm8916_setup.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MSM8916_SETUP_H
+#define MSM8916_SETUP_H
+
+void msm8916_early_platform_setup(void);
+void msm8916_plat_arch_setup(uintptr_t base, size_t size);
+void msm8916_platform_setup(void);
+
+#endif /* MSM8916_SETUP_H */
diff --git a/plat/qti/msm8916/platform.mk b/plat/qti/msm8916/platform.mk
index 107296b..7e698fb 100644
--- a/plat/qti/msm8916/platform.mk
+++ b/plat/qti/msm8916/platform.mk
@@ -7,35 +7,37 @@
 include drivers/arm/gic/v2/gicv2.mk
 include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_BL_COMMON_SOURCES	:= ${XLAT_TABLES_LIB_SRCS}
+PLAT_BL_COMMON_SOURCES	:=	${GICV2_SOURCES}				\
+				${XLAT_TABLES_LIB_SRCS}				\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				plat/common/plat_gicv2.c			\
+				plat/qti/msm8916/msm8916_gicv2.c		\
+				plat/qti/msm8916/msm8916_setup.c		\
+				plat/qti/msm8916/${ARCH}/msm8916_helpers.S	\
+				plat/qti/msm8916/${ARCH}/uartdm_console.S
 
-PLAT_INCLUDES	:=	-Iinclude/plat/arm/common/${ARCH}		\
-			-Iplat/qti/msm8916/include
+MSM8916_PM_SOURCES	:=	lib/cpus/${ARCH}/cortex_a53.S			\
+				plat/common/plat_psci_common.c			\
+				plat/qti/msm8916/msm8916_config.c		\
+				plat/qti/msm8916/msm8916_cpu_boot.c		\
+				plat/qti/msm8916/msm8916_pm.c			\
+				plat/qti/msm8916/msm8916_topology.c
 
-BL31_SOURCES	+=	${GICV2_SOURCES}				\
-			drivers/delay_timer/delay_timer.c		\
-			drivers/delay_timer/generic_delay_timer.c	\
-			lib/cpus/${ARCH}/cortex_a53.S			\
-			plat/common/plat_gicv2.c			\
-			plat/common/plat_psci_common.c			\
-			plat/qti/msm8916/msm8916_bl31_setup.c		\
-			plat/qti/msm8916/msm8916_cpu_boot.c		\
-			plat/qti/msm8916/msm8916_gicv2.c		\
-			plat/qti/msm8916/msm8916_pm.c			\
-			plat/qti/msm8916/msm8916_topology.c		\
-			plat/qti/msm8916/${ARCH}/msm8916_helpers.S	\
-			plat/qti/msm8916/${ARCH}/uartdm_console.S
+BL31_SOURCES		+=	${MSM8916_PM_SOURCES}				\
+				plat/qti/msm8916/msm8916_bl31_setup.c
+
+PLAT_INCLUDES		:=	-Iplat/qti/msm8916/include
+
+ifeq (${ARCH},aarch64)
+# arm_macros.S exists only on aarch64 currently
+PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
+endif
 
 # Only BL31 is supported at the moment and is entered on a single CPU
 RESET_TO_BL31			:= 1
 COLD_BOOT_SINGLE_CPU		:= 1
 
-# Build config flags
-# ------------------
-BL31_BASE			?= 0x86500000
-BL32_BASE			?= 0x86000000
-PRELOADED_BL33_BASE		?= 0x8f600000
-
 # Have different sections for code and rodata
 SEPARATE_CODE_AND_RODATA	:= 1
 
@@ -61,5 +63,27 @@
 ERRATA_A53_855873		:= 0	# Workaround works only for >= r0p3
 ERRATA_A53_1530924		:= 1
 
+# Build config flags
+# ------------------
+BL31_BASE			?= 0x86500000
+PRELOADED_BL33_BASE		?= 0x8f600000
+
+ifeq (${ARCH},aarch64)
+BL32_BASE			?= BL31_LIMIT
 $(eval $(call add_define,BL31_BASE))
+else
+# There is no BL31 on aarch32, so reuse its location for BL32
+BL32_BASE			?= $(BL31_BASE)
+endif
 $(eval $(call add_define,BL32_BASE))
+
+# UART number to use for TF-A output during early boot
+QTI_UART_NUM			?= 2
+$(eval $(call assert_numeric,QTI_UART_NUM))
+$(eval $(call add_define,QTI_UART_NUM))
+
+# Set to 1 on the command line to keep using UART after early boot.
+# Requires reserving the UART and related clocks inside the normal world.
+QTI_RUNTIME_UART		?= 0
+$(eval $(call assert_boolean,QTI_RUNTIME_UART))
+$(eval $(call add_define,QTI_RUNTIME_UART))
diff --git a/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
new file mode 100644
index 0000000..78ab0c7
--- /dev/null
+++ b/plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <platform_sp_min.h>
+
+#include "../msm8916_config.h"
+#include "../msm8916_setup.h"
+
+static struct {
+	entry_point_info_t bl33;
+} image_ep_info = {
+	/* BL33 entry point */
+	SET_STATIC_PARAM_HEAD(bl33, PARAM_EP, VERSION_1,
+			      entry_point_info_t, NON_SECURE),
+	.bl33.pc = PRELOADED_BL33_BASE,
+	.bl33.spsr = SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, SPSR_E_LITTLE,
+				 DISABLE_ALL_EXCEPTIONS),
+};
+
+void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	msm8916_early_platform_setup();
+}
+
+void sp_min_plat_arch_setup(void)
+{
+	msm8916_plat_arch_setup(BL32_BASE, BL32_END - BL32_BASE);
+	enable_mmu_svc_mon(0);
+}
+
+void sp_min_platform_setup(void)
+{
+	INFO("SP_MIN: Platform setup start\n");
+	msm8916_platform_setup();
+	msm8916_configure();
+	INFO("SP_MIN: Platform setup done\n");
+}
+
+entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
+{
+	return &image_ep_info.bl33;
+}
diff --git a/plat/qti/msm8916/sp_min/sp_min-msm8916.mk b/plat/qti/msm8916/sp_min/sp_min-msm8916.mk
new file mode 100644
index 0000000..be07f94
--- /dev/null
+++ b/plat/qti/msm8916/sp_min/sp_min-msm8916.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2022-2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES	+=	${MSM8916_PM_SOURCES}				\
+			plat/common/${ARCH}/platform_mp_stack.S		\
+			plat/qti/msm8916/sp_min/msm8916_sp_min_setup.c
+
+override RESET_TO_SP_MIN := 1
diff --git a/plat/qti/msm8916/tsp/msm8916_tsp_setup.c b/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
new file mode 100644
index 0000000..218af57
--- /dev/null
+++ b/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Stephan Gerhold <stephan@gerhold.net>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <platform_tsp.h>
+
+#include "../msm8916_setup.h"
+#include <platform_def.h>
+
+void tsp_early_platform_setup(void)
+{
+	msm8916_early_platform_setup();
+}
+
+void tsp_plat_arch_setup(void)
+{
+	msm8916_plat_arch_setup(BL32_BASE, BL32_END - BL32_BASE);
+	enable_mmu_el1(0);
+}
+
+void tsp_platform_setup(void)
+{
+	INFO("TSP: Platform setup start\n");
+	msm8916_platform_setup();
+	INFO("TSP: Platform setup done\n");
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+}
diff --git a/plat/qti/msm8916/tsp/tsp-msm8916.mk b/plat/qti/msm8916/tsp/tsp-msm8916.mk
new file mode 100644
index 0000000..0d50058
--- /dev/null
+++ b/plat/qti/msm8916/tsp/tsp-msm8916.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2023, Stephan Gerhold <stephan@gerhold.net>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES	+=	plat/common/${ARCH}/platform_mp_stack.S		\
+			plat/qti/msm8916/tsp/msm8916_tsp_setup.c
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index e8a9627..3fcb62f 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -68,7 +68,7 @@
 					uint32_t flag);
 enum pm_ret_status pm_get_chipid(uint32_t *value);
 
-/**
+/*
  * Assigning of argument values into array elements.
  */
 #define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) {	\
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index af7ca87..c0308ab 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,10 +34,11 @@
 				 TZ_VERSION_MINOR)
 
 /**
- * pm_ipi - struct for capturing IPI-channel specific info
- * @local_ipi_id	Local IPI agent ID
- * @remote_ipi_id	Remote IPI Agent ID
- * @buffer_base	base address for payload buffer
+ * struct pm_ipi - struct for capturing IPI-channel specific info.
+ * @local_ipi_id: Local IPI agent ID.
+ * @remote_ipi_id: Remote IPI Agent ID.
+ * @buffer_base: base address for payload buffer.
+ *
  */
 struct pm_ipi {
 	const uint32_t local_ipi_id;
@@ -45,11 +47,12 @@
 };
 
 /**
- * pm_proc - struct for capturing processor related info
- * @node_id	node-ID of the processor
- * @pwrdn_mask	cpu-specific mask to be used for power control register
- * @ipi		pointer to IPI channel structure
- *		(in APU all processors share one IPI channel)
+ * struct pm_proc - struct for capturing processor related info.
+ * @node_id: node-ID of the processor.
+ * @pwrdn_mask: cpu-specific mask to be used for power control register.
+ * @ipi: pointer to IPI channel structure.
+ *       (in APU all processors share one IPI channel)
+ *
  */
 struct pm_proc {
 	const uint32_t node_id;
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index c5587fd..b80cf45 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -59,7 +59,9 @@
  * Enum definitions
  ********************************************************************/
 
-//ioctl id
+/*
+ * ioctl id
+ */
 enum {
 	IOCTL_GET_RPU_OPER_MODE = 0,
 	IOCTL_SET_RPU_OPER_MODE = 1,
@@ -98,16 +100,18 @@
 };
 
 /**
- * @PM_PLL_PARAM_DIV2:		Enable for divide by 2 function inside the PLL
- * @PM_PLL_PARAM_FBDIV:		Feedback divisor integer portion for the PLL
- * @PM_PLL_PARAM_DATA:		Feedback divisor fractional portion for the PLL
- * @PM_PLL_PARAM_PRE_SRC:	Clock source for PLL input
- * @PM_PLL_PARAM_POST_SRC:	Clock source for PLL Bypass mode
- * @PM_PLL_PARAM_LOCK_DLY:	Lock circuit config settings for lock windowsize
- * @PM_PLL_PARAM_LOCK_CNT:	Lock circuit counter setting
- * @PM_PLL_PARAM_LFHF:		PLL loop filter high frequency capacitor control
- * @PM_PLL_PARAM_CP:		PLL charge pump control
- * @PM_PLL_PARAM_RES:		PLL loop filter resistor control
+ * enum pm_pll_param - enum represents the parameters for a phase-locked loop.
+ * @PM_PLL_PARAM_DIV2: Enable for divide by 2 function inside the PLL.
+ * @PM_PLL_PARAM_FBDIV: Feedback divisor integer portion for the PLL.
+ * @PM_PLL_PARAM_DATA: Feedback divisor fractional portion for the PLL.
+ * @PM_PLL_PARAM_PRE_SRC: Clock source for PLL input.
+ * @PM_PLL_PARAM_POST_SRC: Clock source for PLL Bypass mode.
+ * @PM_PLL_PARAM_LOCK_DLY: Lock circuit config settings for lock windowsize.
+ * @PM_PLL_PARAM_LOCK_CNT: Lock circuit counter setting.
+ * @PM_PLL_PARAM_LFHF: PLL loop filter high frequency capacitor control.
+ * @PM_PLL_PARAM_CP: PLL charge pump control.
+ * @PM_PLL_PARAM_RES: PLL loop filter resistor control.
+ * @PM_PLL_PARAM_MAX: Represents the maximum parameter value for the PLL
  */
 enum pm_pll_param {
 	PM_PLL_PARAM_DIV2,
@@ -205,7 +209,7 @@
 	PM_OPCHAR_TYPE_LATENCY,
 };
 
-/**
+/*
  * Subsystem IDs
  */
 typedef enum {
@@ -223,20 +227,24 @@
 
 /* TODO: move pm_ret_status from device specific location to common location */
 /**
- * @PM_RET_SUCCESS:		success
- * @PM_RET_ERROR_ARGS:		illegal arguments provided (deprecated)
- * @PM_RET_ERROR_NOTSUPPORTED:	feature not supported  (deprecated)
- * @PM_RET_ERROR_NOFEATURE:	feature is not available
- * @PM_RET_ERROR_INVALID_CRC:	invalid crc in IPI communication
- * @PM_RET_ERROR_NOT_ENABLED:   feature is not enabled
- * @PM_RET_ERROR_INTERNAL:	internal error
- * @PM_RET_ERROR_CONFLICT:	conflict
- * @PM_RET_ERROR_ACCESS:	access rights violation
- * @PM_RET_ERROR_INVALID_NODE:	invalid node
- * @PM_RET_ERROR_DOUBLE_REQ:	duplicate request for same node
- * @PM_RET_ERROR_ABORT_SUSPEND:	suspend procedure has been aborted
- * @PM_RET_ERROR_TIMEOUT:	timeout in communication with PMU
- * @PM_RET_ERROR_NODE_USED:	node is already in use
+ * enum pm_ret_status - enum represents the return status codes for a PM
+ *                      operation.
+ * @PM_RET_SUCCESS: success.
+ * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated).
+ * @PM_RET_ERROR_NOTSUPPORTED: feature not supported  (deprecated).
+ * @PM_RET_ERROR_NOFEATURE: feature is not available.
+ * @PM_RET_ERROR_INVALID_CRC: invalid crc in IPI communication.
+ * @PM_RET_ERROR_NOT_ENABLED: feature is not enabled.
+ * @PM_RET_ERROR_INTERNAL: internal error.
+ * @PM_RET_ERROR_CONFLICT: conflict.
+ * @PM_RET_ERROR_ACCESS: access rights violation.
+ * @PM_RET_ERROR_INVALID_NODE: invalid node.
+ * @PM_RET_ERROR_DOUBLE_REQ: duplicate request for same node.
+ * @PM_RET_ERROR_ABORT_SUSPEND: suspend procedure has been aborted.
+ * @PM_RET_ERROR_TIMEOUT: timeout in communication with PMU.
+ * @PM_RET_ERROR_NODE_USED: node is already in use.
+ * @PM_RET_ERROR_NO_FEATURE: indicates that the requested feature is not
+ *                           supported.
  */
 enum pm_ret_status {
 	PM_RET_SUCCESS,
@@ -256,7 +264,7 @@
 	PM_RET_ERROR_NO_FEATURE = 2008
 };
 
-/**
+/*
  * Qids
  */
 enum pm_query_id {
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 9c169ab..399d283 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,10 +46,9 @@
 static uint32_t ipi_total;
 
 /**
- * ipi_config_init() - Initialize IPI configuration data
- *
- * @ipi_config_table  - IPI configuration table
- * @ipi_total - Total number of IPI available
+ * ipi_config_table_init() - Initialize IPI configuration data.
+ * @ipi_config_table: IPI configuration table.
+ * @total_ipi: Total number of IPI available.
  *
  */
 void ipi_config_table_init(const struct ipi_config *ipi_config_table,
@@ -58,12 +58,13 @@
 	ipi_total = total_ipi;
 }
 
-/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
+/**
+ * is_ipi_mb_within_range() - verify if IPI mailbox is within range.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * Return: - 1 if within range, 0 if not.
  *
- * return - 1 if within range, 0 if not
  */
 static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
 {
@@ -77,13 +78,13 @@
 }
 
 /**
- * ipi_mb_validate() - validate IPI mailbox access
+ * ipi_mb_validate() - validate IPI mailbox access.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
+ * @is_secure: indicate if the requester is from secure software.
  *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- * @is_secure - indicate if the requester is from secure software
+ * Return: 0 success, negative value for errors.
  *
- * return - 0 success, negative value for errors
  */
 int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
 {
@@ -104,9 +105,8 @@
 
 /**
  * ipi_mb_open() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  */
 void ipi_mb_open(uint32_t local, uint32_t remote)
@@ -119,9 +119,8 @@
 
 /**
  * ipi_mb_release() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  */
 void ipi_mb_release(uint32_t local, uint32_t remote)
@@ -131,13 +130,13 @@
 }
 
 /**
- * ipi_mb_enquire_status() - Enquire IPI mailbox status
+ * ipi_mb_enquire_status() - Enquire IPI mailbox status.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
- * @local  - local IPI ID
- * @remote - remote IPI ID
+ * Return: 0 idle, positive value for pending sending or receiving,
+ *         negative value for errors.
  *
- * return - 0 idle, positive value for pending sending or receiving,
- *          negative value for errors
  */
 int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
 {
@@ -156,11 +155,11 @@
 	return ret;
 }
 
-/* ipi_mb_notify() - Trigger IPI mailbox notification
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- * @is_blocking - if to trigger the notification in blocking mode or not.
+/**
+ * ipi_mb_notify() - Trigger IPI mailbox notification.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
+ * @is_blocking: if to trigger the notification in blocking mode or not.
  *
  * It sets the remote bit in the IPI agent trigger register.
  *
@@ -179,10 +178,10 @@
 	}
 }
 
-/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
+/**
+ * ipi_mb_ack() - Ack IPI mailbox notification from the other end.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  * It will clear the remote bit in the isr register.
  *
@@ -193,10 +192,10 @@
 		      IPI_BIT_MASK(remote));
 }
 
-/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
+/**
+ * ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  * It will mask the remote bit in the idr register.
  *
@@ -207,10 +206,10 @@
 		      IPI_BIT_MASK(remote));
 }
 
-/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
+/**
+ * ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt.
+ * @local: local IPI ID.
+ * @remote: remote IPI ID.
  *
  * It will mask the remote bit in the idr register.
  *
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 330288c..6c060d5 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,21 +47,25 @@
 #define UNSIGNED32_MASK			0xFFFFFFFFU /* 32bit mask */
 
 /**
- * ipi_smc_handler() - SMC handler for IPI SMC calls
+ * ipi_smc_handler() - SMC handler for IPI SMC calls.
+ * @smc_fid: Function identifier.
+ * @x1: Arguments.
+ * @x2: Arguments.
+ * @x3: Arguments.
+ * @x4: Arguments.
+ * @cookie: Unused.
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
- * @smc_fid - Function identifier
- * @x1 - x4 - Arguments
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
- *
- * @return  - Unused
+ * Return: Unused.
  *
  * Determines that smc_fid is valid and supported PM SMC Function ID from the
  * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * the unknown SMC Function ID.
  *
  * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * function with rt_svc_handle signature.
+ *
  */
 uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 			 uint64_t x3, uint64_t x4, const void *cookie,
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 007c045..d034e00 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -55,11 +55,12 @@
 #define FSBL_FLAGS_A53_3		3U
 
 /**
- * @partition: Pointer to partition struct
+ * get_fsbl_cpu() - Get the target CPU for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target CPU for @partition.
+ * Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or
+ *         FSBL_FLAGS_A53_3.
  *
- * Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or FSBL_FLAGS_A53_3
  */
 static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
 {
@@ -69,11 +70,11 @@
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_fsbl_el() - Get the target exception level for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target exception level for @partition.
+ * Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3.
  *
- * Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3
  */
 static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
 {
@@ -83,11 +84,11 @@
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_fsbl_ss() - Get the target security state for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target security state for @partition.
+ * Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE.
  *
- * Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE
  */
 static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
 {
@@ -97,11 +98,11 @@
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_fsbl_endian() - Get the target endianness for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target endianness for @partition.
+ * Return: SPSR_E_LITTLE or SPSR_E_BIG.
  *
- * Return: SPSR_E_LITTLE or SPSR_E_BIG
  */
 static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
 {
@@ -117,11 +118,11 @@
 }
 
 /**
- * @partition: Pointer to partition struct
+ * get_fsbl_estate() - Get the target execution state for partition.
+ * @partition: Pointer to partition struct.
  *
- * Get the target execution state for @partition.
+ * Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64.
  *
- * Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64
  */
 static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
 {
@@ -131,16 +132,17 @@
 }
 
 /**
- * Populates the bl32 and bl33 image info structures
- * @bl32:	BL32 image info structure
- * @bl33:	BL33 image info structure
- * tfa_handoff_addr:  TF-A handoff address
+ * fsbl_tfa_handover() - Populates the bl32 and bl33 image info structures.
+ * @bl32: BL32 image info structure.
+ * @bl33: BL33 image info structure.
+ * @tfa_handoff_addr: TF-A handoff address.
  *
  * Process the handoff parameters from the FSBL and populate the BL32 and BL33
  * image info structures accordingly.
  *
  * Return: Return the status of the handoff. The value will be from the
  *         fsbl_handoff enum.
+ *
  */
 enum fsbl_handoff fsbl_tfa_handover(entry_point_info_t *bl32,
 					entry_point_info_t *bl33,
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index dcdd2dc..ffc39bb 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -28,9 +28,10 @@
 static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
 
 /**
- * pm_get_shutdown_scope() - Get the currently set shutdown scope
+ * pm_get_shutdown_scope() - Get the currently set shutdown scope.
  *
- * @return	Shutdown scope value
+ * Return: Shutdown scope value.
+ *
  */
 uint32_t pm_get_shutdown_scope(void)
 {
@@ -42,7 +43,8 @@
 /**
  * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as
  *                                wake sources in the XilPM.
- * @node_id:    Node id of processor
+ * @node_id: Node id of processor.
+ *
  */
 void pm_client_set_wakeup_sources(uint32_t node_id)
 {
@@ -91,13 +93,19 @@
 }
 
 /**
- * pm_handle_eemi_call() - PM call for processor to send eemi payload
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- * @x0 to x5	Arguments received per SMC64 standard
- * @result	Payload received from firmware
+ * pm_handle_eemi_call() - PM call for processor to send eemi payload.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ * @x0: Arguments received per SMC64 standard.
+ * @x1: Arguments received per SMC64 standard.
+ * @x2: Arguments received per SMC64 standard.
+ * @x3: Arguments received per SMC64 standard.
+ * @x4: Arguments received per SMC64 standard.
+ * @x5: Arguments received per SMC64 standard.
+ * @result: Payload received from firmware.
  *
- * @return	 PM_RET_SUCCESS on success or error code
+ * Return: PM_RET_SUCCESS on success or error code.
+ *
  */
 enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
 				       uint32_t x2, uint32_t x3, uint32_t x4,
@@ -119,17 +127,18 @@
 
 /**
  * pm_self_suspend() - PM call for processor to suspend itself
- * @nid		Node id of the processor or subsystem
- * @latency	Requested maximum wakeup latency (not supported)
- * @state	Requested state
- * @address	Resume address
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * @nid: Node id of the processor or subsystem.
+ * @latency: Requested maximum wakeup latency (not supported).
+ * @state: Requested state.
+ * @address: Resume address.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This is a blocking call, it will return only once PMU has responded.
  * On a wakeup, resume address will be automatically set by PMU.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_self_suspend(uint32_t nid,
 				   uint32_t latency,
@@ -160,15 +169,16 @@
 
 /**
  * pm_abort_suspend() - PM call to announce that a prior suspend request
- *			is to be aborted.
- * @reason	Reason for the abort
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ *                      is to be aborted.
+ * @reason: Reason for the abort.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * Calling PU expects the PMU to abort the initiated suspend procedure.
  * This is a non-blocking call without any acknowledge.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag)
 {
@@ -188,15 +198,16 @@
 
 /**
  * pm_req_suspend() - PM call to request for another PU or subsystem to
- *		      be suspended gracefully.
- * @target	Node id of the targeted PU or subsystem
- * @ack		Flag to specify whether acknowledge is requested
- * @latency	Requested wakeup latency (not supported)
- * @state	Requested state (not supported)
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ *                    be suspended gracefully.
+ * @target: Node id of the targeted PU or subsystem.
+ * @ack: Flag to specify whether acknowledge is requested.
+ * @latency: Requested wakeup latency (not supported)
+ * @state: Requested state (not supported).
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
 				  uint32_t latency, uint32_t state,
@@ -216,21 +227,22 @@
 
 /**
  * pm_req_wakeup() - PM call for processor to wake up selected processor
- *		     or subsystem
- * @target	Device ID of the processor or subsystem to wake up
- * @set_address	Resume address presence indicator
- *		1 - resume address specified, 0 - otherwise
- * @address	Resume address
- * @ack		Flag to specify whether acknowledge requested
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ *                   or subsystem.
+ * @target: Device ID of the processor or subsystem to wake up.
+ * @set_address: Resume address presence indicator.
+ *               1 - resume address specified, 0 - otherwise.
+ * @address: Resume address.
+ * @ack: Flag to specify whether acknowledge requested.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API function is either used to power up another APU core for SMP
  * (by PSCI) or to power up an entirely different PU or subsystem, such
  * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
  * automatically set by PMC.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
 				 uintptr_t address, uint8_t ack, uint32_t flag)
@@ -245,15 +257,17 @@
 }
 
 /**
- * pm_get_callbackdata() - Read from IPI response buffer
- * @data - array of PAYLOAD_ARG_CNT elements
- * @flag - 0 - Call from secure source
- *	   1 - Call from non-secure source
- * @ack - 0 - Do not ack IPI after reading payload
- *        1 - Ack IPI after reading payload
+ * pm_get_callbackdata() - Read from IPI response buffer.
+ * @data: array of PAYLOAD_ARG_CNT elements.
+ * @count: Number of values to return.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ * @ack: 0 - Do not ack IPI after reading payload.
+ *       1 - Ack IPI after reading payload.
  *
  * Read value from ipi buffer response buffer.
- * @return	Returns status, either success or error
+ * Return: Returns status, either success or error.
+ *
  */
 enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
 {
@@ -273,19 +287,19 @@
 }
 
 /**
- * pm_pll_set_param() - Set PLL parameter
+ * pm_pll_set_param() - Set PLL parameter.
+ * @clk_id: PLL clock ID.
+ * @param: PLL parameter ID.
+ * @value: Value to set for PLL parameter.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API is deprecated and maintained here for backward compatibility.
  * New use of this API should be avoided for versal platform.
  * This API and its use cases will be removed for versal platform.
  *
- * @clk_id	PLL clock ID
- * @param	PLL parameter ID
- * @value	Value to set for PLL parameter
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
 				    uint32_t value, uint32_t flag)
@@ -300,19 +314,19 @@
 }
 
 /**
- * pm_pll_get_param() - Get PLL parameter value
+ * pm_pll_get_param() - Get PLL parameter value.
+ * @clk_id: PLL clock ID.
+ * @param: PLL parameter ID.
+ * @value: Buffer to store PLL parameter value.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API is deprecated and maintained here for backward compatibility.
  * New use of this API should be avoided for versal platform.
  * This API and its use cases will be removed for versal platform.
  *
- * @clk_id	PLL clock ID
- * @param	PLL parameter ID
- * @value:	Buffer to store PLL parameter value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
 				    uint32_t *value, uint32_t flag)
@@ -327,18 +341,18 @@
 }
 
 /**
- * pm_pll_set_mode() - Set PLL mode
+ * pm_pll_set_mode() - Set PLL mode.
+ * @clk_id: PLL clock ID.
+ * @mode: PLL mode.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API is deprecated and maintained here for backward compatibility.
  * New use of this API should be avoided for versal platform.
  * This API and its use cases will be removed for versal platform.
  *
- * @clk_id	PLL clock ID
- * @mode	PLL mode
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
 				   uint32_t flag)
@@ -353,18 +367,18 @@
 }
 
 /**
- * pm_pll_get_mode() - Get PLL mode
+ * pm_pll_get_mode() - Get PLL mode.
+ * @clk_id: PLL clock ID.
+ * @mode: Buffer to store PLL mode.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API is deprecated and maintained here for backward compatibility.
  * New use of this API should be avoided for versal platform.
  * This API and its use cases will be removed for versal platform.
  *
- * @clk_id	PLL clock ID
- * @mode:	Buffer to store PLL mode
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * Return: Returns status, either success or error+reason.
  *
- * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
 				   uint32_t flag)
@@ -380,13 +394,14 @@
 
 /**
  * pm_force_powerdown() - PM call to request for another PU or subsystem to
- *			  be powered down forcefully
- * @target	Device ID of the PU node to be forced powered down.
- * @ack		Flag to specify whether acknowledge is requested
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ *                        be powered down forcefully.
+ * @target: Device ID of the PU node to be forced powered down.
+ * @ack: Flag to specify whether acknowledge is requested
+ * @flag: 0 - Call from secure source
+ *        1 - Call from non-secure source
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
 				      uint32_t flag)
@@ -405,13 +420,14 @@
 }
 
 /**
- * pm_system_shutdown() - PM call to request a system shutdown or restart
- * @type	Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
- * @subtype	Scope: 0=APU-subsystem, 1=PS, 2=system
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * pm_system_shutdown() - PM call to request a system shutdown or restart.
+ * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
+ * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
 				      uint32_t flag)
@@ -432,22 +448,22 @@
 }
 
 /**
- * pm_query_data() -  PM API for querying firmware data
+ * pm_query_data() -  PM API for querying firmware data.
+ * @qid: The type of data to query.
+ * @arg1: Argument 1 to requested query data call.
+ * @arg2: Argument 2 to requested query data call.
+ * @arg3: Argument 3 to requested query data call.
+ * @data: Returned output data.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API is deprecated and maintained here for backward compatibility.
  * New use of this API should be avoided for versal platform.
  * This API and its use cases will be removed for versal platform.
  *
- * @qid	The type of data to query
- * @arg1	Argument 1 to requested query data call
- * @arg2	Argument 2 to requested query data call
- * @arg3	Argument 3 to requested query data call
- * @data	Returned output data
- * @flag 0 - Call from secure source
- *	1 - Call from non-secure source
+ * Return: 0 if success else non-zero error code of type
+ *         enum pm_ret_status.
  *
- * @retur - 0 if success else non-zero error code of type
- * enum pm_ret_status
  */
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag)
@@ -481,25 +497,25 @@
 	return ret;
 }
 /**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs
+ * pm_api_ioctl() -  PM IOCTL API for device control and configs.
+ * @device_id: Device ID.
+ * @ioctl_id: ID of the requested IOCTL.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @arg3: Argument 3 to requested IOCTL call.
+ * @value: Returned output value.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
  * This API is deprecated and maintained here for backward compatibility.
  * New use of this API should be avoided for versal platform.
  * This API and its use cases will be removed for versal platform.
  *
- * @device_id	Device ID
- * @ioctl_id	ID of the requested IOCTL
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @arg3	Argument 3 to requested IOCTL call
- * @value	Returned output value
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- *
  * This function calls IOCTL to firmware for device control and configuration.
  *
- * @return	Returns status, either 0 on success or non-zero error code
- * of type enum pm_ret_status
+ * Return: Returns status, either 0 on success or non-zero error code
+ *         of type enum pm_ret_status.
+ *
  */
 enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
 				uint32_t arg1, uint32_t arg2, uint32_t arg3,
@@ -536,14 +552,16 @@
 }
 
 /**
- * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
- * @target	Device id of the targeted PU or subsystem
- * @wkup_node	Device id of the wakeup peripheral
- * @enable	Enable or disable the specified peripheral as wake source
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * pm_set_wakeup_source() - PM call to specify the wakeup source while
+ *                          suspended.
+ * @target: Device id of the targeted PU or subsystem
+ * @wkup_device: Device id of the wakeup peripheral
+ * @enable: Enable or disable the specified peripheral as wake source
+ * @flag: 0 - Call from secure source
+ *        1 - Call from non-secure source
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
 					uint8_t enable, uint32_t flag)
@@ -556,15 +574,16 @@
 }
 
 /**
- * pm_feature_check() - Returns the supported API version if supported
- * @api_id	API ID to check
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
- * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
- *		words Returned supported API version and bitmasks
- *		for IOCTL and QUERY ID
+ * pm_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
+ * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
+ *               words Returned supported API version and bitmasks
+ *               for IOCTL and QUERY ID
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
 				    uint32_t flag)
@@ -601,17 +620,17 @@
 }
 
 /**
- * pm_load_pdi() - Load the PDI
+ * pm_load_pdi() - Load the PDI. This function provides support to load
+ *                 PDI from linux.
  *
- * This function provides support to load PDI from linux
+ * @src: Source device of pdi(DDR, OCM, SD etc).
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
- * src:        Source device of pdi(DDR, OCM, SD etc)
- * address_low: lower 32-bit Linear memory space address
- * address_high: higher 32-bit Linear memory space address
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ * Return: Returns status, either success or error+reason.
  *
- * @return      Returns status, either success or error+reason
  */
 enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
 			       uint32_t address_high, uint32_t flag)
@@ -626,15 +645,16 @@
 
 /**
  * pm_register_notifier() - PM call to register a subsystem to be notified
- * 			    about the device event
- * @device_id	Device ID for the Node to which the event is related
- * @event	Event in question
- * @wake	Wake subsystem upon capturing the event if value 1
- * @enable	Enable the registration for value 1, disable for value 0
- * @flag	0 - Call from secure source
- *		1 - Call from non-secure source
+ *                          about the device event.
+ * @device_id: Device ID for the Node to which the event is related.
+ * @event: Event in question.
+ * @wake: Wake subsystem upon capturing the event if value 1.
+ * @enable: Enable the registration for value 1, disable for value 0.
+ * @flag: 0 - Call from secure source.
+ *        1 - Call from non-secure source.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
 					uint32_t wake, uint32_t enable,
@@ -650,11 +670,11 @@
 }
 
 /**
- * pm_get_chipid() - Read silicon ID registers
- * @value:	Buffer for two 32bit words.
+ * pm_get_chipid() - Read silicon ID registers.
+ * @value: Buffer for two 32bit words.
  *
- * @return:	Returns status, either success or error+reason and,
- *		optionally, @value.
+ * Return: Returns status, either success or error+reason and,
+ *         optionally, @value.
  */
 enum pm_ret_status pm_get_chipid(uint32_t *value)
 {
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 2c3cb1b..5e59559 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,14 +52,14 @@
 
 /**
  * pm_ipi_init() - Initialize IPI peripheral for communication with
- *		   remote processor
+ *                 remote processor.
+ * @proc: Pointer to the processor who is initiating request.
  *
- * @proc	Pointer to the processor who is initiating request
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
- * Called from pm_setup initialization function
+ * Called from pm_setup initialization function.
  */
 void pm_ipi_init(const struct pm_proc *proc)
 {
@@ -67,14 +67,16 @@
 }
 
 /**
- * pm_ipi_send_common() - Sends IPI request to the remote processor
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
+ * pm_ipi_send_common() - Sends IPI request to the remote processor.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
+ * @is_blocking: if to trigger the notification in blocking mode or not.
  *
  * Send an IPI request to the power controller. Caller needs to hold
  * the 'pm_secure_lock' lock.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
 					     uint32_t payload[PAYLOAD_ARG_CNT],
@@ -103,13 +105,14 @@
 
 /**
  * pm_ipi_send_non_blocking() - Sends IPI request to the remote processor
- *			        without blocking notification
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
+ *                              without blocking notification.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
  *
  * Send an IPI request to the power controller.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
 					    uint32_t payload[PAYLOAD_ARG_CNT])
@@ -126,13 +129,14 @@
 }
 
 /**
- * pm_ipi_send() - Sends IPI request to the remote processor
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
+ * pm_ipi_send() - Sends IPI request to the remote processor.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
  *
  * Send an IPI request to the power controller.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
 			       uint32_t payload[PAYLOAD_ARG_CNT])
@@ -151,12 +155,13 @@
 
 /**
  * pm_ipi_buff_read() - Reads IPI response after remote processor has handled
- *			interrupt
- * @proc	Pointer to the processor who is waiting and reading response
- * @value	Used to return value from IPI buffer element (optional)
- * @count	Number of values to return in @value
+ *                      interrupt.
+ * @proc: Pointer to the processor who is waiting and reading response.
+ * @value: Used to return value from IPI buffer element (optional).
+ * @count: Number of values to return in @value.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
 					   uint32_t *value, size_t count)
@@ -208,13 +213,15 @@
 
 /**
  * pm_ipi_buff_read_callb() - Callback function that reads value from
- *			      ipi response buffer
- * @value	Used to return value from IPI buffer element
- * @count	Number of values to return in @value
+ *                            ipi response buffer.
+ * @value: Used to return value from IPI buffer element.
+ * @count: Number of values to return in @value.
  *
  * This callback function fills requested data in @value from ipi response
  * buffer.
- * @return 	Returns status, either success or error
+ *
+ * Return: Returns status, either success or error.
+ *
  */
 enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count)
 {
@@ -258,16 +265,17 @@
 }
 
 /**
- * pm_ipi_send_sync() - Sends IPI request to the remote processor
- * @proc	Pointer to the processor who is initiating request
- * @payload	API id and call arguments to be written in IPI buffer
- * @value	Used to return value from IPI buffer element (optional)
- * @count	Number of values to return in @value
+ * pm_ipi_send_sync() - Sends IPI request to the remote processor.
+ * @proc: Pointer to the processor who is initiating request.
+ * @payload: API id and call arguments to be written in IPI buffer.
+ * @value: Used to return value from IPI buffer element (optional).
+ * @count: Number of values to return in @value.
  *
  * Send an IPI request to the power controller and wait for it to be handled.
  *
- * @return	Returns status, either success or error+reason and, optionally,
- *		@value
+ * Return: Returns status, either success or error+reason and, optionally,
+ *         @value.
+ *
  */
 enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
 				    uint32_t payload[PAYLOAD_ARG_CNT],
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 1bd2192..bae369e 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -84,13 +84,13 @@
 }
 
 /**
- * pm_register_sgi() - PM register the IPI interrupt
+ * pm_register_sgi() - PM register the IPI interrupt.
+ * @sgi_num: SGI number to be used for communication.
+ * @reset: Reset to invalid SGI when reset=1.
  *
- * @sgi -  SGI number to be used for communication.
- * @reset -  Reset to invalid SGI when reset=1.
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
  * Update the SGI number to be used.
  *
@@ -115,17 +115,18 @@
 }
 
 /**
- * pm_setup() - PM service setup
+ * pm_setup() - PM service setup.
  *
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
  * Initialization functions for Versal power management for
  * communicaton with PMC.
  *
  * Called from sip_svc_setup initialization function with the
  * rt_svc_init signature.
+ *
  */
 int32_t pm_setup(void)
 {
@@ -152,14 +153,19 @@
 }
 
 /**
- * eemi_for_compatibility() - EEMI calls handler for deprecated calls
+ * eemi_for_compatibility() - EEMI calls handler for deprecated calls.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
- * @return - If EEMI API found then, uintptr_t type address, else 0
+ * Return: If EEMI API found then, uintptr_t type address, else 0.
  *
  * Some EEMI API's use case needs to be changed in Linux driver, so they
  * can take advantage of common EEMI handler in TF-A. As of now the old
  * implementation of these APIs are required to maintain backward compatibility
  * until their use case in linux driver changes.
+ *
  */
 static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
 					void *handle, uint32_t security_flag)
@@ -214,14 +220,21 @@
 }
 
 /**
- * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI
+ * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * These EEMI APIs performs CPU specific power management tasks.
  * These EEMI APIs are invoked either from PSCI or from debugfs in kernel.
  * These calls require CPU specific processing before sending IPI request to
  * Platform Management Controller. For example enable/disable CPU specific
  * interrupts. This requires separate handler for these calls and may not be
- * handled using common eemi handler
+ * handled using common eemi handler.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0.
+ *
  */
 static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
 					   void *handle, uint32_t security_flag)
@@ -258,11 +271,18 @@
 }
 
 /**
- * TF_A_specific_handler() - SMC handler for TF-A specific functionality
+ * TF_A_specific_handler() - SMC handler for TF-A specific functionality.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * These EEMI calls performs functionality that does not require
  * IPI transaction. The handler ends in TF-A and returns requested data to
  * kernel from TF-A.
+ *
+ * Return: If TF-A specific API found then, uintptr_t type address, else 0
+ *
  */
 static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
 				       void *handle, uint32_t security_flag)
@@ -306,7 +326,11 @@
 }
 
 /**
- * eemi_handler() - Prepare EEMI payload and perform IPI transaction
+ * eemi_handler() - Prepare EEMI payload and perform IPI transaction.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * EEMI - Embedded Energy Management Interface is Xilinx proprietary protocol
  * to allow communication between power management controller and different
@@ -314,6 +338,9 @@
  *
  * This handler prepares EEMI protocol payload received from kernel and performs
  * IPI transaction.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0
+ *
  */
 static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
 			      void *handle, uint32_t security_flag)
@@ -345,20 +372,24 @@
 
 /**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - SMC64 Arguments from kernel
- *	      x3 (upper 32-bits) and x4 are Unused
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
+ * @smc_fid: Function Identifier.
+ * @x1: SMC64 Arguments from kernel.
+ * @x2: SMC64 Arguments from kernel.
+ * @x3: SMC64 Arguments from kernel (upper 32-bits).
+ * @x4: Unused.
+ * @cookie: Unused.
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
- * @return  - Unused
+ * Return: Unused.
  *
  * Determines that smc_fid is valid and supported PM SMC Function ID from the
  * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * the unknown SMC Function ID.
  *
  * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * function with rt_svc_handle signature.
+ *
  */
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
diff --git a/plat/xilinx/common/versal.c b/plat/xilinx/common/versal.c
index 019c862..3ea022c 100644
--- a/plat/xilinx/common/versal.c
+++ b/plat/xilinx/common/versal.c
@@ -15,12 +15,12 @@
 
 /**
  * plat_is_smccc_feature_available() - This function checks whether SMCCC
- *					feature is availabile for platform.
- * @fid: SMCCC function id
+ *                                     feature is availabile for platform.
+ * @fid: SMCCC function id.
  *
- * Return:
- * * SMC_ARCH_CALL_SUCCESS		- if SMCCC feature is available
- * * SMC_ARCH_CALL_NOT_SUPPORTED	- Otherwise
+ * Return: SMC_ARCH_CALL_SUCCESS - if SMCCC feature is available.
+ *         SMC_ARCH_CALL_NOT_SUPPORTED - Otherwise.
+ *
  */
 int32_t plat_is_smccc_feature_available(u_register_t fid)
 {
@@ -33,12 +33,12 @@
 }
 
 /**
- * plat_get_soc_version() - Get the SOC version of the platform
+ * plat_get_soc_version() - Get the SOC version of the platform.
+ *
+ * Return: SiP defined SoC version in JEP-106.
  *
  * This function is called when the SoC_ID_type == 0.
- * For further details please refer to section 7.4 of SMC Calling Convention
- *
- * Return:  SiP defined SoC version in JEP-106
+ * For further details please refer to section 7.4 of SMC Calling Convention.
  */
 int32_t plat_get_soc_version(void)
 {
@@ -50,12 +50,12 @@
 }
 
 /**
- * plat_get_soc_revision() - Get the SOC revision for the platform
+ * plat_get_soc_revision() - Get the SOC revision for the platform.
+ *
+ * Return: SiP defined SoC revision.
  *
  * This function is called when the  SoC_ID_type == 1
  * For further details please refer to section 7.4 of SMC Calling Convention
- *
- * Return:  SiP defined SoC revision
  */
 int32_t plat_get_soc_revision(void)
 {
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index b901e3d..1bc30f1 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,9 +45,9 @@
 
 /**
  * versal_pwr_domain_suspend() - This function sends request to PMC to suspend
- * core.
+ *                               core.
+ * @target_state: Targated state.
  *
- * @target_state	Targated state
  */
 static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
@@ -81,9 +82,9 @@
 
 /**
  * versal_pwr_domain_suspend_finish() - This function performs actions to finish
- * suspend procedure.
+ *                                      suspend procedure.
+ * @target_state: Targated state.
  *
- * @target_state	Targated state
  */
 static void versal_pwr_domain_suspend_finish(
 					const psci_power_state_t *target_state)
@@ -120,8 +121,9 @@
 }
 
 /**
- * versal_system_off() - This function sends the system off request
- * to firmware.  This function does not return.
+ * versal_system_off() - This function sends the system off request to firmware.
+ *                       This function does not return.
+ *
  */
 static void __dead2 versal_system_off(void)
 {
@@ -135,8 +137,10 @@
 }
 
 /**
- * versal_system_reset() - This function sends the reset request
- * to firmware for the system to reset.  This function does not return.
+ * versal_system_reset() - This function sends the reset request to firmware
+ *                         for the system to reset.  This function does not
+ *			   return.
+ *
  */
 static void __dead2 versal_system_reset(void)
 {
@@ -150,9 +154,9 @@
 }
 
 /**
- * versal_pwr_domain_off() - This function performs actions to turn off core
+ * versal_pwr_domain_off() - This function performs actions to turn off core.
+ * @target_state: Targated state.
  *
- * @target_state	Targated state
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
@@ -181,12 +185,12 @@
 
 /**
  * versal_validate_power_state() - This function ensures that the power state
- * parameter in request is valid.
+ *                                 parameter in request is valid.
+ * @power_state: Power state of core.
+ * @req_state: Requested state.
  *
- * @power_state		Power state of core
- * @req_state		Requested state
+ * Return: Returns status, either success or reason.
  *
- * @return	Returns status, either success or reason
  */
 static int32_t versal_validate_power_state(uint32_t power_state,
 				       psci_power_state_t *req_state)
@@ -213,9 +217,9 @@
 }
 
 /**
- * versal_get_sys_suspend_power_state() -  Get power state for system suspend
+ * versal_get_sys_suspend_power_state() - Get power state for system suspend.
+ * @req_state: Requested state.
  *
- * @req_state	Requested state
  */
 static void versal_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index af5263d..9ad21a1 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -51,10 +51,11 @@
 const struct pm_proc *primary_proc = &pm_procs_all[0];
 
 /**
- * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number
- * @irq:	Interrupt number
+ * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
+ * @irq: Interrupt number
  *
- * Return:	PM node index corresponding to the specified interrupt
+ * Return: PM node index corresponding to the specified interrupt.
+ *
  */
 enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
 {
@@ -172,11 +173,14 @@
 }
 
 /**
- * pm_client_suspend() - Client-specific suspend actions
+ * pm_client_suspend() - Client-specific suspend actions.
+ * @proc: processor which need to suspend.
+ * @state: desired suspend state.
  *
  * This function should contain any PU-specific actions
  * required prior to sending suspend request to PMU
  * Actions taken depend on the state system is suspending to.
+ *
  */
 void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
@@ -194,10 +198,11 @@
 }
 
 /**
- * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions.
  *
  * This function should contain any PU-specific actions
- * required for aborting a prior suspend request
+ * required for aborting a prior suspend request.
+ *
  */
 void pm_client_abort_suspend(void)
 {
@@ -214,10 +219,11 @@
 }
 
 /**
- * pm_get_cpuid() - get the local cpu ID for a global node ID
- * @nid:	node id of the processor
+ * pm_get_cpuid() - get the local cpu ID for a global node ID.
+ * @nid: node id of the processor.
  *
- * Return: the cpu ID (starting from 0) for the subsystem
+ * Return: the cpu ID (starting from 0) for the subsystem.
+ *
  */
 static uint32_t pm_get_cpuid(uint32_t nid)
 {
@@ -230,10 +236,12 @@
 }
 
 /**
- * pm_client_wakeup() - Client-specific wakeup actions
+ * pm_client_wakeup() - Client-specific wakeup actions.
+ * @proc: Processor which need to wakeup.
  *
  * This function should contain any PU-specific actions
- * required for waking up another APU core
+ * required for waking up another APU core.
+ *
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
@@ -254,10 +262,11 @@
 }
 
 /**
- * pm_get_proc() - returns pointer to the proc structure
- * @cpuid:	id of the cpu whose proc struct pointer should be returned
+ * pm_get_proc() - returns pointer to the proc structure.
+ * @cpuid: id of the cpu whose proc struct pointer should be returned.
  *
- * Return: pointer to a proc structure if proc is found, otherwise NULL
+ * Return: pointer to a proc structure if proc is found, otherwise NULL.
+ *
  */
 const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index 35118a7..b30254d 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,7 +41,9 @@
 /**
  * sip_svc_setup() - Setup SiP Service
  *
- * Invokes PM setup
+ * Return: 0 on success,negative error code on failure.
+ *
+ * Invokes PM setup.
  */
 static int32_t sip_svc_setup(void)
 {
@@ -51,10 +54,20 @@
 }
 
 /**
- * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ * sip_svc_smc_handler() - Top-level SiP Service SMC handler.
+ * @smc_fid: Function Identifier.
+ * @x1: SMC64 Arguments 1 from kernel.
+ * @x2: SMC64 Arguments 2 from kernel.
+ * @x3: SMC64 Arguments 3 from kernel(upper 32-bits).
+ * @x4: SMC64 Arguments 4 from kernel.
+ * @cookie: Unused
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * Handler for all SiP SMC calls. Handles standard SIP requests
  * and calls PM SMC handler if the call is for a PM-API function.
+ *
+ * Return: Unused.
  */
 uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 			     u_register_t x1,
diff --git a/plat/xilinx/versal/versal_ipi.c b/plat/xilinx/versal/versal_ipi.c
index 51eb759..80a2e83 100644
--- a/plat/xilinx/versal/versal_ipi.c
+++ b/plat/xilinx/versal/versal_ipi.c
@@ -65,10 +65,9 @@
 	},
 };
 
-/* versal_ipi_config_table_init() - Initialize versal IPI configuration data
- *
- * @ipi_config_table  - IPI configuration table
- * @ipi_total - Total number of IPI available
+/* versal_ipi_config_table_init() - Initialize versal IPI configuration data.
+ * @ipi_config_table: IPI configuration table.
+ * @ipi_total: Total number of IPI available.
  *
  */
 void versal_ipi_config_table_init(void)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index d39fc2e..87e25bc 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,9 +50,10 @@
 }
 
 /**
- * versal_net_pwr_domain_off() - This function performs actions to turn off core
+ * versal_net_pwr_domain_off() - This function performs actions to turn off
+ *                               core.
+ * @target_state: Targeted state.
  *
- * @param target_state	Targeted state
  */
 static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 {
@@ -80,8 +81,10 @@
 }
 
 /**
- * versal_net_system_reset() - This function sends the reset request
- * to firmware for the system to reset.  This function does not return.
+ * versal_net_system_reset() - This function sends the reset request to firmware
+ *                             for the system to reset. This function does not
+ *                             return.
+ *
  */
 static void __dead2 versal_net_system_reset(void)
 {
@@ -96,9 +99,9 @@
 
 /**
  * versal_net_pwr_domain_suspend() - This function sends request to PMC to suspend
- * core.
+ *                                   core.
+ * @target_state: Targeted state.
  *
- * @param target_state	Targeted state
  */
 static void versal_net_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
@@ -140,9 +143,9 @@
 
 /**
  * versal_net_pwr_domain_suspend_finish() - This function performs actions to finish
- * suspend procedure.
+ *                                          suspend procedure.
+ * @target_state: Targeted state.
  *
- * @param target_state	Targeted state
  */
 static void versal_net_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
 {
@@ -168,7 +171,8 @@
 
 /**
  * versal_net_system_off() - This function sends the system off request
- * to firmware.  This function does not return.
+ *                           to firmware. This function does not return.
+ *
  */
 static void __dead2 versal_net_system_off(void)
 {
@@ -183,12 +187,12 @@
 
 /**
  * versal_net_validate_power_state() - This function ensures that the power state
- * parameter in request is valid.
+ *                                     parameter in request is valid.
+ * @power_state: Power state of core.
+ * @req_state: Requested state.
  *
- * @param power_state		Power state of core
- * @param req_state		Requested state
+ * Return: Returns status, either PSCI_E_SUCCESS or reason.
  *
- * @return Returns status, either PSCI_E_SUCCESS or reason
  */
 static int32_t versal_net_validate_power_state(unsigned int power_state,
 					       psci_power_state_t *req_state)
@@ -215,9 +219,10 @@
 }
 
 /**
- * versal_net_get_sys_suspend_power_state() - Get power state for system suspend
+ * versal_net_get_sys_suspend_power_state() - Get power state for system
+ *                                            suspend.
+ * @req_state: Requested state.
  *
- * @param req_state	Requested state
  */
 static void versal_net_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index 3387891..d09c927 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -152,10 +152,11 @@
 const struct pm_proc *primary_proc = &pm_procs_all[0];
 
 /**
- * pm_get_proc() - returns pointer to the proc structure
- * @param cpuid	id of the cpu whose proc struct pointer should be returned
+ * pm_get_proc() - returns pointer to the proc structure.
+ * @cpuid: id of the cpu whose proc struct pointer should be returned.
  *
- * @return pointer to a proc structure if proc is found, otherwise NULL
+ * Return: Pointer to a proc structure if proc is found, otherwise NULL.
+ *
  */
 const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
@@ -168,10 +169,11 @@
 }
 
 /**
- * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number
- * @irq:        Interrupt number
+ * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
+ * @irq: Interrupt number.
  *
- * Return:      PM node index corresponding to the specified interrupt
+ * Return: PM node index corresponding to the specified interrupt.
+ *
  */
 enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
 {
@@ -295,14 +297,13 @@
 }
 
 /**
- * pm_client_suspend() - Client-specific suspend actions
+ * pm_client_suspend() - Client-specific suspend actions. This function
+ *                       should contain any PU-specific actions required
+ *                       prior to sending suspend request to PMU. Actions
+ *                       taken depend on the state system is suspending to.
+ * @proc: processor which need to suspend.
+ * @state: desired suspend state.
  *
- * This function should contain any PU-specific actions
- * required prior to sending suspend request to PMU
- * Actions taken depend on the state system is suspending to.
- *
- * @param proc	processor which need to suspend
- * @param state	desired suspend state
  */
 void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
@@ -338,10 +339,11 @@
 }
 
 /**
- * pm_get_cpuid() - get the local cpu ID for a global node ID
- * @param nid	node id of the processor
+ * pm_get_cpuid() - get the local cpu ID for a global node ID.
+ * @nid: node id of the processor.
  *
- * @return the cpu ID (starting from 0) for the subsystem
+ * Return: the cpu ID (starting from 0) for the subsystem.
+ *
  */
 static uint32_t pm_get_cpuid(uint32_t nid)
 {
@@ -354,12 +356,12 @@
 }
 
 /**
- * pm_client_wakeup() - Client-specific wakeup actions
+ * pm_client_wakeup() - Client-specific wakeup actions.
+ * @proc: Processor which need to wakeup.
  *
  * This function should contain any PU-specific actions
- * required for waking up another APU core
+ * required for waking up another APU core.
  *
- * @param proc	Processor which need to wakeup
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
@@ -393,10 +395,11 @@
 }
 
 /**
- * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions.
  *
  * This function should contain any PU-specific actions
- * required for aborting a prior suspend request
+ * required for aborting a prior suspend request.
+ *
  */
 void pm_client_abort_suspend(void)
 {
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index f6240f3..0c27dec 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -43,6 +43,9 @@
 
 /**
  * sip_svc_setup() - Setup SiP Service
+ *
+ * Return: 0 on success, negative error code on failure.
+ *
  */
 static int32_t sip_svc_setup(void)
 {
diff --git a/plat/xilinx/versal_net/versal_net_ipi.c b/plat/xilinx/versal_net/versal_net_ipi.c
index ed3f2bb..0943c62 100644
--- a/plat/xilinx/versal_net/versal_net_ipi.c
+++ b/plat/xilinx/versal_net/versal_net_ipi.c
@@ -65,10 +65,10 @@
 	},
 };
 
-/* versal_net_ipi_config_table_init() - Initialize versal_net IPI configuration data
- *
- * @ipi_config_table  - IPI configuration table
- * @ipi_total - Total number of IPI available
+/* versal_net_ipi_config_table_init() - Initialize versal_net IPI configuration
+ *                                      data.
+ * @ipi_config_table: IPI configuration table.
+ * @ipi_total: Total number of IPI available.
  *
  */
 void versal_net_ipi_config_table_init(void)
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 2f8f4c1..2041541 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -198,14 +198,15 @@
 	}
 
 /**
- * struct pm_clock_node - Clock topology node information
- * @type:	Topology type (mux/div1/div2/gate/pll/fixed factor)
- * @offset:	Offset in control register
- * @width:	Width of the specific type in control register
- * @clkflags:	Clk specific flags
- * @typeflags:	Type specific flags
- * @mult:	Multiplier for fixed factor
- * @div:	Divisor for fixed factor
+ * struct pm_clock_node - Clock topology node information.
+ * @type: Topology type (mux/div1/div2/gate/pll/fixed factor).
+ * @offset: Offset in control register.
+ * @width: Width of the specific type in control register.
+ * @clkflags: Clk specific flags.
+ * @typeflags: Type specific flags.
+ * @mult: Multiplier for fixed factor.
+ * @div: Divisor for fixed factor.
+ *
  */
 struct pm_clock_node {
 	uint16_t clkflags;
@@ -218,13 +219,15 @@
 };
 
 /**
- * struct pm_clock - Clock structure
- * @name:	Clock name
- * @control_reg:	Control register address
- * @status_reg:	Status register address
- * @parents:	Parents for first clock node. Lower byte indicates parent
- *		clock id and upper byte indicate flags for that id.
- * pm_clock_node:	Clock nodes
+ * struct pm_clock - Clock structure.
+ * @name: Clock name.
+ * @num_nodes: number of nodes.
+ * @control_reg: Control register address.
+ * @status_reg: Status register address.
+ * @parents: Parents for first clock node. Lower byte indicates parent
+ *           clock id and upper byte indicate flags for that id.
+ * @nodes: Clock nodes.
+ *
  */
 struct pm_clock {
 	char name[CLK_NAME_LEN];
@@ -236,8 +239,9 @@
 };
 
 /**
- * struct pm_clock - Clock structure
- * @name:		Clock name
+ * struct pm_ext_clock - Clock structure.
+ * @name: Clock name.
+ *
  */
 struct pm_ext_clock {
 	char name[CLK_NAME_LEN];
@@ -2386,8 +2390,8 @@
 };
 
 /**
- * pm_clock_valid - Check if clock is valid or not
- * @clock_id	Id of the clock to be queried
+ * pm_clock_valid - Check if clock is valid or not.
+ * @clock_id: Id of the clock to be queried.
  *
  * This function is used to check if given clock is valid
  * or not for the chip variant.
@@ -2396,6 +2400,7 @@
  * different variants.
  *
  * Return: Returns 1 if clock is valid else 0.
+ *
  */
 static bool pm_clock_valid(uint32_t clock_id)
 {
@@ -2409,12 +2414,13 @@
 }
 
 /**
- * pm_clock_type - Get clock's type
- * @clock_id	Id of the clock to be queried
+ * pm_clock_type - Get clock's type.
+ * @clock_id: Id of the clock to be queried.
  *
  * This function is used to check type of clock (OUTPUT/EXTERNAL).
  *
  * Return: Returns type of clock (OUTPUT/EXTERNAL).
+ *
  */
 static uint32_t pm_clock_type(uint32_t clock_id)
 {
@@ -2423,12 +2429,13 @@
 }
 
 /**
- * pm_api_clock_get_num_clocks() - PM call to request number of clocks
- * @nclocks	Number of clocks
+ * pm_api_clock_get_num_clocks() - PM call to request number of clocks.
+ * @nclocks: Number of clocks.
  *
  * This function is used by master to get number of clocks.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks)
 {
@@ -2438,12 +2445,13 @@
 }
 
 /**
- * pm_api_clock_get_name() - PM call to request a clock's name
- * @clock_id	Clock ID
- * @name	Name of clock (max 16 bytes)
+ * pm_api_clock_get_name() - PM call to request a clock's name.
+ * @clock_id: Clock ID.
+ * @name: Name of clock (max 16 bytes).
  *
  * This function is used by master to get nmae of clock specified
  * by given clock ID.
+ *
  */
 void pm_api_clock_get_name(uint32_t clock_id, char *name)
 {
@@ -2461,17 +2469,18 @@
 }
 
 /**
- * pm_api_clock_get_topology() - PM call to request a clock's topology
- * @clock_id	Clock ID
- * @index	Topology index for next toplogy node
- * @topology	Buffer to store nodes in topology and flags
+ * pm_api_clock_get_topology() - PM call to request a clock's topology.
+ * @clock_id: Clock ID.
+ * @index: Topology index for next toplogy node.
+ * @topology: Buffer to store nodes in topology and flags.
  *
  * This function is used by master to get topology information for the
  * clock specified by given clock ID. Each response would return 3
  * topology nodes. To get next nodes, caller needs to call this API with
  * index of next node. Index starts from 0.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
 					     uint32_t index,
@@ -2519,15 +2528,16 @@
 
 /**
  * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
- *					   factor parameters for fixed clock
- * @clock_id	Clock ID
- * @mul		Multiplication value
- * @div		Divisor value
+ *					   factor parameters for fixed clock.
+ * @clock_id: Clock ID.
+ * @mul: Multiplication value.
+ * @div: Divisor value.
  *
  * This function is used by master to get fixed factor parameers for the
  * fixed clock. This API is application only for the fixed clock.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
 						       uint32_t *mul,
@@ -2566,10 +2576,10 @@
 }
 
 /**
- * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
- * @clock_id	Clock ID
- * @index	Index of next parent
- * @parents	Parents of the given clock
+ * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents.
+ * @clock_id: Clock ID.
+ * @index: Index of next parent.
+ * @parents: Parents of the given clock.
  *
  * This function is used by master to get clock's parents information.
  * This API will return 3 parents with a single response. To get other
@@ -2580,7 +2590,8 @@
  * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
  * so on.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
 					    uint32_t index,
@@ -2622,14 +2633,15 @@
 }
 
 /**
- * pm_api_clock_get_attributes() - PM call to request a clock's attributes
- * @clock_id	Clock ID
- * @attr	Clock attributes
+ * pm_api_clock_get_attributes() - PM call to request a clock's attributes.
+ * @clock_id: Clock ID.
+ * @attr: Clock attributes.
  *
  * This function is used by master to get clock's attributes
  * (e.g. valid, clock type, etc).
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
 					       uint32_t *attr)
@@ -2648,14 +2660,15 @@
 }
 
 /**
- * pm_api_clock_get_max_divisor - PM call to get max divisor
- * @clock_id	Clock ID
- * @div_type	Divisor Type (TYPE_DIV1 or TYPE_DIV2)
- * @max_div	Maximum supported divisor
+ * pm_api_clock_get_max_divisor - PM call to get max divisor.
+ * @clock_id: Clock ID.
+ * @div_type: Divisor Type (TYPE_DIV1 or TYPE_DIV2).
+ * @max_div: Maximum supported divisor.
  *
  * This function is used by master to get maximum supported value.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
 						uint8_t div_type,
@@ -2685,15 +2698,16 @@
 }
 
 /**
- * struct pm_pll - PLL related data required to map IOCTL-based PLL control
- * implemented by linux to system-level EEMI APIs
- * @nid:	PLL node ID
- * @cid:	PLL clock ID
- * @pre_src:	Pre-source PLL clock ID
- * @post_src:	Post-source PLL clock ID
- * @div2:	DIV2 PLL clock ID
- * @bypass:	PLL output clock ID that maps to bypass select output
- * @mode:	PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE)
+ * struct pm_pll - PLL related data required to map IOCTL-based PLL control.
+ * implemented by linux to system-level EEMI APIs.
+ * @nid: PLL node ID.
+ * @cid: PLL clock ID.
+ * @pre_src: Pre-source PLL clock ID.
+ * @post_src: Post-source PLL clock ID.
+ * @div2: DIV2 PLL clock ID.
+ * @bypass: PLL output clock ID that maps to bypass select output.
+ * @mode: PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE).
+ *
  */
 struct pm_pll {
 	const enum pm_node_id nid;
@@ -2745,10 +2759,11 @@
 };
 
 /**
- * pm_clock_get_pll() - Get PLL structure by PLL clock ID
- * @clock_id	Clock ID of the target PLL
+ * pm_clock_get_pll() - Get PLL structure by PLL clock ID.
+ * @clock_id: Clock ID of the target PLL.
  *
- * @return	Pointer to PLL structure if found, NULL otherwise
+ * Return: Pointer to PLL structure if found, NULL otherwise.
+ *
  */
 struct pm_pll *pm_clock_get_pll(enum clock_id clock_id)
 {
@@ -2764,11 +2779,12 @@
 }
 
 /**
- * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID
- * @clock_id	Clock ID of the target PLL
- * @node_id	Location to store node ID of the target PLL
+ * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID.
+ * @clock_id: Clock ID of the target PLL.
+ * @node_id: Location to store node ID of the target PLL.
  *
- * @return	PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise
+ * Return: PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise.
+ *
  */
 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
 					    enum pm_node_id *node_id)
@@ -2784,10 +2800,12 @@
 }
 
 /**
- * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock ID
- * @clock_id	Clock ID
+ * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock
+ *                                     ID.
+ * @clock_id: Clock ID.
  *
- * @return	Pointer to PLL structure if found, NULL otherwise
+ * Return: Pointer to PLL structure if found, NULL otherwise.
+ *
  */
 struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id)
 {
@@ -2806,13 +2824,14 @@
 }
 
 /**
- * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL)
- * @pll: PLL to be locked
+ * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL).
+ * @pll: PLL to be locked.
  *
  * This function is used to map IOCTL/linux-based PLL handling to system-level
- * EEMI APIs
+ * EEMI APIs.
  *
- * Return: Error if the argument is not valid or status as returned by PMU
+ * Return: Error if the argument is not valid or status as returned by PMU.
+ *
  */
 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
 {
@@ -2829,13 +2848,14 @@
 }
 
 /**
- * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL)
- * @pll		PLL to be bypassed/reset
+ * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL).
+ * @pll: PLL to be bypassed/reset.
  *
  * This function is used to map IOCTL/linux-based PLL handling to system-level
- * EEMI APIs
+ * EEMI APIs.
  *
- * Return: Error if the argument is not valid or status as returned by PMU
+ * Return: Error if the argument is not valid or status as returned by PMU.
+ *
  */
 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
 {
@@ -2847,15 +2867,15 @@
 }
 
 /**
- * pm_clock_pll_get_state - Get state of the PLL
- * @pll		Pointer to the target PLL structure
- * @state	Location to store the state: 1/0 ("Enabled"/"Disabled")
+ * pm_clock_pll_get_state - Get state of the PLL.
+ * @pll: Pointer to the target PLL structure.
+ * @state: Location to store the state: 1/0 ("Enabled"/"Disabled").
  *
  * "Enable" actually means that the PLL is locked and its bypass is deasserted,
  * "Disable" means that it is bypassed.
  *
  * Return: PM_RET_ERROR_ARGS error if the argument is not valid, success if
- * returned state value is valid or an error if returned by PMU
+ *         returned state value is valid or an error if returned by PMU.
  */
 enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
 					  uint32_t *state)
@@ -2882,16 +2902,17 @@
 }
 
 /**
- * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id
- * @pll			Target PLL structure
- * @clock_id		Id of the clock
- * @parent_index	parent index (=mux select value)
+ * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id.
+ * @pll: Target PLL structure.
+ * @clock_id: Id of the clock.
+ * @parent_index: parent index (=mux select value).
  *
  * The whole clock-tree implementation relies on the fact that parent indexes
  * match to the multiplexer select values. This function has to rely on that
  * assumption as well => parent_index is actually the mux select value.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
 					   enum clock_id clock_id,
@@ -2917,14 +2938,15 @@
 }
 
 /**
- * pm_clock_pll_get_parent - Get mux select value of PLL-related clock parent
- * @pll			Target PLL structure
- * @clock_id		Id of the clock
- * @parent_index	parent index (=mux select value)
+ * pm_clock_pll_get_parent - Get mux select value of PLL-related clock parent.
+ * @pll: Target PLL structure.
+ * @clock_id: Id of the clock.
+ * @parent_index: parent index (=mux select value).
  *
  * This function is used by master to get parent index for PLL-related clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
 					   enum clock_id clock_id,
@@ -2954,13 +2976,14 @@
 }
 
 /**
- * pm_clock_set_pll_mode() -  Set PLL mode
- * @clock_id	PLL clock id
- * @mode	Mode fractional/integer
+ * pm_clock_set_pll_mode() -  Set PLL mode.
+ * @clock_id: PLL clock id.
+ * @mode: Mode fractional/integer.
  *
  * This function buffers/saves the PLL mode that is set.
  *
- * @return      Success if mode is buffered or error if an argument is invalid
+ * Return: Success if mode is buffered or error if an argument is invalid.
+ *
  */
 enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
 					 uint32_t mode)
@@ -2976,13 +2999,14 @@
 }
 
 /**
- * pm_clock_get_pll_mode() -  Get PLL mode
- * @clock_id	PLL clock id
- * @mode	Location to store the mode (fractional/integer)
+ * pm_clock_get_pll_mode() -  Get PLL mode.
+ * @clock_id: PLL clock id.
+ * @mode: Location to store the mode (fractional/integer).
  *
  * This function returns buffered PLL mode.
  *
- * @return      Success if mode is stored or error if an argument is invalid
+ * Return: Success if mode is stored or error if an argument is invalid.
+ *
  */
 enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
 					 uint32_t *mode)
@@ -2998,10 +3022,11 @@
 }
 
 /**
- * pm_clock_id_is_valid() -  Check if given clock ID is valid
- * @clock_id   ID of the clock to be checked
+ * pm_clock_id_is_valid() -  Check if given clock ID is valid.
+ * @clock_id: ID of the clock to be checked.
  *
- * @return     Returns success if clock_id is valid, otherwise an error
+ * Return: Returns success if clock_id is valid, otherwise an error.
+ *
  */
 enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
 {
@@ -3017,11 +3042,12 @@
 }
 
 /**
- * pm_clock_has_div() - Check if the clock has divider with given ID
- * @clock_id	Clock ID
- * @div_id	Divider ID
+ * pm_clock_has_div() - Check if the clock has divider with given ID.
+ * @clock_id: Clock ID.
+ * @div_id: Divider ID.
  *
- * @return	True(1)=clock has the divider, false(0)=otherwise
+ * Return: True(1)=clock has the divider, false(0)=otherwise.
+ *
  */
 uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
 {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index afd664e..1880d9b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -23,12 +23,13 @@
 #include "zynqmp_pm_api_sys.h"
 
 /**
- * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
- * @mode	Buffer to store value of oper mode(Split/Lock-step)
+ * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode.
+ * @mode: Buffer to store value of oper mode(Split/Lock-step)
  *
  * This function provides current configured RPU operational mode.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
 {
@@ -46,15 +47,16 @@
 }
 
 /**
- * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
- * @mode	Value to set for oper mode(Split/Lock-step)
+ * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode.
+ * @mode: Value to set for oper mode(Split/Lock-step).
  *
  * This function configures RPU operational mode(Split/Lock-step).
  * It also sets TCM combined mode in RPU lock-step and TCM non-combined
  * mode for RPU split mode. In case of Lock step mode, RPU1's output is
  * clamped.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
 {
@@ -84,13 +86,14 @@
 }
 
 /**
- * pm_ioctl_config_boot_addr() - Configure RPU boot address
- * @nid		Node ID of RPU
- * @value	Value to set for boot address (TCM/OCM)
+ * pm_ioctl_config_boot_addr() - Configure RPU boot address.
+ * @nid: Node ID of RPU.
+ * @value: Value to set for boot address (TCM/OCM).
  *
  * This function configures RPU boot address(memory).
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
 						    uint32_t value)
@@ -121,13 +124,14 @@
 }
 
 /**
- * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
- * @value	Value to set (Split/Combined)
+ * pm_ioctl_config_tcm_comb() - Configure TCM combined mode.
+ * @value: Value to set (Split/Combined).
  *
  * This function configures TCM to be in split mode or combined
  * mode.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
 {
@@ -149,13 +153,14 @@
 }
 
 /**
- * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass
- * @type	Type of tap delay to enable/disable (e.g. QSPI)
- * @value	Enable/Disable
+ * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass.
+ * @type: Type of tap delay to enable/disable (e.g. QSPI).
+ * @value: Enable/Disable.
  *
  * This function enable/disable tap delay bypass.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
 						       uint32_t value)
@@ -169,15 +174,16 @@
 }
 
 /**
- * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device
- * @nid		Node ID of the device
- * @value	Enable/Disable
+ * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device.
+ * @nid: Node ID of the device.
+ * @value: Enable/Disable.
  *
  * This function enable/disable SGMII mode for the GEM device.
  * While enabling SGMII mode, it also ties the GEM PCS Signal
  * Detect to 1 and selects EMIO for RX clock generation.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
 						  uint32_t value)
@@ -229,13 +235,14 @@
 }
 
 /**
- * pm_ioctl_sd_dll_reset() -  Reset DLL logic
- * @nid		Node ID of the device
- * @type	Reset type
+ * pm_ioctl_sd_dll_reset() -  Reset DLL logic.
+ * @nid: Node ID of the device.
+ * @type: Reset type.
  *
  * This function resets DLL logic for the SD device.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
 						uint32_t type)
@@ -278,14 +285,15 @@
 }
 
 /**
- * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device
- * @nid		Node ID of the device
- * @type	Type of tap delay to set (input/output)
- * @value	Value to set fot the tap delay
+ * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device.
+ * @nid: Node ID of the device.
+ * @type: Type of tap delay to set (input/output).
+ * @value: Value to set fot the tap delay.
  *
  * This function sets input/output tap delay for the SD device.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
 						   enum tap_delay_type type,
@@ -375,14 +383,14 @@
 }
 
 /**
- * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
- *				   setting pll mode
- * @pll     PLL clock id
- * @mode    Mode fraction/integar
+ * pm_ioctl_set_pll_frac_mode() -  Ioctl function for setting pll mode.
+ * @pll: PLL clock id.
+ * @mode: Mode fraction/integar.
  *
- * This function sets PLL mode
+ * This function sets PLL mode.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
 			(uint32_t pll, uint32_t mode)
@@ -391,14 +399,14 @@
 }
 
 /**
- * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
- *				   getting pll mode
- * @pll     PLL clock id
- * @mode    Mode fraction/integar
+ * pm_ioctl_get_pll_frac_mode() -  Ioctl function for getting pll mode.
+ * @pll: PLL clock id.
+ * @mode: Mode fraction/integar.
  *
- * This function return current PLL mode
+ * This function return current PLL mode.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
 			(uint32_t pll, uint32_t *mode)
@@ -407,15 +415,15 @@
 }
 
 /**
- * pm_ioctl_set_pll_frac_data() -  Ioctl function for
- *				   setting pll fraction data
- * @pll     PLL clock id
- * @data    fraction data
+ * pm_ioctl_set_pll_frac_data() -  Ioctl function for setting pll fraction data.
+ * @pll: PLL clock id.
+ * @data: fraction data.
  *
  * This function sets fraction data.
  * It is valid for fraction mode only.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_pll_frac_data
 			(uint32_t pll, uint32_t data)
@@ -433,14 +441,14 @@
 }
 
 /**
- * pm_ioctl_get_pll_frac_data() -  Ioctl function for
- *				   getting pll fraction data
- * @pll     PLL clock id
- * @data    fraction data
+ * pm_ioctl_get_pll_frac_data() -  Ioctl function for getting pll fraction data.
+ * @pll: PLL clock id.
+ * @data: fraction data.
  *
  * This function returns fraction data value.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_get_pll_frac_data
 			(uint32_t pll, uint32_t *data)
@@ -458,14 +466,15 @@
 }
 
 /**
- * pm_ioctl_write_ggs() - Ioctl function for writing
- *			  global general storage (ggs)
- * @index	GGS register index
- * @value	Register value to be written
+ * pm_ioctl_write_ggs() - Ioctl function for writing global general storage
+ *                        (ggs).
+ * @index: GGS register index.
+ * @value: Register value to be written.
  *
  * This function writes value to GGS register.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
 					     uint32_t value)
@@ -479,14 +488,15 @@
 }
 
 /**
- * pm_ioctl_read_ggs() - Ioctl function for reading
- *			 global general storage (ggs)
- * @index	GGS register index
- * @value	Register value
+ * pm_ioctl_read_ggs() - Ioctl function for reading global general storage
+ *                       (ggs).
+ * @index: GGS register index.
+ * @value: Register value.
  *
  * This function returns GGS register value.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
 					    uint32_t *value)
@@ -499,14 +509,15 @@
 }
 
 /**
- * pm_ioctl_write_pggs() - Ioctl function for writing persistent
- *			   global general storage (pggs)
- * @index	PGGS register index
- * @value	Register value to be written
+ * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general
+ *                         storage (pggs).
+ * @index: PGGS register index.
+ * @value: Register value to be written.
  *
  * This function writes value to PGGS register.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
 					      uint32_t value)
@@ -520,13 +531,12 @@
 }
 
 /**
- * pm_ioctl_afi() - Ioctl function for writing afi values
+ * pm_ioctl_afi() - Ioctl function for writing afi values.
+ * @index: AFI register index.
+ * @value: Register value to be written.
  *
- * @index 	AFI register index
- * @value	Register value to be written
+ * Return: Returns status, either success or error+reason.
  *
- *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_afi(uint32_t index,
 					      uint32_t value)
@@ -564,14 +574,15 @@
 }
 
 /**
- * pm_ioctl_read_pggs() - Ioctl function for reading persistent
- *			  global general storage (pggs)
- * @index	PGGS register index
- * @value	Register value
+ * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general
+ *                        storage (pggs).
+ * @index: PGGS register index.
+ * @value: Register value.
  *
  * This function returns PGGS register value.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
 					     uint32_t *value)
@@ -584,12 +595,12 @@
 }
 
 /**
- * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
+ * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset.
+ *
+ * Return: Returns status, either success or error+reason.
  *
  * This function peerforms the ULPI reset sequence for resetting
  * the ULPI transceiver.
- *
- * @return      Returns status, either success or error+reason
  */
 static enum pm_ret_status pm_ioctl_ulpi_reset(void)
 {
@@ -620,12 +631,14 @@
 }
 
 /**
- * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
+ * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status.
+ * @value: Value to write.
  *
  * This function sets healthy bit value to indicate boot health status
  * to firmware.
  *
- * @return      Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
 {
@@ -634,16 +647,17 @@
 }
 
 /**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs
- * @node_id	Node ID of the device
- * @ioctl_id	ID of the requested IOCTL
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @value	Returned output value
+ * pm_api_ioctl() -  PM IOCTL API for device control and configs.
+ * @nid: Node ID of the device.
+ * @ioctl_id: ID of the requested IOCTL.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @value: Returned output value.
  *
  * This function calls IOCTL to firmware for device control and configuration.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
 				uint32_t ioctl_id,
@@ -724,8 +738,11 @@
 }
 
 /**
- * pm_update_ioctl_bitmask() -  API to get supported IOCTL ID mask
- * @bit_mask		Returned bit mask of supported IOCTL IDs
+ * tfa_ioctl_bitmask() -  API to get supported IOCTL ID mask.
+ * @bit_mask: Returned bit mask of supported IOCTL IDs.
+ *
+ * Return: 0 success, negative value for errors.
+ *
  */
 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
 {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 6afadef..2d8c23b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -1946,12 +1946,13 @@
 };
 
 /**
- * pm_api_pinctrl_get_num_pins() - PM call to request number of pins
- * @npins	Number of pins
+ * pm_api_pinctrl_get_num_pins() - PM call to request number of pins.
+ * @npins: Number of pins.
  *
- * This function is used by master to get number of pins
+ * This function is used by master to get number of pins.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_num_pins(uint32_t *npins)
 {
@@ -1961,12 +1962,13 @@
 }
 
 /**
- * pm_api_pinctrl_get_num_functions() - PM call to request number of functions
- * @nfuncs	Number of functions
+ * pm_api_pinctrl_get_num_functions() - PM call to request number of functions.
+ * @nfuncs: Number of functions.
  *
- * This function is used by master to get number of functions
+ * This function is used by master to get number of functions.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_num_functions(uint32_t *nfuncs)
 {
@@ -1977,13 +1979,14 @@
 
 /**
  * pm_api_pinctrl_get_num_func_groups() - PM call to request number of
- *					  function groups
- * @fid		Function Id
- * @ngroups	Number of function groups
+ *					  function groups.
+ * @fid: Function Id.
+ * @ngroups: Number of function groups.
  *
- * This function is used by master to get number of function groups
+ * This function is used by master to get number of function groups.
  *
- * @return	Returns success.
+ * Return: Returns success.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
 						      uint32_t *ngroups)
@@ -1998,12 +2001,13 @@
 }
 
 /**
- * pm_api_pinctrl_get_function_name() - PM call to request a function name
- * @fid		Function ID
- * @name	Name of function (max 16 bytes)
+ * pm_api_pinctrl_get_function_name() - PM call to request a function name.
+ * @fid: Function ID.
+ * @name: Name of function (max 16 bytes).
  *
  * This function is used by master to get name of function specified
  * by given function ID.
+ *
  */
 void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
 {
@@ -2016,10 +2020,10 @@
 
 /**
  * pm_api_pinctrl_get_function_groups() - PM call to request first 6 function
- *					  groups of function Id
- * @fid		Function ID
- * @index	Index of next function groups
- * @groups	Function groups
+ *					  groups of function Id.
+ * @fid: Function ID.
+ * @index: Index of next function groups.
+ * @groups: Function groups.
  *
  * This function is used by master to get function groups specified
  * by given function Id. This API will return 6 function groups with
@@ -2031,6 +2035,7 @@
  * function groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
 						      uint32_t index,
@@ -2061,10 +2066,10 @@
 
 /**
  * pm_api_pinctrl_get_pin_groups() - PM call to request first 6 pin
- *				     groups of pin
- * @pin		Pin
- * @index	Index of next pin groups
- * @groups	pin groups
+ *                                   groups of pin.
+ * @pin: Pin.
+ * @index: Index of next pin groups.
+ * @groups: pin groups.
  *
  * This function is used by master to get pin groups specified
  * by given pin Id. This API will return 6 pin groups with
@@ -2076,6 +2081,7 @@
  * pin groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
 						 uint32_t index,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 853e9e1..8cf29f0 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -157,10 +157,11 @@
 };
 
 /**
- * irq_to_pm_node - Get PM node ID corresponding to the interrupt number
- * @irq:	Interrupt number
+ * irq_to_pm_node - Get PM node ID corresponding to the interrupt number.
+ * @irq: Interrupt number.
  *
- * Return:	PM node ID corresponding to the specified interrupt
+ * Return: PM node ID corresponding to the specified interrupt.
+ *
  */
 static enum pm_node_id irq_to_pm_node(uint32_t irq)
 {
@@ -170,7 +171,8 @@
 
 /**
  * pm_client_set_wakeup_sources - Set all slaves with enabled interrupts as wake
- *				sources in the PMU firmware
+ *                                sources in the PMU firmware.
+ *
  */
 static void pm_client_set_wakeup_sources(void)
 {
@@ -227,10 +229,11 @@
 }
 
 /**
- * pm_get_proc() - returns pointer to the proc structure
- * @cpuid:	id of the cpu whose proc struct pointer should be returned
+ * pm_get_proc() - returns pointer to the proc structure.
+ * @cpuid: id of the cpu whose proc struct pointer should be returned.
  *
- * Return: pointer to a proc structure if proc is found, otherwise NULL
+ * Return: pointer to a proc structure if proc is found, otherwise NULL.
+ *
  */
 const struct pm_proc *pm_get_proc(uint32_t cpuid)
 {
@@ -242,10 +245,11 @@
 }
 
 /**
- * pm_get_proc_by_node() - returns pointer to the proc structure
- * @nid:	node id of the processor
+ * pm_get_proc_by_node() - returns pointer to the proc structure.
+ * @nid: node id of the processor.
  *
- * Return: pointer to a proc structure if proc is found, otherwise NULL
+ * Return: pointer to a proc structure if proc is found, otherwise NULL.
+ *
  */
 const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
 {
@@ -258,10 +262,11 @@
 }
 
 /**
- * pm_get_cpuid() - get the local cpu ID for a global node ID
- * @nid:	node id of the processor
+ * pm_get_cpuid() - get the local cpu ID for a global node ID.
+ * @nid: node id of the processor.
  *
- * Return: the cpu ID (starting from 0) for the subsystem
+ * Return: the cpu ID (starting from 0) for the subsystem.
+ *
  */
 static uint32_t pm_get_cpuid(enum pm_node_id nid)
 {
@@ -276,11 +281,14 @@
 const struct pm_proc *primary_proc = &pm_procs_all[0];
 
 /**
- * pm_client_suspend() - Client-specific suspend actions
+ * pm_client_suspend() - Client-specific suspend actions.
+ * @proc: processor which need to suspend.
+ * @state: desired suspend state.
  *
  * This function should contain any PU-specific actions
  * required prior to sending suspend request to PMU
  * Actions taken depend on the state system is suspending to.
+ *
  */
 void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
 {
@@ -298,10 +306,11 @@
 
 
 /**
- * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions.
  *
  * This function should contain any PU-specific actions
- * required for aborting a prior suspend request
+ * required for aborting a prior suspend request.
+ *
  */
 void pm_client_abort_suspend(void)
 {
@@ -318,10 +327,12 @@
 }
 
 /**
- * pm_client_wakeup() - Client-specific wakeup actions
+ * pm_client_wakeup() - Client-specific wakeup actions.
+ * @proc: Processor which need to wakeup.
  *
  * This function should contain any PU-specific actions
- * required for waking up another APU core
+ * required for waking up another APU core.
+ *
  */
 void pm_client_wakeup(const struct pm_proc *proc)
 {
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 75cb54f..ece5954 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -37,11 +37,11 @@
 	(1ULL << (uint64_t)PM_QID_CLOCK_GET_MAX_DIVISOR))
 
 /**
- * struct eemi_api_dependency - Dependent EEMI APIs which are implemented
- * on both the TF-A and firmware
+ * typedef eemi_api_dependency - Dependent EEMI APIs which are implemented
+ *                               on both the TF-A and firmware.
+ * @id: EEMI API id or IOCTL id to be checked.
+ * @api_id: Dependent EEMI API.
  *
- * @id:		EEMI API id or IOCTL id to be checked
- * @api_id:	Dependent EEMI API
  */
 typedef struct __attribute__((packed)) {
 	uint8_t id;
@@ -244,9 +244,10 @@
 static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
 
 /**
- * pm_get_shutdown_scope() - Get the currently set shutdown scope
+ * pm_get_shutdown_scope() - Get the currently set shutdown scope.
  *
- * @return	Shutdown scope value
+ * Return: Shutdown scope value.
+ *
  */
 uint32_t pm_get_shutdown_scope(void)
 {
@@ -254,16 +255,17 @@
 }
 
 /**
- * pm_self_suspend() - PM call for processor to suspend itself
- * @nid		Node id of the processor or subsystem
- * @latency	Requested maximum wakeup latency (not supported)
- * @state	Requested state
- * @address	Resume address
+ * pm_self_suspend() - PM call for processor to suspend itself.
+ * @nid: Node id of the processor or subsystem.
+ * @latency: Requested maximum wakeup latency (not supported).
+ * @state: Requested state.
+ * @address: Resume address.
  *
  * This is a blocking call, it will return only once PMU has responded.
  * On a wakeup, resume address will be automatically set by PMU.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
 				   uint32_t latency,
@@ -287,13 +289,14 @@
 
 /**
  * pm_req_suspend() - PM call to request for another PU or subsystem to
- *		      be suspended gracefully.
- * @target	Node id of the targeted PU or subsystem
- * @ack		Flag to specify whether acknowledge is requested
- * @latency	Requested wakeup latency (not supported)
- * @state	Requested state (not supported)
+ *                    be suspended gracefully.
+ * @target: Node id of the targeted PU or subsystem.
+ * @ack: Flag to specify whether acknowledge is requested.
+ * @latency: Requested wakeup latency (not supported).
+ * @state: Requested state (not supported).
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_req_suspend(enum pm_node_id target,
 				  enum pm_request_ack ack,
@@ -312,19 +315,20 @@
 
 /**
  * pm_req_wakeup() - PM call for processor to wake up selected processor
- *		     or subsystem
- * @target	Node id of the processor or subsystem to wake up
- * @ack		Flag to specify whether acknowledge requested
- * @set_address	Resume address presence indicator
- *				1 resume address specified, 0 otherwise
- * @address	Resume address
+ *		     or subsystem.
+ * @target: Node id of the processor or subsystem to wake up.
+ * @ack: Flag to specify whether acknowledge requested.
+ * @set_address: Resume address presence indicator.
+ *               1 resume address specified, 0 otherwise.
+ * @address: Resume address.
  *
  * This API function is either used to power up another APU core for SMP
  * (by PSCI) or to power up an entirely different PU or subsystem, such
  * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
  * automatically set by PMU.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
 				 uint32_t set_address,
@@ -352,11 +356,12 @@
 
 /**
  * pm_force_powerdown() - PM call to request for another PU or subsystem to
- *			  be powered down forcefully
- * @target	Node id of the targeted PU or subsystem
- * @ack		Flag to specify whether acknowledge is requested
+ *                        be powered down forcefully.
+ * @target: Node id of the targeted PU or subsystem.
+ * @ack: Flag to specify whether acknowledge is requested.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
 				      enum pm_request_ack ack)
@@ -375,13 +380,14 @@
 
 /**
  * pm_abort_suspend() - PM call to announce that a prior suspend request
- *			is to be aborted.
- * @reason	Reason for the abort
+ *                      is to be aborted.
+ * @reason: Reason for the abort.
  *
  * Calling PU expects the PMU to abort the initiated suspend procedure.
  * This is a non-blocking call without any acknowledge.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason
+ *
  */
 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
 {
@@ -400,12 +406,14 @@
 }
 
 /**
- * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
- * @target	Node id of the targeted PU or subsystem
- * @wkup_node	Node id of the wakeup peripheral
- * @enable	Enable or disable the specified peripheral as wake source
+ * pm_set_wakeup_source() - PM call to specify the wakeup source while
+ *                          suspended.
+ * @target: Node id of the targeted PU or subsystem.
+ * @wkup_node: Node id of the wakeup peripheral.
+ * @enable: Enable or disable the specified peripheral as wake source.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
 					enum pm_node_id wkup_node,
@@ -419,11 +427,12 @@
 }
 
 /**
- * pm_system_shutdown() - PM call to request a system shutdown or restart
- * @type	Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
- * @subtype	Scope: 0=APU-subsystem, 1=PS, 2=system
+ * pm_system_shutdown() - PM call to request a system shutdown or restart.
+ * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
+ * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
 {
@@ -442,13 +451,14 @@
 /* APIs for managing PM slaves: */
 
 /**
- * pm_req_node() - PM call to request a node with specific capabilities
- * @nid		Node id of the slave
- * @capabilities Requested capabilities of the slave
- * @qos		Quality of service (not supported)
- * @ack		Flag to specify whether acknowledge is requested
+ * pm_req_node() - PM call to request a node with specific capabilities.
+ * @nid: Node id of the slave.
+ * @capabilities: Requested capabilities of the slave.
+ * @qos: Quality of service (not supported).
+ * @ack: Flag to specify whether acknowledge is requested.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_req_node(enum pm_node_id nid,
 			       uint32_t capabilities,
@@ -467,15 +477,16 @@
 }
 
 /**
- * pm_set_requirement() - PM call to set requirement for PM slaves
- * @nid		Node id of the slave
- * @capabilities Requested capabilities of the slave
- * @qos		Quality of service (not supported)
- * @ack		Flag to specify whether acknowledge is requested
+ * pm_set_requirement() - PM call to set requirement for PM slaves.
+ * @nid: Node id of the slave.
+ * @capabilities: Requested capabilities of the slave.
+ * @qos: Quality of service (not supported).
+ * @ack: Flag to specify whether acknowledge is requested.
  *
- * This API function is to be used for slaves a PU already has requested
+ * This API function is to be used for slaves a PU already has requested.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
 				      uint32_t capabilities,
@@ -497,10 +508,11 @@
 /* Miscellaneous API functions */
 
 /**
- * pm_get_api_version() - Get version number of PMU PM firmware
- * @version	Returns 32-bit version number of PMU Power Management Firmware
+ * pm_get_api_version() - Get version number of PMU PM firmware.
+ * @version: Returns 32-bit version number of PMU Power Management Firmware.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_get_api_version(uint32_t *version)
 {
@@ -512,14 +524,15 @@
 }
 
 /**
- * pm_get_node_status() - PM call to request a node's current status
- * @nid		Node id
- * @ret_buff	Buffer for the return values:
- *		[0] - Current power state of the node
- *		[1] - Current requirements for the node (slave nodes only)
- *		[2] - Current usage status for the node (slave nodes only)
+ * pm_get_node_status() - PM call to request a node's current status.
+ * @nid: Node id.
+ * @ret_buff: Buffer for the return values
+ *            [0] - Current power state of the node
+ *            [1] - Current requirements for the node (slave nodes only)
+ *            [2] - Current usage status for the node (slave nodes only)
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
 				      uint32_t *ret_buff)
@@ -531,15 +544,16 @@
 }
 
 /**
- * pm_mmio_write() - Perform write to protected mmio
- * @address	Address to write to
- * @mask	Mask to apply
- * @value	Value to write
+ * pm_mmio_write() - Perform write to protected mmio.
+ * @address: Address to write to.
+ * @mask: Mask to apply.
+ * @value: Value to write.
  *
  * This function provides access to PM-related control registers
  * that may not be directly accessible by a particular PU.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_mmio_write(uintptr_t address,
 				 uint32_t mask,
@@ -553,14 +567,15 @@
 }
 
 /**
- * pm_mmio_read() - Read value from protected mmio
- * @address	Address to write to
- * @value	Value to write
+ * pm_mmio_read() - Read value from protected mmio.
+ * @address: Address to write to.
+ * @value: Value to write.
  *
  * This function provides access to PM-related control registers
  * that may not be directly accessible by a particular PU.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
 {
@@ -572,18 +587,16 @@
 }
 
 /**
- * pm_fpga_load() - Load the bitstream into the PL.
+ * pm_fpga_load() - Load the bitstream into the PL. This function provides
+ *                  access to the xilfpga library to load the Bit-stream
+ *                  into PL.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @size: Number of 32bit words.
+ * @flags: Additional flags or settings for the fpga operation.
  *
- * This function provides access to the xilfpga library to load
- * the Bit-stream into PL.
+ * Return: Returns status, either success or error+reason.
  *
- * address_low: lower 32-bit Linear memory space address
- *
- * address_high: higher 32-bit Linear memory space address
- *
- * size:	Number of 32bit words
- *
- * @return      Returns status, either success or error+reason
  */
 enum pm_ret_status pm_fpga_load(uint32_t address_low,
 				uint32_t address_high,
@@ -599,12 +612,14 @@
 }
 
 /**
- * pm_fpga_get_status() - Read value from fpga status register
- * @value       Value to read
+ * pm_fpga_get_status() - Read value from fpga status register.
+ * @value: Value to read.
  *
  * This function provides access to the xilfpga library to get
- * the fpga status
- * @return      Returns status, either success or error+reason
+ * the fpga status.
+ *
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_fpga_get_status(uint32_t *value)
 {
@@ -616,11 +631,11 @@
 }
 
 /**
- * pm_get_chipid() - Read silicon ID registers
- * @value       Buffer for return values. Must be large enough
- *		to hold 8 bytes.
+ * pm_get_chipid() - Read silicon ID registers.
+ * @value: Buffer for return values. Must be large enough to hold 8 bytes.
  *
- * @return      Returns silicon ID registers
+ * Return: Returns silicon ID registers.
+ *
  */
 enum pm_ret_status pm_get_chipid(uint32_t *value)
 {
@@ -633,17 +648,16 @@
 
 /**
  * pm_secure_rsaaes() - Load the secure images.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @size: Number of 32bit words.
+ * @flags: Additional flags or settings for the fpga operation.
  *
- * This function provides access to the xilsecure library to load
- * the authenticated, encrypted, and authenticated/encrypted images.
+ * This function provides access to the xilsecure library to load the
+ * authenticated, encrypted, and authenticated/encrypted images.
  *
- * address_low: lower 32-bit Linear memory space address
+ * Return: Returns status, either success or error+reason.
  *
- * address_high: higher 32-bit Linear memory space address
- *
- * size:	Number of 32bit words
- *
- * @return      Returns status, either success or error+reason
  */
 enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
 				uint32_t address_high,
@@ -659,17 +673,16 @@
 }
 
 /**
- * pm_aes_engine() - Aes data blob encryption/decryption
+ * pm_aes_engine() - Aes data blob encryption/decryption.
+ * @address_low: lower 32-bit address of the AesParams structure.
+ * @address_high: higher 32-bit address of the AesParams structure.
+ * @value: Returned output value.
+ *
  * This function provides access to the xilsecure library to
  * encrypt/decrypt data blobs.
  *
- * address_low: lower 32-bit address of the AesParams structure
+ * Return: Returns status, either success or error+reason.
  *
- * address_high: higher 32-bit address of the AesParams structure
- *
- * value:        Returned output value
- *
- * @return       Returns status, either success or error+reason
  */
 enum pm_ret_status pm_aes_engine(uint32_t address_high,
 				 uint32_t address_low,
@@ -683,11 +696,13 @@
 }
 
 /**
- * pm_get_callbackdata() - Read from IPI response buffer
- * @data - array of PAYLOAD_ARG_CNT elements
+ * pm_get_callbackdata() - Read from IPI response buffer.
+ * @data: array of PAYLOAD_ARG_CNT elements.
+ * @count: Number of values to return.
  *
  * Read value from ipi buffer response buffer.
- * @return      Returns status, either success or error
+ * Return: Returns status, either success or error.
+ *
  */
 enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
 {
@@ -703,16 +718,17 @@
 }
 
 /**
- * pm_ioctl() -  PM IOCTL API for device control and configs
- * @node_id	Node ID of the device
- * @ioctl_id	ID of the requested IOCTL
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @out		Returned output value
+ * pm_ioctl() - PM IOCTL API for device control and configs.
+ * @nid: Node ID of the device.
+ * @ioctl_id: ID of the requested IOCTL.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @value: Returned output value.
  *
  * This function calls IOCTL to firmware for device control and configuration.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
 			    uint32_t ioctl_id,
@@ -724,12 +740,13 @@
 }
 
 /**
- * fw_api_version() - Returns API version implemented in firmware
- * @api_id	API ID to check
- * @version	Returned supported API version
- * @len		Number of words to be returned
+ * fw_api_version() - Returns API version implemented in firmware.
+ * @id: API ID to check.
+ * @version: Returned supported API version.
+ * @len: Number of words to be returned.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version,
 					 uint32_t len)
@@ -741,10 +758,11 @@
 }
 
 /**
- * check_api_dependency() -  API to check dependent EEMI API version
- * @id		EEMI API ID to check
+ * check_api_dependency() -  API to check dependent EEMI API version.
+ * @id: EEMI API ID to check.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status check_api_dependency(uint8_t id)
 {
@@ -775,11 +793,13 @@
 }
 
 /**
- * feature_check_tfa() - These are API's completely implemented in TF-A
- * @api_id	API ID to check
- * @version	Returned supported API version
+ * feature_check_tfa() - These are API's completely implemented in TF-A.
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
+ * @bit_mask: Returned supported IOCTL id version.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status feature_check_tfa(uint32_t api_id, uint32_t *version,
 					    uint32_t *bit_mask)
@@ -801,12 +821,13 @@
 }
 
 /**
- * get_tfa_version_for_partial_apis() - Return TF-A version for partially
- * implemented APIs
- * @api_id	API ID to check
- * @version	Returned supported API version
+ * get_tfa_version_for_partial_apis() - Return TF-A version for partially.
+ *                                      implemented APIs
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status get_tfa_version_for_partial_apis(uint32_t api_id,
 							   uint32_t *version)
@@ -842,11 +863,12 @@
 
 /**
  * feature_check_partial() - These are API's partially implemented in
- * TF-A and firmware both
- * @api_id	API ID to check
- * @version	Returned supported API version
+ *                           TF-A and firmware both.
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status feature_check_partial(uint32_t api_id,
 						uint32_t *version)
@@ -884,13 +906,14 @@
 }
 
 /**
- * pm_feature_check() - Returns the supported API version if supported
- * @api_id	API ID to check
- * @version	Returned supported API version
- * @bit_mask	Returned supported IOCTL id version
- * @len		Number of bytes to be returned in bit_mask variable
+ * pm_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @version: Returned supported API version.
+ * @bit_mask: Returned supported IOCTL id version.
+ * @len: Number of bytes to be returned in bit_mask variable.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
 				    uint32_t *bit_mask, uint8_t len)
@@ -940,14 +963,15 @@
 }
 
 /**
- * pm_clock_get_max_divisor - PM call to get max divisor
- * @clock_id	Clock ID
- * @div_type	Divisor ID (TYPE_DIV1 or TYPE_DIV2)
- * @max_div	Maximum supported divisor
+ * pm_clock_get_max_divisor - PM call to get max divisor.
+ * @clock_id: Clock ID.
+ * @div_type: Divisor ID (TYPE_DIV1 or TYPE_DIV2).
+ * @max_div: Maximum supported divisor.
  *
  * This function is used by master to get maximum supported value.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
 						   uint8_t div_type,
@@ -957,12 +981,13 @@
 }
 
 /**
- * pm_clock_get_num_clocks - PM call to request number of clocks
- * @nclockss: Number of clocks
+ * pm_clock_get_num_clocks - PM call to request number of clocks.
+ * @nclocks: Number of clocks.
  *
  * This function is used by master to get number of clocks.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
 {
@@ -970,12 +995,13 @@
 }
 
 /**
- * pm_clock_get_name() - PM call to request a clock's name
- * @clock_id	Clock ID
- * @name	Name of clock (max 16 bytes)
+ * pm_clock_get_name() - PM call to request a clock's name.
+ * @clock_id: Clock ID.
+ * @name: Name of clock (max 16 bytes).
  *
  * This function is used by master to get nmae of clock specified
  * by given clock ID.
+ *
  */
 static void pm_clock_get_name(uint32_t clock_id, char *name)
 {
@@ -983,17 +1009,18 @@
 }
 
 /**
- * pm_clock_get_topology() - PM call to request a clock's topology
- * @clock_id	Clock ID
- * @index	Topology index for next toplogy node
- * @topology	Buffer to store nodes in topology and flags
+ * pm_clock_get_topology() - PM call to request a clock's topology.
+ * @clock_id: Clock ID.
+ * @index: Topology index for next toplogy node.
+ * @topology: Buffer to store nodes in topology and flags.
  *
  * This function is used by master to get topology information for the
  * clock specified by given clock ID. Each response would return 3
  * topology nodes. To get next nodes, caller needs to call this API with
  * index of next node. Index starts from 0.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
 						uint32_t index,
@@ -1004,15 +1031,16 @@
 
 /**
  * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
- *				 parameters for fixed clock
- * @clock_id	Clock ID
- * @mul		Multiplication value
- * @div		Divisor value
+ *                                     parameters for fixed clock.
+ * @clock_id: Clock ID.
+ * @mul: Multiplication value.
+ * @div: Divisor value.
  *
  * This function is used by master to get fixed factor parameers for the
  * fixed clock. This API is application only for the fixed clock.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
 							  uint32_t *mul,
@@ -1022,10 +1050,10 @@
 }
 
 /**
- * pm_clock_get_parents() - PM call to request a clock's first 3 parents
- * @clock_id	Clock ID
- * @index	Index of next parent
- * @parents	Parents of the given clock
+ * pm_clock_get_parents() - PM call to request a clock's first 3 parents.
+ * @clock_id: Clock ID.
+ * @index: Index of next parent.
+ * @parents: Parents of the given clock.
  *
  * This function is used by master to get clock's parents information.
  * This API will return 3 parents with a single response. To get other
@@ -1036,7 +1064,8 @@
  * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
  * so on.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
 					       uint32_t index,
@@ -1046,14 +1075,15 @@
 }
 
 /**
- * pm_clock_get_attributes() - PM call to request a clock's attributes
- * @clock_id	Clock ID
- * @attr	Clock attributes
+ * pm_clock_get_attributes() - PM call to request a clock's attributes.
+ * @clock_id: Clock ID.
+ * @attr: Clock attributes.
  *
  * This function is used by master to get clock's attributes
  * (e.g. valid, clock type, etc).
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
 						  uint32_t *attr)
@@ -1062,12 +1092,13 @@
 }
 
 /**
- * pm_clock_gate() - Configure clock gate
- * @clock_id	Id of the clock to be configured
- * @enable	Flag 0=disable (gate the clock), !0=enable (activate the clock)
+ * pm_clock_gate() - Configure clock gate.
+ * @clock_id: Id of the clock to be configured.
+ * @enable: Flag 0=disable (gate the clock), !0=enable (activate the clock).
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
 					uint8_t enable)
@@ -1101,14 +1132,15 @@
 }
 
 /**
- * pm_clock_enable() - Enable the clock for given id
- * @clock_id: Id of the clock to be enabled
+ * pm_clock_enable() - Enable the clock for given id.
+ * @clock_id: Id of the clock to be enabled.
  *
  * This function is used by master to enable the clock
  * including peripherals and PLL clocks.
  *
- * @return:	Error if an argument is not valid or status as returned by the
- *		pm_clock_gate
+ * Return: Error if an argument is not valid or status as returned by the
+ *         pm_clock_gate.
+ *
  */
 enum pm_ret_status pm_clock_enable(uint32_t clock_id)
 {
@@ -1125,14 +1157,15 @@
 }
 
 /**
- * pm_clock_disable - Disable the clock for given id
- * @clock_id: Id of the clock to be disable
+ * pm_clock_disable - Disable the clock for given id.
+ * @clock_id: Id of the clock to be disable.
  *
  * This function is used by master to disable the clock
  * including peripherals and PLL clocks.
  *
- * @return:	Error if an argument is not valid or status as returned by the
- *		pm_clock_gate
+ * Return: Error if an argument is not valid or status as returned by the
+ *         pm_clock_gate
+ *
  */
 enum pm_ret_status pm_clock_disable(uint32_t clock_id)
 {
@@ -1149,14 +1182,15 @@
 }
 
 /**
- * pm_clock_getstate - Get the clock state for given id
- * @clock_id: Id of the clock to be queried
- * @state: 1/0 (Enabled/Disabled)
+ * pm_clock_getstate - Get the clock state for given id.
+ * @clock_id: Id of the clock to be queried.
+ * @state: 1/0 (Enabled/Disabled).
  *
  * This function is used by master to get the state of clock
  * including peripherals and PLL clocks.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
 				     uint32_t *state)
@@ -1182,14 +1216,15 @@
 }
 
 /**
- * pm_clock_setdivider - Set the clock divider for given id
- * @clock_id: Id of the clock
- * @divider: divider value
+ * pm_clock_setdivider - Set the clock divider for given id.
+ * @clock_id: Id of the clock.
+ * @divider: divider value.
  *
  * This function is used by master to set divider for any clock
  * to achieve desired rate.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
 				       uint32_t divider)
@@ -1230,14 +1265,15 @@
 }
 
 /**
- * pm_clock_getdivider - Get the clock divider for given id
- * @clock_id: Id of the clock
- * @divider: divider value
+ * pm_clock_getdivider - Get the clock divider for given id.
+ * @clock_id: Id of the clock.
+ * @divider: divider value.
  *
  * This function is used by master to get divider values
  * for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
 				       uint32_t *divider)
@@ -1285,13 +1321,14 @@
 }
 
 /**
- * pm_clock_setrate - Set the clock rate for given id
- * @clock_id: Id of the clock
- * @rate: rate value in hz
+ * pm_clock_setrate - Set the clock rate for given id.
+ * @clock_id: Id of the clock.
+ * @rate: rate value in hz.
  *
  * This function is used by master to set rate for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
 				    uint64_t rate)
@@ -1300,14 +1337,15 @@
 }
 
 /**
- * pm_clock_getrate - Get the clock rate for given id
- * @clock_id: Id of the clock
- * @rate: rate value in hz
+ * pm_clock_getrate - Get the clock rate for given id.
+ * @clock_id: Id of the clock.
+ * @rate: rate value in hz.
  *
  * This function is used by master to get rate
  * for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
 				    uint64_t *rate)
@@ -1316,13 +1354,14 @@
 }
 
 /**
- * pm_clock_setparent - Set the clock parent for given id
- * @clock_id: Id of the clock
- * @parent_index: Index of the parent clock into clock's parents array
+ * pm_clock_setparent - Set the clock parent for given id.
+ * @clock_id: Id of the clock.
+ * @parent_index: Index of the parent clock into clock's parents array.
  *
  * This function is used by master to set parent for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
 				      uint32_t parent_index)
@@ -1349,14 +1388,15 @@
 }
 
 /**
- * pm_clock_getparent - Get the clock parent for given id
- * @clock_id: Id of the clock
- * @parent_index: parent index
+ * pm_clock_getparent - Get the clock parent for given id.
+ * @clock_id: Id of the clock.
+ * @parent_index: parent index.
  *
  * This function is used by master to get parent index
  * for any clock.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
 				      uint32_t *parent_index)
@@ -1383,12 +1423,13 @@
 }
 
 /**
- * pm_pinctrl_get_num_pins - PM call to request number of pins
- * @npins: Number of pins
+ * pm_pinctrl_get_num_pins - PM call to request number of pins.
+ * @npins: Number of pins.
  *
- * This function is used by master to get number of pins
+ * This function is used by master to get number of pins.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
 {
@@ -1396,12 +1437,13 @@
 }
 
 /**
- * pm_pinctrl_get_num_functions - PM call to request number of functions
- * @nfuncs: Number of functions
+ * pm_pinctrl_get_num_functions - PM call to request number of functions.
+ * @nfuncs: Number of functions.
  *
- * This function is used by master to get number of functions
+ * This function is used by master to get number of functions.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
 {
@@ -1410,14 +1452,15 @@
 
 /**
  * pm_pinctrl_get_num_function_groups - PM call to request number of
- *					function groups
- * @fid: Id of function
- * @ngroups: Number of function groups
+ *                                      function groups.
+ * @fid: Id of function.
+ * @ngroups: Number of function groups.
  *
  * This function is used by master to get number of function groups specified
- * by given function Id
+ * by given function Id.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
 							     uint32_t *ngroups)
@@ -1426,12 +1469,13 @@
 }
 
 /**
- * pm_pinctrl_get_function_name - PM call to request function name
- * @fid: Id of function
- * @name: Name of function
+ * pm_pinctrl_get_function_name - PM call to request function name.
+ * @fid: Id of function.
+ * @name: Name of function.
  *
  * This function is used by master to get name of function specified
- * by given function Id
+ * by given function Id.
+ *
  */
 static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
 {
@@ -1439,10 +1483,10 @@
 }
 
 /**
- * pm_pinctrl_get_function_groups - PM call to request function groups
- * @fid: Id of function
- * @index: Index of next function groups
- * @groups: Function groups
+ * pm_pinctrl_get_function_groups - PM call to request function groups.
+ * @fid: Id of function.
+ * @index: Index of next function groups.
+ * @groups: Function groups.
  *
  * This function is used by master to get function groups specified
  * by given function Id. This API will return 6 function groups with
@@ -1454,6 +1498,7 @@
  * function groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
 							 uint32_t index,
@@ -1463,10 +1508,10 @@
 }
 
 /**
- * pm_pinctrl_get_pin_groups - PM call to request pin groups
- * @pin_id: Id of pin
- * @index: Index of next pin groups
- * @groups: pin groups
+ * pm_pinctrl_get_pin_groups - PM call to request pin groups.
+ * @pin_id: Id of pin.
+ * @index: Index of next pin groups.
+ * @groups: pin groups.
  *
  * This function is used by master to get pin groups specified
  * by given pin Id. This API will return 6 pin groups with
@@ -1478,6 +1523,7 @@
  * pin groups 6, 7, 8, 9, 10 and 11 and so on.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
 						    uint32_t index,
@@ -1487,14 +1533,15 @@
 }
 
 /**
- * pm_query_data() -  PM API for querying firmware data
- * @arg1	Argument 1 to requested IOCTL call
- * @arg2	Argument 2 to requested IOCTL call
- * @arg3	Argument 3 to requested IOCTL call
- * @arg4	Argument 4 to requested IOCTL call
- * @data	Returned output data
+ * pm_query_data() - PM API for querying firmware data.
+ * @qid:  represents the query identifiers for PM.
+ * @arg1: Argument 1 to requested IOCTL call.
+ * @arg2: Argument 2 to requested IOCTL call.
+ * @arg3: Argument 3 to requested IOCTL call.
+ * @data: Returned output data.
  *
  * This function returns requested data.
+ *
  */
 void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
 		   uint32_t arg3, uint32_t *data)
@@ -1591,20 +1638,20 @@
 }
 
 /**
- * pm_fpga_read - Perform the fpga configuration readback
- *
- * @reg_numframes: Configuration register offset (or) Number of frames to read
- * @address_low: lower 32-bit Linear memory space address
- * @address_high: higher 32-bit Linear memory space address
- * @readback_type: Type of fpga readback operation
- *		   0 -- Configuration Register readback
- *		   1 -- Configuration Data readback
- * @value:	Value to read
+ * pm_fpga_read - Perform the fpga configuration readback.
+ * @reg_numframes: Configuration register offset (or) Number of frames to read.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @readback_type: Type of fpga readback operation.
+ *		   0 -- Configuration Register readback.
+ *		   1 -- Configuration Data readback.
+ * @value: Value to read.
  *
  * This function provides access to the xilfpga library to read
  * the PL configuration.
  *
  * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
 				uint32_t address_low,
@@ -1621,16 +1668,17 @@
 }
 
 /*
- * pm_pll_set_parameter() - Set the PLL parameter value
- * @nid		Node id of the target PLL
- * @param_id	ID of the PLL parameter
- * @value	Parameter value to be set
+ * pm_pll_set_parameter() - Set the PLL parameter value.
+ * @nid: Node id of the target PLL.
+ * @param_id: ID of the PLL parameter.
+ * @value: Parameter value to be set.
  *
  * Setting the parameter will have physical effect once the PLL mode is set to
  * integer or fractional.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
 					enum pm_pll_param param_id,
@@ -1654,13 +1702,14 @@
 }
 
 /**
- * pm_pll_get_parameter() - Get the PLL parameter value
- * @nid		Node id of the target PLL
- * @param_id	ID of the PLL parameter
- * @value	Location to store the parameter value
+ * pm_pll_get_parameter() - Get the PLL parameter value.
+ * @nid: Node id of the target PLL.
+ * @param_id: ID of the PLL parameter.
+ * @value: Location to store the parameter value.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
 					enum pm_pll_param param_id,
@@ -1684,17 +1733,18 @@
 }
 
 /**
- * pm_pll_set_mode() - Set the PLL mode
- * @nid		Node id of the target PLL
- * @mode	PLL mode to be set
+ * pm_pll_set_mode() - Set the PLL mode.
+ * @nid: Node id of the target PLL.
+ * @mode: PLL mode to be set.
  *
  * If reset mode is set the PM controller will first bypass the PLL and then
  * assert the reset. If integer or fractional mode is set the PM controller will
  * ensure that the complete PLL programming sequence is satisfied. After this
  * function returns success the PLL is locked and its bypass is deasserted.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
 {
@@ -1716,12 +1766,13 @@
 }
 
 /**
- * pm_pll_get_mode() - Get the PLL mode
- * @nid		Node id of the target PLL
- * @mode	Location to store the mode of the PLL
+ * pm_pll_get_mode() - Get the PLL mode.
+ * @nid: Node id of the target PLL.
+ * @mode: Location to store the mode of the PLL.
  *
- * @return	Error if an argument is not valid or status as returned by the
- *		PM controller (PMU)
+ * Return: Error if an argument is not valid or status as returned by the
+ *         PM controller (PMU).
+ *
  */
 enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
 {
@@ -1738,21 +1789,17 @@
 }
 
 /**
- * pm_register_access() -  PM API for register read/write access data
- *
- * @register_access_id	Register_access_id which says register read/write
- *
- * @address		Address of the register to be accessed
- *
- * @mask		Mask value to be used while writing value
- *
- * @value		Value to be written to register
- *
- * @out			Returned output data
+ * pm_register_access() -  PM API for register read/write access data.
+ * @register_access_id: Register_access_id which says register read/write.
+ * @address: Address of the register to be accessed.
+ * @mask: Mask value to be used while writing value.
+ * @value: Value to be written to register.
+ * @out: Returned output data.
  *
  * This function returns requested data.
  *
- * @return	Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
+ *
  */
 enum pm_ret_status pm_register_access(uint32_t register_access_id,
 				      uint32_t address,
@@ -1785,17 +1832,14 @@
 }
 
 /**
- * pm_efuse_access() - To program or read efuse bits.
+ * pm_efuse_access() - To program or read efuse bits. This function provides
+ *                     access to the xilskey library to program/read
+ *                     efuse bits.
+ * @address_low: lower 32-bit Linear memory space address.
+ * @address_high: higher 32-bit Linear memory space address.
+ * @value: Returned output value.
  *
- * This function provides access to the xilskey library to program/read
- * efuse bits.
- *
- * address_low: lower 32-bit Linear memory space address
- * address_high: higher 32-bit Linear memory space address
- *
- * value: Returned output value
- *
- * @return  Returns status, either success or error+reason
+ * Return: Returns status, either success or error+reason.
  *
  */
 enum pm_ret_status pm_efuse_access(uint32_t address_high,
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
index 2baad3d..a2597bc 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.h
@@ -35,7 +35,7 @@
 	CONFIG_REG_READ,
 };
 
-/**
+/*
  * Assigning of argument values into array elements.
  */
 #define PM_PACK_PAYLOAD1(pl, arg0) {	\
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
index 6dff07e..af75c5c 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_defs.h
@@ -23,9 +23,10 @@
 
 #define PM_VERSION	((PM_VERSION_MAJOR << 16U) | PM_VERSION_MINOR)
 
-/**
+/*
  * PM API versions
  */
+
 /* Expected version of firmware APIs */
 #define FW_API_BASE_VERSION		(1U)
 /* Expected version of firmware API for feature check */
@@ -153,9 +154,11 @@
 };
 
 /**
- * @PM_INITIAL_BOOT:	boot is a fresh system startup
- * @PM_RESUME:		boot is a resume
- * @PM_BOOT_ERROR:	error, boot cause cannot be identified
+ * enum pm_boot_status - enum represents the boot status of the PM.
+ * @PM_INITIAL_BOOT: boot is a fresh system startup.
+ * @PM_RESUME: boot is a resume.
+ * @PM_BOOT_ERROR: error, boot cause cannot be identified.
+ *
  */
 enum pm_boot_status {
 	PM_INITIAL_BOOT,
@@ -164,9 +167,11 @@
 };
 
 /**
- * @PMF_SHUTDOWN_TYPE_SHUTDOWN:		shutdown
- * @PMF_SHUTDOWN_TYPE_RESET:		reset/reboot
- * @PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY:	set the shutdown/reboot scope
+ * enum pm_shutdown_type - enum represents the shutdown type of the PM.
+ * @PMF_SHUTDOWN_TYPE_SHUTDOWN: shutdown.
+ * @PMF_SHUTDOWN_TYPE_RESET: reset/reboot.
+ * @PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY: set the shutdown/reboot scope.
+ *
  */
 enum pm_shutdown_type {
 	PMF_SHUTDOWN_TYPE_SHUTDOWN,
@@ -175,9 +180,11 @@
 };
 
 /**
- * @PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM:	shutdown/reboot APU subsystem only
- * @PMF_SHUTDOWN_SUBTYPE_PS_ONLY:	shutdown/reboot entire PS (but not PL)
- * @PMF_SHUTDOWN_SUBTYPE_SYSTEM:	shutdown/reboot entire system
+ * enum pm_shutdown_subtype - enum represents the shutdown subtype of the PM.
+ * @PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM: shutdown/reboot APU subsystem only.
+ * @PMF_SHUTDOWN_SUBTYPE_PS_ONLY: shutdown/reboot entire PS (but not PL).
+ * @PMF_SHUTDOWN_SUBTYPE_SYSTEM: shutdown/reboot entire system.
+ *
  */
 enum pm_shutdown_subtype {
 	PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM,
@@ -186,9 +193,11 @@
 };
 
 /**
- * @PM_PLL_MODE_RESET:		PLL is in reset (not locked)
- * @PM_PLL_MODE_INTEGER:	PLL is locked in integer mode
- * @PM_PLL_MODE_FRACTIONAL:	PLL is locked in fractional mode
+ * enum pm_pll_mode - enum represents the mode of the PLL.
+ * @PM_PLL_MODE_RESET: PLL is in reset (not locked).
+ * @PM_PLL_MODE_INTEGER: PLL is locked in integer mode.
+ * @PM_PLL_MODE_FRACTIONAL: PLL is locked in fractional mode.
+ * @PM_PLL_MODE_MAX: Represents the maximum mode value for the PLL.
  */
 enum pm_pll_mode {
 	PM_PLL_MODE_RESET,
@@ -198,8 +207,10 @@
 };
 
 /**
- * @PM_CLOCK_DIV0_ID:		Clock divider 0
- * @PM_CLOCK_DIV1_ID:		Clock divider 1
+ * enum pm_clock_div_id - enum represents the clock division identifiers in the
+ *                        PM.
+ * @PM_CLOCK_DIV0_ID: Clock divider 0.
+ * @PM_CLOCK_DIV1_ID: Clock divider 1.
  */
 enum pm_clock_div_id {
 	PM_CLOCK_DIV0_ID,
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 54b0007..fc9290c 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -36,22 +36,26 @@
 #endif
 
 /**
- * pm_context - Structure which contains data for power management
- * @api_version		version of PM API, must match with one on PMU side
- * @payload		payload array used to store received
- *			data from ipi buffer registers
+ * typedef pm_ctx_t - Structure which contains data for power management.
+ * @api_version: version of PM API, must match with one on PMU side.
+ * @payload: payload array used to store received.
+ *           data from ipi buffer registers.
+ *
  */
-static struct {
+typedef struct {
 	uint32_t api_version;
 	uint32_t payload[PAYLOAD_ARG_CNT];
-} pm_ctx;
+} pm_ctx_t;
+
+static pm_ctx_t pm_ctx;
 
 #if ZYNQMP_WDT_RESTART
 /**
- * trigger_wdt_restart() - Trigger warm restart event to APU cores
+ * trigger_wdt_restart() - Trigger warm restart event to APU cores.
  *
  * This function triggers SGI for all active APU CPUs. SGI handler then
  * power down CPU and call system reset.
+ *
  */
 static void trigger_wdt_restart(void)
 {
@@ -83,15 +87,15 @@
 }
 
 /**
- * ttc_fiq_handler() - TTC Handler for timer event
- * @id         number of the highest priority pending interrupt of the type
- *             that this handler was registered for
- * @flags      security state, bit[0]
- * @handler    pointer to 'cpu_context' structure of the current CPU for the
- *             security state specified in the 'flags' parameter
- * @cookie     unused
+ * ttc_fiq_handler() - TTC Handler for timer event.
+ * @id: number of the highest priority pending interrupt of the type
+ *      that this handler was registered for.
+ * @flags: security state, bit[0].
+ * @handle: pointer to 'cpu_context' structure of the current CPU for the
+ *           security state specified in the 'flags' parameter.
+ * @cookie: unused.
  *
- * Function registered as INTR_TYPE_EL3 interrupt handler
+ * Function registered as INTR_TYPE_EL3 interrupt handler.
  *
  * When WDT event is received in PMU, PMU needs to notify master to do cleanup
  * if required. PMU sets up timer and starts timer to overflow in zero time upon
@@ -101,6 +105,9 @@
  * In presence of non-secure software layers (EL1/2) sets the interrupt
  * at registered entrance in GIC and informs that PMU responded or demands
  * action.
+ *
+ * Return: 0 on success.
+ *
  */
 static uint64_t ttc_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 				void *cookie)
@@ -121,19 +128,21 @@
 }
 
 /**
- * zynqmp_sgi7_irq() - Handler for SGI7 IRQ
- * @id         number of the highest priority pending interrupt of the type
- *             that this handler was registered for
- * @flags      security state, bit[0]
- * @handler    pointer to 'cpu_context' structure of the current CPU for the
- *             security state specified in the 'flags' parameter
- * @cookie     unused
+ * zynqmp_sgi7_irq() - Handler for SGI7 IRQ.
+ * @id: number of the highest priority pending interrupt of the type
+ *      that this handler was registered for.
+ * @flags: security state, bit[0].
+ * @handle: pointer to 'cpu_context' structure of the current CPU for the
+ *           security state specified in the 'flags' parameter.
+ * @cookie: unused.
  *
  * Function registered as INTR_TYPE_EL3 interrupt handler
  *
  * On receiving WDT event from PMU, TF-A generates SGI7 to all running CPUs.
  * In response to SGI7 interrupt, each CPUs do clean up if required and last
  * running CPU calls system restart.
+ *
+ * Return: This function does not return a value and it enters into wfi.
  */
 static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags,
 						 void *handle, void *cookie)
@@ -168,7 +177,9 @@
 }
 
 /**
- * pm_wdt_restart_setup() - Setup warm restart interrupts
+ * pm_wdt_restart_setup() - Setup warm restart interrupts.
+ *
+ * Return: Returns status, 0 on success or error+reason.
  *
  * This function sets up handler for SGI7 and TTC interrupts
  * used for warm restart.
@@ -194,17 +205,18 @@
 #endif
 
 /**
- * pm_setup() - PM service setup
+ * pm_setup() - PM service setup.
  *
- * @return	On success, the initialization function must return 0.
- *		Any other return value will cause the framework to ignore
- *		the service
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
  *
  * Initialization functions for ZynqMP power management for
  * communicaton with PMU.
  *
  * Called from sip_svc_setup initialization function with the
  * rt_svc_init signature.
+ *
  */
 int32_t pm_setup(void)
 {
@@ -249,19 +261,24 @@
 
 /**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - Arguments
- * @cookie  - Unused
- * @handler - Pointer to caller's context structure
- *
- * @return  - Unused
+ * @smc_fid: Function Identifier.
+ * @x1: Arguments.
+ * @x2: Arguments.
+ * @x3: Arguments.
+ * @x4: Arguments.
+ * @cookie: Unused.
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * Determines that smc_fid is valid and supported PM SMC Function ID from the
  * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
+ * the unknown SMC Function ID.
  *
  * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * function with rt_svc_handle signature.
+ *
+ * Return: Unused.
+ *
  */
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 7ddd28c..6a8555e 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -40,9 +40,13 @@
 	0xb9, 0x25, 0x82, 0x2d, 0xe3, 0xa5);
 
 /**
- * sip_svc_setup() - Setup SiP Service
+ * sip_svc_setup() - Setup SiP Service.
  *
- * Invokes PM setup
+ * Return: On success, the initialization function must return 0.
+ *         Any other return value will cause the framework to ignore
+ *         the service.
+ *
+ * Invokes PM setup.
  */
 static int32_t sip_svc_setup(void)
 {
@@ -52,9 +56,19 @@
 
 /**
  * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ * @smc_fid: Function Identifier.
+ * @x1: SMC64 Arguments 1 from kernel.
+ * @x2: SMC64 Arguments 2 from kernel.
+ * @x3: SMC64 Arguments 3 from kernel(upper 32-bits).
+ * @x4: SMC64 Arguments 4 from kernel.
+ * @cookie: Unused
+ * @handle: Pointer to caller's context structure.
+ * @flags: SECURE_FLAG or NON_SECURE_FLAG.
  *
  * Handler for all SiP SMC calls. Handles standard SIP requests
  * and calls PM SMC handler if the call is for a PM-API function.
+ *
+ * Return: Unused.
  */
 static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 			      u_register_t x1,
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index c7d2c08..439bd6f 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -85,7 +85,7 @@
 };
 
 /**
- * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data
+ * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data.
  *
  */
 void zynqmp_ipi_config_table_init(void)
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index 61afee3..13875b9 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -131,6 +131,9 @@
 
 	/* Track the current runtime model of the SP. */
 	enum sp_runtime_model rt_model;
+
+	/* Track the source partition ID to validate a direct response. */
+	uint16_t dir_req_origin_id;
 };
 
 /*
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 08e7218..ada6f45 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -260,6 +260,65 @@
 }
 
 /*******************************************************************************
+ * Helper function to validate the destination ID of a direct response.
+ ******************************************************************************/
+static bool direct_msg_validate_dst_id(uint16_t dst_id)
+{
+	struct secure_partition_desc *sp;
+
+	/* Check if we're targeting a normal world partition. */
+	if (ffa_is_normal_world_id(dst_id)) {
+		return true;
+	}
+
+	/* Or directed to the SPMC itself.*/
+	if (dst_id == FFA_SPMC_ID) {
+		return true;
+	}
+
+	/* Otherwise ensure the SP exists. */
+	sp = spmc_get_sp_ctx(dst_id);
+	if (sp != NULL) {
+		return true;
+	}
+
+	return false;
+}
+
+/*******************************************************************************
+ * Helper function to validate the response from a Logical Partition.
+ ******************************************************************************/
+static bool direct_msg_validate_lp_resp(uint16_t origin_id, uint16_t lp_id,
+					void *handle)
+{
+	/* Retrieve populated Direct Response Arguments. */
+	uint64_t x1 = SMC_GET_GP(handle, CTX_GPREG_X1);
+	uint64_t x2 = SMC_GET_GP(handle, CTX_GPREG_X2);
+	uint16_t src_id = ffa_endpoint_source(x1);
+	uint16_t dst_id = ffa_endpoint_destination(x1);
+
+	if (src_id != lp_id) {
+		ERROR("Invalid EL3 LP source ID (0x%x).\n", src_id);
+		return false;
+	}
+
+	/*
+	 * Check the destination ID is valid and ensure the LP is responding to
+	 * the original request.
+	 */
+	if ((!direct_msg_validate_dst_id(dst_id)) || (dst_id != origin_id)) {
+		ERROR("Invalid EL3 LP destination ID (0x%x).\n", dst_id);
+		return false;
+	}
+
+	if (!direct_msg_validate_arg2(x2)) {
+		ERROR("Invalid EL3 LP message encoding.\n");
+		return false;
+	}
+	return true;
+}
+
+/*******************************************************************************
  * Handle direct request messages and route to the appropriate destination.
  ******************************************************************************/
 static uint64_t direct_req_smc_handler(uint32_t smc_fid,
@@ -272,6 +331,7 @@
 				       void *handle,
 				       uint64_t flags)
 {
+	uint16_t src_id = ffa_endpoint_source(x1);
 	uint16_t dst_id = ffa_endpoint_destination(x1);
 	struct el3_lp_desc *el3_lp_descs;
 	struct secure_partition_desc *sp;
@@ -283,14 +343,29 @@
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
 
+	/* Validate Sender is either the current SP or from the normal world. */
+	if ((secure_origin && src_id != spmc_get_current_sp_ctx()->sp_id) ||
+		(!secure_origin && !ffa_is_normal_world_id(src_id))) {
+		ERROR("Invalid direct request source ID (0x%x).\n", src_id);
+		return spmc_ffa_error_return(handle,
+					FFA_ERROR_INVALID_PARAMETER);
+	}
+
 	el3_lp_descs = get_el3_lp_array();
 
 	/* Check if the request is destined for a Logical Partition. */
 	for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) {
 		if (el3_lp_descs[i].sp_id == dst_id) {
-			return el3_lp_descs[i].direct_req(
-					smc_fid, secure_origin, x1, x2, x3, x4,
-					cookie, handle, flags);
+			uint64_t ret = el3_lp_descs[i].direct_req(
+						smc_fid, secure_origin, x1, x2,
+						x3, x4, cookie, handle, flags);
+			if (!direct_msg_validate_lp_resp(src_id, dst_id,
+							 handle)) {
+				panic();
+			}
+
+			/* Message checks out. */
+			return ret;
 		}
 	}
 
@@ -332,6 +407,7 @@
 	 */
 	sp->ec[idx].rt_state = RT_STATE_RUNNING;
 	sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
+	sp->ec[idx].dir_req_origin_id = src_id;
 	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
 			       handle, cookie, flags, dst_id);
 }
@@ -370,7 +446,7 @@
 	 * Check that the response is either targeted to the Normal world or the
 	 * SPMC e.g. a PM response.
 	 */
-	if ((dst_id != FFA_SPMC_ID) && ffa_is_secure_world_id(dst_id)) {
+	if (!direct_msg_validate_dst_id(dst_id)) {
 		VERBOSE("Direct response to invalid partition ID (0x%x).\n",
 			dst_id);
 		return spmc_ffa_error_return(handle,
@@ -397,9 +473,18 @@
 		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
 	}
 
+	if (sp->ec[idx].dir_req_origin_id != dst_id) {
+		WARN("Invalid direct resp partition ID 0x%x != 0x%x on core%u.\n",
+		     dst_id, sp->ec[idx].dir_req_origin_id, idx);
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
 	/* Update the state of the SP execution context. */
 	sp->ec[idx].rt_state = RT_STATE_WAITING;
 
+	/* Clear the ongoing direct request ID. */
+	sp->ec[idx].dir_req_origin_id = INV_SP_ID;
+
 	/*
 	 * If the receiver is not the SPMC then forward the response to the
 	 * Normal world.
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
index d25344c..c7e864f 100644
--- a/services/std_svc/spm/el3_spmc/spmc_pm.c
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -83,6 +83,7 @@
 	/* Update the runtime model and state of the partition. */
 	ec->rt_model = RT_MODEL_INIT;
 	ec->rt_state = RT_STATE_RUNNING;
+	ec->dir_req_origin_id = INV_SP_ID;
 
 	INFO("SP (0x%x) init start on core%u.\n", sp->sp_id, linear_id);
 
@@ -132,6 +133,7 @@
 	/* Update the runtime model and state of the partition. */
 	ec->rt_model = RT_MODEL_DIR_REQ;
 	ec->rt_state = RT_STATE_RUNNING;
+	ec->dir_req_origin_id = FFA_SPMC_ID;
 
 	rc = spmc_sp_synchronous_entry(ec);
 	if (rc != 0ULL) {
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
index 15c7e91..5c3d580 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -777,16 +777,16 @@
 static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
 				uint32_t ffa_version)
 {
-	uint64_t total_page_count;
+	unsigned long long total_page_count;
 	const struct ffa_emad_v1_0 *first_emad;
 	const struct ffa_emad_v1_0 *end_emad;
 	size_t emad_size;
-	uint32_t comp_mrd_offset = 0;
+	uint32_t comp_mrd_offset;
 	size_t header_emad_size;
 	size_t size;
 	size_t count;
 	size_t expected_size;
-	struct ffa_comp_mrd *comp;
+	const struct ffa_comp_mrd *comp;
 
 	if (obj->desc_filled != obj->desc_size) {
 		ERROR("BUG: %s called on incomplete object (%zu != %zu)\n",
@@ -807,9 +807,7 @@
 	comp_mrd_offset = first_emad->comp_mrd_offset;
 
 	/* Loop through the endpoint descriptors, validating each of them. */
-	for (const struct ffa_emad_v1_0 *emad = first_emad;
-	     emad < end_emad;
-	     emad = emad_advance(emad, emad_size)) {
+	for (const struct ffa_emad_v1_0 *emad = first_emad; emad < end_emad;) {
 		ffa_endpoint_id16_t ep_id;
 
 		/*
@@ -836,6 +834,23 @@
 			       __func__, emad->comp_mrd_offset, comp_mrd_offset);
 			return FFA_ERROR_INVALID_PARAMETER;
 		}
+
+		/* Advance to the next endpoint descriptor */
+		emad = emad_advance(emad, emad_size);
+
+		/*
+		 * Ensure neither this emad nor any subsequent emads have
+		 * the same partition ID as the previous emad.
+		 */
+		for (const struct ffa_emad_v1_0 *other_emad = emad;
+		     other_emad < end_emad;
+		     other_emad = emad_advance(other_emad, emad_size)) {
+			if (ep_id == other_emad->mapd.endpoint_id) {
+				WARN("%s: Duplicated endpoint id 0x%x\n",
+				     __func__, emad->mapd.endpoint_id);
+				return FFA_ERROR_INVALID_PARAMETER;
+			}
+		}
 	}
 
 	header_emad_size = (size_t)((const uint8_t *)end_emad -
@@ -869,16 +884,18 @@
 	}
 	size -= comp_mrd_offset;
 
+	/* Check that there is enough space for the composite descriptor. */
 	if (size < sizeof(struct ffa_comp_mrd)) {
 		WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
 		     __func__, comp_mrd_offset, obj->desc_size);
 		return FFA_ERROR_INVALID_PARAMETER;
 	}
-	size -= sizeof(struct ffa_comp_mrd);
+	size -= sizeof(*comp);
 
 	count = size / sizeof(struct ffa_cons_mrd);
 
-	comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
+	comp = (const struct ffa_comp_mrd *)
+	       ((const uint8_t *)(&obj->desc) + comp_mrd_offset);
 
 	if (comp->address_range_count != count) {
 		WARN("%s: invalid object, desc count %u != %zu\n",
@@ -886,6 +903,7 @@
 		return FFA_ERROR_INVALID_PARAMETER;
 	}
 
+	/* Ensure that the expected and actual sizes are equal. */
 	expected_size = comp_mrd_offset + sizeof(*comp) +
 		count * sizeof(struct ffa_cons_mrd);
 
@@ -897,14 +915,30 @@
 
 	total_page_count = 0;
 
+	/*
+	 * comp->address_range_count is 32-bit, so 'count' must fit in a
+	 * uint32_t at this point.
+	 */
 	for (size_t i = 0; i < count; i++) {
-		total_page_count +=
-			comp->address_range_array[i].page_count;
+		const struct ffa_cons_mrd *mrd = comp->address_range_array + i;
+
+		if (!is_aligned(mrd->address, PAGE_SIZE)) {
+			WARN("%s: invalid object, address in region descriptor "
+			     "%zu not 4K aligned (got 0x%016llx)",
+			     __func__, i, (unsigned long long)mrd->address);
+		}
+
+		/*
+		 * No overflow possible: total_page_count can hold at
+		 * least 2^64 - 1, but will be have at most 2^32 - 1.
+		 * values added to it, each of which cannot exceed 2^32 - 1.
+		 */
+		total_page_count += mrd->page_count;
 	}
+
 	if (comp->total_page_count != total_page_count) {
-		WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
-		     __func__, comp->total_page_count,
-		total_page_count);
+		WARN("%s: invalid object, desc total_page_count %u != %llu\n",
+		     __func__, comp->total_page_count, total_page_count);
 		return FFA_ERROR_INVALID_PARAMETER;
 	}
 
@@ -970,11 +1004,8 @@
 			       void *smc_handle)
 {
 	int ret;
-	size_t emad_size;
 	uint32_t handle_low;
 	uint32_t handle_high;
-	struct ffa_emad_v1_0 *emad;
-	struct ffa_emad_v1_0 *other_emad;
 
 	if (mbox->rxtx_page_count == 0U) {
 		WARN("%s: buffer pair not registered.\n", __func__);
@@ -1057,26 +1088,6 @@
 		goto err_bad_desc;
 	}
 
-	/* Ensure partition IDs are not duplicated. */
-	for (size_t i = 0; i < obj->desc.emad_count; i++) {
-		emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
-					       &emad_size);
-
-		for (size_t j = i + 1; j < obj->desc.emad_count; j++) {
-			other_emad = spmc_shmem_obj_get_emad(&obj->desc, j,
-							     ffa_version,
-							     &emad_size);
-
-			if (emad->mapd.endpoint_id ==
-				other_emad->mapd.endpoint_id) {
-				WARN("%s: Duplicated endpoint id 0x%x\n",
-				     __func__, emad->mapd.endpoint_id);
-				ret = FFA_ERROR_INVALID_PARAMETER;
-				goto err_bad_desc;
-			}
-		}
-	}
-
 	ret = spmc_shmem_check_state_obj(obj, ffa_version);
 	if (ret) {
 		ERROR("%s: invalid memory region descriptor.\n", __func__);