Merge changes I713f6e93,Iac4fbf4d,I43d02c77,Iadecd544,Ib31f9c4a, ... into integration

* changes:
  build(intel): enable access to on-chip ram in BL31 for N5X
  fix(intel): make FPGA memory configurations platform specific
  fix(intel): fix ECC Double Bit Error handling
  build(intel): define a macro for SIMICS build
  build(intel): add N5X as a new Intel platform
  build(intel): initial commit for crypto driver
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 16c41bd..ad125cf 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -480,6 +480,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Rex-BC Chen <rex-bc.chen@mediatek.com>
 :|G|: `mtk-rex-bc-chen`_
+:|F|: docs/plat/mt\*.rst
 :|F|: plat/mediatek/
 
 Marvell platform ports and SoC drivers
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 7aa7384..9401811 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -417,6 +417,10 @@
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+-  ``ERRATA_A710_2282622``: This applies errata 2282622 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+   of the CPU and is fixed in r2p1.
+
 For Neoverse N2, the following errata build flags are defined :
 
 -  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index af302c6..cefc21f 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -115,6 +115,24 @@
 - ``STM32MP_SPI_NAND``
 - ``STM32MP_SPI_NOR``
 
+Serial boot devices:
+
+- ``STM32MP_UART_PROGRAMMER``
+- ``STM32MP_USB_PROGRAMMER``
+
+
+Other configuration flags:
+
+- | ``DTB_FILE_NAME``: to precise board device-tree blob to be used.
+  | Default: stm32mp157c-ev1.dtb
+- | ``STM32MP_EARLY_CONSOLE``: to enable early traces before clock driver is setup.
+  | Default: 0 (disabled)
+- | ``STM32MP_UART_BAUDRATE``: to select UART baud rate.
+  | Default: 115200
+- | ``STM32_TF_VERSION``: to manage BL2 monotonic counter.
+  | Default: 0
+
+
 Boot with FIP
 ~~~~~~~~~~~~~
 You need to build BL2, BL32 (SP_min or OP-TEE) and BL33 (U-Boot) before building FIP binary.
diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index ce2c843..887b06a 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -14,3 +14,4 @@
    security-advisory-tfv-6.rst
    security-advisory-tfv-7.rst
    security-advisory-tfv-8.rst
+   security-advisory-tfv-9.rst
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
new file mode 100644
index 0000000..74b85dc
--- /dev/null
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -0,0 +1,104 @@
+Advisory TFV-9 (CVE-2022-23960)
+============================================================
+
++----------------+-------------------------------------------------------------+
+| Title          | Trusted Firmware-A exposure to speculative processor        |
+|                | vulnerabilities with branch prediction target reuse         |
++================+=============================================================+
+| CVE ID         | `CVE-2022-23960`_                                           |
++----------------+-------------------------------------------------------------+
+| Date           | 08 Mar 2022                                                 |
++----------------+-------------------------------------------------------------+
+| Versions       | All, up to and including v2.6                               |
+| Affected       |                                                             |
++----------------+-------------------------------------------------------------+
+| Configurations | All                                                         |
+| Affected       |                                                             |
++----------------+-------------------------------------------------------------+
+| Impact         | Potential leakage of secure world data to normal world      |
+|                | if an attacker is able to find a TF-A exfiltration primitive|
+|                | that can be predicted as a valid branch target, and somehow |
+|                | induce misprediction onto that primitive. There are         |
+|                | currently no known exploits.                                |
++----------------+-------------------------------------------------------------+
+| Fix Version    | `Gerrit topic #spectre_bhb`_                                |
++----------------+-------------------------------------------------------------+
+| Credit         | Systems and Network Security Group at Vrije Universiteit    |
+|                | Amsterdam for CVE-2022-23960, Arm for patches               |
++----------------+-------------------------------------------------------------+
+
+This security advisory describes the current understanding of the Trusted
+Firmware-A exposure to the new speculative processor vulnerability.
+To understand the background and wider impact of these vulnerabilities on Arm
+systems, please refer to the `Arm Processor Security Update`_. The whitepaper
+referred to below describes the Spectre attack and mitigation in more detail
+including implementation specific mitigation details for all impacted Arm CPUs.
+
+
+`CVE-2022-23960`_
+-----------------
+
+Where possible on vulnerable CPUs that implement FEAT_CSV2, Arm recommends
+inserting a loop workaround with implementation specific number of iterations
+that will discard the branch history on exception entry to a higher exception
+level for the given CPU. This is done as early as possible on entry into EL3,
+before any branch instruction is executed. This is sufficient to mitigate
+Spectre-BHB on behalf of all secure world code, assuming that no secure world
+code is under attacker control.
+
+The below table lists the CPUs that mitigate against this vulnerability in
+TF-A using the loop workaround(all cores that implement FEAT_CSV2 except the
+revisions of Cortex-A73 and Cortex-A75 that implements FEAT_CSV2).
+
++----------------------+
+| Core                 |
++----------------------+
+| Cortex-A72(from r1p0)|
++----------------------+
+| Cortex-A76           |
++----------------------+
+| Cortex-A77           |
++----------------------+
+| Cortex-A78           |
++----------------------+
+| Cortex-X2            |
++----------------------+
+| Cortex-A710          |
++----------------------+
+| Neoverse-N1          |
++----------------------+
+| Neoverse-N2          |
++----------------------+
+| Neoverse-V1          |
++----------------------+
+
+For all other cores impacted by Spectre-BHB, some of which that do not implement
+FEAT_CSV2 and some that do e.g. Cortex-A73, the recommended mitigation is to
+flush all branch predictions via an implementation specific route.
+
+In case local workaround is not feasible, the Rich OS can invoke the SMC
+(``SMCCC_ARCH_WORKAROUND_3``) to apply the workaround. Refer to `SMCCC Calling
+Convention specification`_ for more details.
+
+`Gerrit topic #spectre_bhb`_ This patchset implements the Spectre-BHB loop
+workaround for CPUs mentioned in the above table. It also mitigates against
+this vulnerability for Cortex-A72 CPU versions that support the CSV2 feature
+(from r1p0). The patch stack also includes an implementation for a specified
+`CVE-2022-23960`_ workaround SMC(``SMCCC_ARCH_WORKAROUND_3``) for use by normal
+world privileged software. Details of ``SMCCC_ARCH_WORKAROUND_3`` can be found
+in the `SMCCC Calling Convention specification`_. The specification and
+implementation also enables the normal world to discover the presence of this
+firmware service. This patch also implements ``SMCCC_ARCH_WORKAROUND_3`` for
+Cortex-A57, Coxtex-A72, Cortex-A73 and Cortex-A75 using the existing workaround.
+for CVE-2017-5715.
+
+The above workaround is enabled by default (on vulnerable CPUs only). Platforms
+can choose to disable them at compile time if they do not require them.
+
+For more information about non-Arm CPUs, please contact the CPU vendor.
+
+.. _Arm Processor Security Update: http://www.arm.com/security-update
+.. _CVE-2022-23960: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23960
+.. _Gerrit topic #spectre_bhb: https://review.trustedfirmware.org/q/topic:"spectre_bhb"+(status:open%20OR%20status:merged)
+.. _CVE-2022-23960 mitigation specification: https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability
+.. _SMCCC Calling Convention specification: https://developer.arm.com/documentation/den0028/latest
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
index e1e47bc..8368503 100644
--- a/drivers/auth/dualroot/cot.c
+++ b/drivers/auth/dualroot/cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 
 #include <platform_def.h>
 
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 #include <drivers/auth/auth_mod.h>
 #include <tools_share/dualroot_oid.h>
 
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index 4a8efae..a12e49c 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 
 #include <common/debug.h>
 #include <drivers/auth/mbedtls/mbedtls_common.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 #include <plat/common/platform.h>
 
 static void cleanup(void)
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 54c819c..0a4775d 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -16,7 +16,7 @@
 MBEDTLS_INC		=	-I${MBEDTLS_DIR}/include
 
 # Specify mbed TLS configuration file
-MBEDTLS_CONFIG_FILE	:=	"<drivers/auth/mbedtls/mbedtls_config.h>"
+MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config.h>"
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
 
 MBEDTLS_SOURCES	+=		drivers/auth/mbedtls/mbedtls_common.c
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c
index e4c9221..44f8638 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <stddef.h>
 
 #include <platform_def.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/tbbr_cot_common.h>
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
index e8e017c..78e38f6 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <stddef.h>
 
 #include <drivers/auth/auth_mod.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 #include <drivers/auth/tbbr_cot_common.h>
 
 #if USE_TBBR_DEFS
diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
index 65a0478..11e2f46 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl2.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <stddef.h>
 
 #include <platform_def.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/tbbr_cot_common.h>
diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c
index ff3f22d..0983d42 100644
--- a/drivers/auth/tbbr/tbbr_cot_common.c
+++ b/drivers/auth/tbbr/tbbr_cot_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <stddef.h>
 
 #include <platform_def.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/tbbr_cot_common.h>
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 2288348..534ee3b 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1921,14 +1921,21 @@
 
 	if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) &
 	     RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) {
-		pll3_preserve = stm32mp1_check_pll_conf(_PLL3,
+		if (pllcfg_valid[_PLL3]) {
+			pll3_preserve =
+				stm32mp1_check_pll_conf(_PLL3,
 							clksrc[CLKSRC_PLL3],
 							pllcfg[_PLL3],
 							plloff[_PLL3]);
-		pll4_preserve = stm32mp1_check_pll_conf(_PLL4,
+		}
+
+		if (pllcfg_valid[_PLL4]) {
+			pll4_preserve =
+				stm32mp1_check_pll_conf(_PLL4,
 							clksrc[CLKSRC_PLL4],
 							pllcfg[_PLL4],
 							plloff[_PLL4]);
+		}
 	}
 	/* Don't initialize PLL4, when used by BOOTROM */
 	if ((stm32mp_get_boot_itf_selected() ==
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index 0139661..7030cf5 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -403,7 +403,7 @@
 	}
 }
 
-struct regul_ops pmic_ops = {
+static const struct regul_ops pmic_ops = {
 	.set_state = pmic_set_state,
 	.get_state = pmic_get_state,
 	.set_voltage = pmic_set_voltage,
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index 2b8879a..e467f09 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,9 +67,24 @@
 	bic	r3, r3, #USART_CR2_STOP
 	str	r3, [r0, #USART_CR2]
 	/* Divisor =  (Uart clock + (baudrate / 2)) / baudrate */
-	lsl	r3, r2, #1
+	lsr	r3, r2, #1
 	add	r3, r1, r3
 	udiv	r3, r3, r2
+	cmp	r3, #16
+	bhi	2f
+	/* Oversampling 8 */
+	/* Divisor =  (2 * Uart clock + (baudrate / 2)) / baudrate */
+	lsr	r3, r2, #1
+	add	r3, r3, r1, lsl #1
+	udiv	r3, r3, r2
+	and	r1, r3, #USART_BRR_DIV_FRACTION
+	lsr	r1, r1, #1
+	bic	r3, r3, #USART_BRR_DIV_FRACTION
+	orr	r3, r3, r1
+	ldr	r1, [r0, #USART_CR1]
+	orr	r1, r1, #USART_CR1_OVER8
+	str	r1, [r0, #USART_CR1]
+2:
 	str	r3, [r0, #USART_BRR]
 	/* Enable UART */
 	ldr	r3, [r0, #USART_CR1]
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index dc56b62..ec62421 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -29,7 +29,12 @@
 #define CORTEX_A710_CPUACTLR_EL1_BIT_22				(ULL(1) << 22)
 
 /*******************************************************************************
- * CPU Auxiliary Control register specific definitions.
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A710_CPUACTLR2_EL1				S3_0_C15_C1_1
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 5 specific definitions.
  ******************************************************************************/
 #define CORTEX_A710_CPUACTLR5_EL1				S3_0_C15_C8_0
 #define CORTEX_A710_CPUACTLR5_EL1_BIT_13			(ULL(1) << 13)
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 92f7363..4d5d949 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -275,6 +275,36 @@
 	b       cpu_rev_var_ls
 endfunc check_errata_2136059
 
+/* ---------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2282622.
+ * This applies to revision r0p0, r1p0 and r2p0.
+ * It is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x17
+ * ---------------------------------------------------------------
+ */
+func errata_a710_2282622_wa
+	/* Compare x0 against revision r2p0 */
+	mov     x17, x30
+	bl      check_errata_2282622
+	cbz     x0, 1f
+
+	/* Apply the workaround */
+	mrs     x1, CORTEX_A710_CPUACTLR2_EL1
+	orr     x1, x1, BIT(0)
+	msr     CORTEX_A710_CPUACTLR2_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_a710_2282622_wa
+
+func check_errata_2282622
+	/* Applies to r0p0, r1p0 and r2p0 */
+	mov     x1, #0x20
+	b       cpu_rev_var_ls
+endfunc check_errata_2282622
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -313,6 +343,7 @@
 	report_errata ERRATA_A710_2058056, cortex_a710, 2058056
 	report_errata ERRATA_A710_2267065, cortex_a710, 2267065
 	report_errata ERRATA_A710_2136059, cortex_a710, 2136059
+	report_errata ERRATA_A710_2282622, cortex_a710, 2282622
 
 	ldp	x8, x30, [sp], #16
 	ret
@@ -368,6 +399,11 @@
 	bl	errata_a710_2136059_wa
 #endif
 
+#if ERRATA_A710_2282622
+	mov	x0, x18
+	bl	errata_a710_2282622_wa
+#endif
+
 	isb
 	ret	x19
 endfunc cortex_a710_reset_func
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 62b67b6..e812c07 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -467,6 +467,10 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 ERRATA_A710_2136059	?=0
 
+# Flag to apply erratum 2282622 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+ERRATA_A710_2282622	?=0
+
 # Flag to apply erratum 2067956 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
 ERRATA_N2_2067956	?=0
@@ -957,6 +961,10 @@
 $(eval $(call assert_boolean,ERRATA_A710_2136059))
 $(eval $(call add_define,ERRATA_A710_2136059))
 
+# Process ERRATA_A710_2282622 flag
+$(eval $(call assert_boolean,ERRATA_A710_2282622))
+$(eval $(call add_define,ERRATA_A710_2282622))
+
 # Process ERRATA_N2_2067956 flag
 $(eval $(call assert_boolean,ERRATA_N2_2067956))
 $(eval $(call add_define,ERRATA_N2_2067956))
diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c
index adfa534..ae59d8c 100644
--- a/lib/fconf/fconf_cot_getter.c
+++ b/lib/fconf/fconf_cot_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 #include <stddef.h>
 
 #include <common/fdt_wrappers.h>
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
 #include <drivers/auth/auth_mod.h>
 #include <lib/fconf/fconf.h>
 #include <lib/object_pool.h>
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index f99cad5..d922d3c 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -210,7 +210,7 @@
 	unsigned int console_flags;
 
 	if (console_stm32_register(base, clk_rate,
-				   STM32MP_UART_BAUDRATE, &console) == 0) {
+				   (uint32_t)STM32MP_UART_BAUDRATE, &console) == 0) {
 		panic();
 	}
 
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index ca2bad8..0f579a4 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -10,6 +10,7 @@
 USE_COHERENT_MEM	:=	0
 
 STM32MP_EARLY_CONSOLE	?=	0
+STM32MP_UART_BAUDRATE	?=	115200
 
 # Allow TF-A to concatenate BL2 & BL32 binaries in a single file,
 # share DTB file between BL2 and BL32
@@ -172,6 +173,7 @@
 		PLAT_PARTITION_MAX_ENTRIES \
 		STM32_TF_A_COPIES \
 		STM32_TF_VERSION \
+		STM32MP_UART_BAUDRATE \
 )))
 
 $(eval $(call add_defines,\
@@ -189,6 +191,7 @@
 		STM32MP_SDMMC \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
+		STM32MP_UART_BAUDRATE \
 		STM32MP_UART_PROGRAMMER \
 		STM32MP_USB_PROGRAMMER \
 		STM32MP_USE_STM32IMAGE \
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index aabe81f..801b947 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -202,7 +202,6 @@
 #define USART6_BASE			U(0x44003000)
 #define UART7_BASE			U(0x40018000)
 #define UART8_BASE			U(0x40019000)
-#define STM32MP_UART_BAUDRATE		U(115200)
 
 /* For UART crash console */
 #define STM32MP_DEBUG_USART_BASE	UART4_BASE
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 60f7449..78bfc29 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -112,10 +112,12 @@
 						  atf_handoff_addr);
 	if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) {
 		bl31_set_default_config();
+	} else if (ret == FSBL_HANDOFF_TOO_MANY_PARTS) {
+		ERROR("BL31: Error too many partitions %u\n", ret);
 	} else if (ret != FSBL_HANDOFF_SUCCESS) {
 		panic();
 	} else {
-		ERROR("BL31: Error during fsbl-atf handover %d.\n", ret);
+		INFO("BL31: fsbl-atf handover success %u\n", ret);
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index f78b88c..b2b473a 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,6 +33,8 @@
 {
 	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
 	const struct pm_proc *proc;
+	uint32_t buff[3];
+	enum pm_ret_status ret;
 
 	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
 
@@ -40,6 +42,13 @@
 		return PSCI_E_INTERN_FAIL;
 
 	proc = pm_get_proc(cpu_id);
+
+	/* Check the APU proc status before wakeup */
+	ret = pm_get_node_status(proc->node_id, buff);
+	if ((ret != PM_RET_SUCCESS) || (buff[0] == PM_PROC_STATE_SUSPENDING)) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
 	/* Clear power down request */
 	pm_client_wakeup(proc);
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 0cc517e..4109830 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2443,8 +2443,6 @@
  *
  * This function is used by master to get nmae of clock specified
  * by given clock ID.
- *
- * @return	Returns success. In case of error, name data is 0.
  */
 void pm_api_clock_get_name(unsigned int clock_id, char *name)
 {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 9c5af88..a87681b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -618,6 +618,7 @@
 				unsigned int *value)
 {
 	enum pm_ret_status ret;
+	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	switch (ioctl_id) {
 	case IOCTL_GET_RPU_OPER_MODE:
@@ -677,14 +678,57 @@
 	case IOCTL_AFI:
 		ret = pm_ioctl_afi(arg1, arg2);
 		break;
-	case IOCTL_SET_FEATURE_CONFIG:
-	case IOCTL_GET_FEATURE_CONFIG:
-		ret = pm_feature_config(ioctl_id, arg1, arg2, value);
-		break;
 	default:
-		ret = PM_RET_ERROR_NOTSUPPORTED;
+		/* Send request to the PMU */
+		PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2);
+
+		ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
 		break;
 	}
 
 	return ret;
 }
+
+/**
+ * pm_update_ioctl_bitmask() -  API to get supported IOCTL ID mask
+ * @bit_mask		Returned bit mask of supported IOCTL IDs
+ */
+enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask)
+{
+	uint8_t supported_ids[] = {
+		IOCTL_GET_RPU_OPER_MODE,
+		IOCTL_SET_RPU_OPER_MODE,
+		IOCTL_RPU_BOOT_ADDR_CONFIG,
+		IOCTL_TCM_COMB_CONFIG,
+		IOCTL_SET_TAPDELAY_BYPASS,
+		IOCTL_SET_SGMII_MODE,
+		IOCTL_SD_DLL_RESET,
+		IOCTL_SET_SD_TAPDELAY,
+		IOCTL_SET_PLL_FRAC_MODE,
+		IOCTL_GET_PLL_FRAC_MODE,
+		IOCTL_SET_PLL_FRAC_DATA,
+		IOCTL_GET_PLL_FRAC_DATA,
+		IOCTL_WRITE_GGS,
+		IOCTL_READ_GGS,
+		IOCTL_WRITE_PGGS,
+		IOCTL_READ_PGGS,
+		IOCTL_ULPI_RESET,
+		IOCTL_SET_BOOT_HEALTH_STATUS,
+		IOCTL_AFI,
+	};
+	uint8_t i, ioctl_id;
+	int ret;
+
+	for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
+		ioctl_id = supported_ids[i];
+		if (ioctl_id >= 64U) {
+			return PM_RET_ERROR_NOTSUPPORTED;
+		}
+		ret = check_api_dependency(ioctl_id);
+		if (ret == PM_RET_SUCCESS) {
+			bit_mask[ioctl_id / 32] |= BIT(ioctl_id % 32);
+		}
+	}
+
+	return PM_RET_SUCCESS;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index f18dc00..0c5f33f 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,9 +49,6 @@
 	IOCTL_AIE_ISR_CLEAR = 24,
 	/* Register SGI to ATF */
 	IOCTL_REGISTER_SGI = 25,
-	/* Runtime feature configuration */
-	IOCTL_SET_FEATURE_CONFIG = 26,
-	IOCTL_GET_FEATURE_CONFIG = 27,
 };
 
 //RPU operation mode
@@ -95,4 +92,5 @@
 				unsigned int arg1,
 				unsigned int arg2,
 				unsigned int *value);
+enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask);
 #endif /* PM_API_IOCTL_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 5d9408c..f9af451 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,225 @@
 #include "pm_common.h"
 #include "pm_ipi.h"
 
+#define PM_QUERY_FEATURE_BITMASK ( \
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_NAME) | \
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_TOPOLOGY) |	\
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS) | \
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_PARENTS) | \
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_ATTRIBUTES) | \
+	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_PINS) | \
+	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTIONS) | \
+	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS) | \
+	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_NAME) | \
+	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_GROUPS) | \
+	(1ULL << (uint64_t)PM_QID_PINCTRL_GET_PIN_GROUPS) | \
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_NUM_CLOCKS) | \
+	(1ULL << (uint64_t)PM_QID_CLOCK_GET_MAX_DIVISOR))
+
+/**
+ * struct eemi_api_dependency - Dependent EEMI APIs which are implemented
+ * on both the ATF and firmware
+ *
+ * @id:		EEMI API id or IOCTL id to be checked
+ * @api_id:	Dependent EEMI API
+ */
+typedef struct __attribute__((packed)) {
+	uint8_t id;
+	uint8_t api_id;
+} eemi_api_dependency;
+
+/* Dependent APIs for ATF to check their version from firmware */
+static const eemi_api_dependency api_dep_table[] = {
+	{
+		.id = PM_SELF_SUSPEND,
+		.api_id = PM_SELF_SUSPEND,
+	},
+	{
+		.id = PM_REQ_WAKEUP,
+		.api_id = PM_REQ_WAKEUP,
+	},
+	{
+		.id = PM_ABORT_SUSPEND,
+		.api_id = PM_ABORT_SUSPEND,
+	},
+	{
+		.id = PM_SET_WAKEUP_SOURCE,
+		.api_id = PM_SET_WAKEUP_SOURCE,
+	},
+	{
+		.id = PM_SYSTEM_SHUTDOWN,
+		.api_id = PM_SYSTEM_SHUTDOWN,
+	},
+	{
+		.id = PM_GET_API_VERSION,
+		.api_id = PM_GET_API_VERSION,
+	},
+	{
+		.id = PM_CLOCK_ENABLE,
+		.api_id = PM_PLL_SET_MODE,
+	},
+	{
+		.id = PM_CLOCK_ENABLE,
+		.api_id = PM_CLOCK_ENABLE,
+	},
+	{
+		.id = PM_CLOCK_DISABLE,
+		.api_id = PM_PLL_SET_MODE,
+	},
+	{
+		.id = PM_CLOCK_DISABLE,
+		.api_id = PM_CLOCK_DISABLE,
+	},
+	{
+		.id = PM_CLOCK_GETSTATE,
+		.api_id = PM_PLL_GET_MODE,
+	},
+	{
+		.id = PM_CLOCK_GETSTATE,
+		.api_id = PM_CLOCK_GETSTATE,
+	},
+	{
+		.id = PM_CLOCK_SETDIVIDER,
+		.api_id = PM_PLL_SET_PARAMETER,
+	},
+	{
+		.id = PM_CLOCK_SETDIVIDER,
+		.api_id = PM_CLOCK_SETDIVIDER,
+	},
+	{
+		.id = PM_CLOCK_GETDIVIDER,
+		.api_id = PM_PLL_GET_PARAMETER,
+	},
+	{
+		.id = PM_CLOCK_GETDIVIDER,
+		.api_id = PM_CLOCK_GETDIVIDER,
+	},
+	{
+		.id = PM_CLOCK_SETPARENT,
+		.api_id = PM_PLL_SET_PARAMETER,
+	},
+	{
+		.id = PM_CLOCK_SETPARENT,
+		.api_id = PM_CLOCK_SETPARENT,
+	},
+	{
+		.id = PM_CLOCK_GETPARENT,
+		.api_id = PM_PLL_GET_PARAMETER,
+	},
+	{
+		.id = PM_CLOCK_GETPARENT,
+		.api_id = PM_CLOCK_GETPARENT,
+	},
+	{
+		.id = PM_PLL_SET_PARAMETER,
+		.api_id = PM_PLL_SET_PARAMETER,
+	},
+	{
+		.id = PM_PLL_GET_PARAMETER,
+		.api_id = PM_PLL_GET_PARAMETER,
+	},
+	{
+		.id = PM_PLL_SET_MODE,
+		.api_id = PM_PLL_SET_MODE,
+	},
+	{
+		.id = PM_PLL_GET_MODE,
+		.api_id = PM_PLL_GET_MODE,
+	},
+	{
+		.id = PM_REGISTER_ACCESS,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = PM_REGISTER_ACCESS,
+		.api_id = PM_MMIO_READ,
+	},
+	{
+		.id = PM_FEATURE_CHECK,
+		.api_id = PM_FEATURE_CHECK,
+	},
+	{
+		.id = IOCTL_SET_TAPDELAY_BYPASS,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_SET_SGMII_MODE,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_SD_DLL_RESET,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_SET_SD_TAPDELAY,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_SET_SD_TAPDELAY,
+		.api_id = PM_MMIO_READ,
+	},
+	{
+		.id = IOCTL_SET_PLL_FRAC_DATA,
+		.api_id = PM_PLL_SET_PARAMETER,
+	},
+	{
+		.id = IOCTL_GET_PLL_FRAC_DATA,
+		.api_id = PM_PLL_GET_PARAMETER,
+	},
+	{
+		.id = IOCTL_WRITE_GGS,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_READ_GGS,
+		.api_id = PM_MMIO_READ,
+	},
+	{
+		.id = IOCTL_WRITE_PGGS,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_READ_PGGS,
+		.api_id = PM_MMIO_READ,
+	},
+	{
+		.id = IOCTL_ULPI_RESET,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_SET_BOOT_HEALTH_STATUS,
+		.api_id = PM_MMIO_WRITE,
+	},
+	{
+		.id = IOCTL_AFI,
+		.api_id = PM_MMIO_WRITE,
+	},
+};
+
+/* Expected firmware API version to ATF */
+static const uint8_t atf_expected_ver_id[] = {
+	[PM_SELF_SUSPEND] = FW_API_BASE_VERSION,
+	[PM_REQ_WAKEUP] = FW_API_BASE_VERSION,
+	[PM_ABORT_SUSPEND] = FW_API_BASE_VERSION,
+	[PM_SET_WAKEUP_SOURCE] = FW_API_BASE_VERSION,
+	[PM_SYSTEM_SHUTDOWN] = FW_API_BASE_VERSION,
+	[PM_GET_API_VERSION] = FW_API_BASE_VERSION,
+	[PM_PLL_SET_MODE] = FW_API_BASE_VERSION,
+	[PM_PLL_GET_MODE] = FW_API_BASE_VERSION,
+	[PM_CLOCK_ENABLE] = FW_API_BASE_VERSION,
+	[PM_CLOCK_DISABLE] = FW_API_BASE_VERSION,
+	[PM_CLOCK_GETSTATE] = FW_API_BASE_VERSION,
+	[PM_PLL_SET_PARAMETER] = FW_API_BASE_VERSION,
+	[PM_PLL_GET_PARAMETER] = FW_API_BASE_VERSION,
+	[PM_CLOCK_SETDIVIDER] = FW_API_BASE_VERSION,
+	[PM_CLOCK_GETDIVIDER] = FW_API_BASE_VERSION,
+	[PM_CLOCK_SETPARENT] = FW_API_BASE_VERSION,
+	[PM_CLOCK_GETPARENT] = FW_API_BASE_VERSION,
+	[PM_MMIO_WRITE] = FW_API_BASE_VERSION,
+	[PM_MMIO_READ] = FW_API_BASE_VERSION,
+	[PM_FEATURE_CHECK] = FW_API_VERSION_2,
+};
+
 /* default shutdown/reboot scope is system(2) */
 static unsigned int pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
 
@@ -33,38 +252,6 @@
 	return pm_shutdown_scope;
 }
 
-/**
- * Assigning of argument values into array elements.
- */
-#define PM_PACK_PAYLOAD1(pl, arg0) {	\
-	pl[0] = (uint32_t)(arg0);	\
-}
-
-#define PM_PACK_PAYLOAD2(pl, arg0, arg1) {	\
-	pl[1] = (uint32_t)(arg1);		\
-	PM_PACK_PAYLOAD1(pl, arg0);		\
-}
-
-#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) {	\
-	pl[2] = (uint32_t)(arg2);			\
-	PM_PACK_PAYLOAD2(pl, arg0, arg1);		\
-}
-
-#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) {	\
-	pl[3] = (uint32_t)(arg3);			\
-	PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2);		\
-}
-
-#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) {	\
-	pl[4] = (uint32_t)(arg4);				\
-	PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3);		\
-}
-
-#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) {	\
-	pl[5] = (uint32_t)(arg5);					\
-	PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4);		\
-}
-
 #define EM_PACK_PAYLOAD1(pl, arg0) {	\
 	pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0;	\
 }
@@ -305,36 +492,6 @@
 		return pm_ipi_send(primary_proc, payload);
 }
 
-/**
- * pm_release_node() - PM call to release a node
- * @nid		Node id of the slave
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_release_node(enum pm_node_id nid)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_set_max_latency() - PM call to set wakeup latency requirements
- * @nid		Node id of the slave
- * @latency	Requested maximum wakeup latency
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
-				      unsigned int latency)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
 /* Miscellaneous API functions */
 
 /**
@@ -353,36 +510,6 @@
 }
 
 /**
- * pm_set_configuration() - PM call to set system configuration
- * @phys_addr	Physical 32-bit address of data structure in memory
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_configuration(unsigned int phys_addr)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD2(payload, PM_SET_CONFIGURATION, phys_addr);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_init_finalize() - Call to notify PMU firmware that master has power
- *			management enabled and that it has finished its
- *			initialization
- *
- * @return	Status returned by the PMU firmware
- */
-enum pm_ret_status pm_init_finalize(void)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD1(payload, PM_INIT_FINALIZE);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
  * pm_get_node_status() - PM call to request a node's current status
  * @nid		Node id
  * @ret_buff	Buffer for the return values:
@@ -402,86 +529,6 @@
 }
 
 /**
- * pm_register_notifier() - Register the PU to be notified of PM events
- * @nid		Node id of the slave
- * @event	The event to be notified about
- * @wake	Wake up on event
- * @enable	Enable or disable the notifier
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
-					unsigned int event,
-					unsigned int wake,
-					unsigned int enable)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
-			 nid, event, wake, enable);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_get_op_characteristic() - PM call to request operating characteristics
- *				of a node
- * @nid		Node id of the slave
- * @type	Type of the operating characteristic
- *		(power, temperature and latency)
- * @result	Returns the operating characteristic for the requested node,
- *		specified by the type
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
-					    enum pm_opchar_type type,
-					    uint32_t *result)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
-	return pm_ipi_send_sync(primary_proc, payload, result, 1);
-}
-
-/* Direct-Control API functions */
-
-/**
- * pm_reset_assert() - Assert reset
- * @reset	Reset ID
- * @assert	Assert (1) or de-assert (0)
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_assert(unsigned int reset,
-				   unsigned int assert)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_reset_get_status() - Get current status of a reset line
- * @reset	Reset ID
- * @reset_status Returns current status of selected reset line
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_get_status(unsigned int reset,
-				       unsigned int *reset_status)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset);
-	return pm_ipi_send_sync(primary_proc, payload, reset_status, 1);
-}
-
-/**
  * pm_mmio_write() - Perform write to protected mmio
  * @address	Address to write to
  * @mask	Mask to apply
@@ -650,113 +697,6 @@
 }
 
 /**
- * pm_pinctrl_request() - Request Pin from firmware
- * @pin		Pin number to request
- *
- * This function requests pin from firmware.
- *
- * @return	Returns status, either success or error+reason.
- */
-enum pm_ret_status pm_pinctrl_request(unsigned int pin)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD2(payload, PM_PINCTRL_REQUEST, pin);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_release() - Release Pin from firmware
- * @pin		Pin number to release
- *
- * This function releases pin from firmware.
- *
- * @return	Returns status, either success or error+reason.
- */
-enum pm_ret_status pm_pinctrl_release(unsigned int pin)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD2(payload, PM_PINCTRL_RELEASE, pin);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_function() - Read function id set for the given pin
- * @pin		Pin number
- * @fid		ID of function currently set for given pin
- *
- * This function provides the function currently set for the given pin.
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, unsigned int *fid)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD2(payload, PM_PINCTRL_GET_FUNCTION, pin);
-	return pm_ipi_send_sync(primary_proc, payload, fid, 1);
-}
-
-/**
- * pm_pinctrl_set_function() - Set function id set for the given pin
- * @pin		Pin number
- * @fid		ID of function to set for given pin
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, unsigned int fid)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD3(payload, PM_PINCTRL_SET_FUNCTION, pin, fid);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_config() - Read value of requested config param for given pin
- * @pin		Pin number
- * @param	Parameter values to be read
- * @value	Buffer for configuration Parameter value
- *
- * This function provides the configuration parameter value for the given pin.
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
-					 unsigned int param,
-					 unsigned int *value)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD3(payload, PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pinctrl_set_config() - Set value of requested config param for given pin
- * @pin		Pin number
- * @param	Parameter to set
- * @value	Parameter value to set
- *
- * @return	Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
-					 unsigned int param,
-					 unsigned int value)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD4(payload, PM_PINCTRL_CONFIG_PARAM_SET, pin, param,
-			 value);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
  * pm_ioctl() -  PM IOCTL API for device control and configs
  * @node_id	Node ID of the device
  * @ioctl_id	ID of the requested IOCTL
@@ -778,6 +718,220 @@
 }
 
 /**
+ * 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
+ *
+ * @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)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	PM_PACK_PAYLOAD2(payload, PM_FEATURE_CHECK, id);
+	return pm_ipi_send_sync(primary_proc, payload, version, len);
+}
+
+/**
+ * check_api_dependency() -  API to check dependent EEMI API version
+ * @id		EEMI API ID to check
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status check_api_dependency(uint8_t id)
+{
+	uint8_t i;
+	uint32_t version;
+	int ret;
+
+	for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
+		if (api_dep_table[i].id == id) {
+			if (api_dep_table[i].api_id == 0U) {
+				break;
+			}
+
+			ret = fw_api_version(api_dep_table[i].api_id,
+					     &version, 1);
+			if (ret != PM_RET_SUCCESS) {
+				return ret;
+			}
+
+			/* Check if fw version matches ATF expected version */
+			if (version != atf_expected_ver_id[api_dep_table[i].api_id]) {
+				return PM_RET_ERROR_NOTSUPPORTED;
+			}
+		}
+	}
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * feature_check_atf() - These are API's completely implemented in ATF
+ * @api_id	API ID to check
+ * @version	Returned supported API version
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status feature_check_atf(uint32_t api_id, uint32_t *version,
+					    uint32_t *bit_mask)
+{
+	switch (api_id) {
+	case PM_QUERY_DATA:
+		*version = ATF_API_BASE_VERSION;
+		bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
+		bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
+		return PM_RET_SUCCESS;
+	case PM_GET_CALLBACK_DATA:
+	case PM_GET_TRUSTZONE_VERSION:
+	case PM_SET_SUSPEND_MODE:
+		*version = ATF_API_BASE_VERSION;
+		return PM_RET_SUCCESS;
+	default:
+		return PM_RET_ERROR_NO_FEATURE;
+	}
+}
+
+/**
+ * get_atf_version_for_partial_apis() - Return ATF version for partially
+ * implemented APIs
+ * @api_id	API ID to check
+ * @version	Returned supported API version
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status get_atf_version_for_partial_apis(uint32_t api_id,
+							   uint32_t *version)
+{
+	switch (api_id) {
+	case PM_SELF_SUSPEND:
+	case PM_REQ_WAKEUP:
+	case PM_ABORT_SUSPEND:
+	case PM_SET_WAKEUP_SOURCE:
+	case PM_SYSTEM_SHUTDOWN:
+	case PM_GET_API_VERSION:
+	case PM_CLOCK_ENABLE:
+	case PM_CLOCK_DISABLE:
+	case PM_CLOCK_GETSTATE:
+	case PM_CLOCK_SETDIVIDER:
+	case PM_CLOCK_GETDIVIDER:
+	case PM_CLOCK_SETPARENT:
+	case PM_CLOCK_GETPARENT:
+	case PM_PLL_SET_PARAMETER:
+	case PM_PLL_GET_PARAMETER:
+	case PM_PLL_SET_MODE:
+	case PM_PLL_GET_MODE:
+	case PM_REGISTER_ACCESS:
+		*version = ATF_API_BASE_VERSION;
+		return PM_RET_SUCCESS;
+	case PM_FEATURE_CHECK:
+		*version = FW_API_VERSION_2;
+		return PM_RET_SUCCESS;
+	default:
+		return PM_RET_ERROR_ARGS;
+	}
+}
+
+/**
+ * feature_check_partial() - These are API's partially implemented in
+ * ATF and firmware both
+ * @api_id	API ID to check
+ * @version	Returned supported API version
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status feature_check_partial(uint32_t api_id,
+						uint32_t *version)
+{
+	uint32_t status;
+
+	switch (api_id) {
+	case PM_SELF_SUSPEND:
+	case PM_REQ_WAKEUP:
+	case PM_ABORT_SUSPEND:
+	case PM_SET_WAKEUP_SOURCE:
+	case PM_SYSTEM_SHUTDOWN:
+	case PM_GET_API_VERSION:
+	case PM_CLOCK_ENABLE:
+	case PM_CLOCK_DISABLE:
+	case PM_CLOCK_GETSTATE:
+	case PM_CLOCK_SETDIVIDER:
+	case PM_CLOCK_GETDIVIDER:
+	case PM_CLOCK_SETPARENT:
+	case PM_CLOCK_GETPARENT:
+	case PM_PLL_SET_PARAMETER:
+	case PM_PLL_GET_PARAMETER:
+	case PM_PLL_SET_MODE:
+	case PM_PLL_GET_MODE:
+	case PM_REGISTER_ACCESS:
+	case PM_FEATURE_CHECK:
+		status = check_api_dependency(api_id);
+		if (status != PM_RET_SUCCESS) {
+			return status;
+		}
+		return get_atf_version_for_partial_apis(api_id, version);
+	default:
+		return PM_RET_ERROR_NO_FEATURE;
+	}
+}
+
+/**
+ * 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
+ */
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
+				    uint32_t *bit_mask, uint8_t len)
+{
+	uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t status;
+
+	/* Get API version implemented in ATF */
+	status = feature_check_atf(api_id, version, bit_mask);
+	if (status != PM_RET_ERROR_NO_FEATURE) {
+		return status;
+	}
+
+	/* Get API version implemented by firmware and ATF both */
+	status = feature_check_partial(api_id, version);
+	if (status != PM_RET_ERROR_NO_FEATURE) {
+		return status;
+	}
+
+	/* Get API version implemented by firmware */
+	status = fw_api_version(api_id, ret_payload, 3);
+	/* IOCTL call may return failure whose ID is not implemented in
+	 * firmware but implemented in ATF
+	 */
+	if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
+		return status;
+	}
+
+	*version = ret_payload[0];
+
+	/* Update IOCTL bit mask which are implemented in ATF */
+	if (api_id == PM_IOCTL) {
+		if (len < 2) {
+			return PM_RET_ERROR_ARGS;
+		}
+		bit_mask[0] = ret_payload[1];
+		bit_mask[1] = ret_payload[2];
+		/* Get IOCTL's implemented by ATF */
+		status = atf_ioctl_bitmask(bit_mask);
+	} else {
+		/* Requires for MISRA */
+	}
+
+	return status;
+}
+
+/**
  * pm_clock_get_max_divisor - PM call to get max divisor
  * @clock_id	Clock ID
  * @div_type	Divisor ID (TYPE_DIV1 or TYPE_DIV2)
@@ -1648,36 +1802,3 @@
 	EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
 	return pm_ipi_send_sync(primary_proc, payload, value, 1);
 }
-
-/**
- * pm_feature_config() - feature configuration at runtime
- *
- * This function is used to send IPI request to PMUFW to configure feature
- * at runtime. The feature can be enable or disable as well as the feature
- * can be configure at runtime using an IOCTL call.
- *
- * @ioctl_id	The ioctl id for the feature configuration
- * @config_id	The config id of the feature to be configured
- * @value	The value to be configured
- * @response	Return to reference pointer
- *
- * @return      Returns 0 on success or error value on failure
- */
-enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
-				     unsigned int config_id,
-				     unsigned int value,
-				     unsigned int *response)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMU */
-	PM_PACK_PAYLOAD5(payload, PM_IOCTL, 0, ioctl_id, config_id, value);
-
-	if (ioctl_id == IOCTL_GET_FEATURE_CONFIG) {
-		return pm_ipi_send_sync(primary_proc, payload, response, 1);
-	} else if (ioctl_id == IOCTL_SET_FEATURE_CONFIG) {
-		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-	} else {
-		return PM_RET_ERROR_ARGS;
-	}
-}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index ca07cef..4e38c42 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,6 +33,38 @@
 	CONFIG_REG_READ,
 };
 
+/**
+ * Assigning of argument values into array elements.
+ */
+#define PM_PACK_PAYLOAD1(pl, arg0) {	\
+	pl[0] = (uint32_t)(arg0);	\
+}
+
+#define PM_PACK_PAYLOAD2(pl, arg0, arg1) {	\
+	pl[1] = (uint32_t)(arg1);		\
+	PM_PACK_PAYLOAD1(pl, arg0);		\
+}
+
+#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) {	\
+	pl[2] = (uint32_t)(arg2);			\
+	PM_PACK_PAYLOAD2(pl, arg0, arg1);		\
+}
+
+#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) {	\
+	pl[3] = (uint32_t)(arg3);			\
+	PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2);		\
+}
+
+#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) {	\
+	pl[4] = (uint32_t)(arg4);				\
+	PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3);		\
+}
+
+#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) {	\
+	pl[5] = (uint32_t)(arg5);					\
+	PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4);		\
+}
+
 /**********************************************************
  * System-level API function declarations
  **********************************************************/
@@ -72,28 +104,16 @@
 			       unsigned int capabilities,
 			       unsigned int qos,
 			       enum pm_request_ack ack);
-enum pm_ret_status pm_release_node(enum pm_node_id nid);
 
 enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
 				      unsigned int capabilities,
 				      unsigned int qos,
 				      enum pm_request_ack ack);
-enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
-				      unsigned int latency);
 
 /* Miscellaneous API functions */
 enum pm_ret_status pm_get_api_version(unsigned int *version);
-enum pm_ret_status pm_set_configuration(unsigned int phys_addr);
-enum pm_ret_status pm_init_finalize(void);
 enum pm_ret_status pm_get_node_status(enum pm_node_id node,
 				      uint32_t *ret_buff);
-enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
-					unsigned int event,
-					unsigned int wake,
-					unsigned int enable);
-enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
-					    enum pm_opchar_type type,
-					    uint32_t *result);
 enum pm_ret_status pm_acknowledge_cb(enum pm_node_id nid,
 				     enum pm_ret_status status,
 				     unsigned int oppoint);
@@ -102,10 +122,6 @@
 				unsigned int oppoint);
 
 /* Direct-Control API functions */
-enum pm_ret_status pm_reset_assert(unsigned int reset_id,
-				   unsigned int assert);
-enum pm_ret_status pm_reset_get_status(unsigned int reset_id,
-				       unsigned int *reset_status);
 enum pm_ret_status pm_mmio_write(uintptr_t address,
 				 unsigned int mask,
 				 unsigned int value);
@@ -123,18 +139,6 @@
 				    uint32_t flags);
 unsigned int pm_get_shutdown_scope(void);
 void pm_get_callbackdata(uint32_t *data, size_t count);
-enum pm_ret_status pm_pinctrl_request(unsigned int pin);
-enum pm_ret_status pm_pinctrl_release(unsigned int pin);
-enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
-					   enum pm_node_id *nid);
-enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
-					   enum pm_node_id nid);
-enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
-					 unsigned int param,
-					 unsigned int *value);
-enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
-					 unsigned int param,
-					 unsigned int value);
 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
 			    unsigned int ioctl_id,
 			    unsigned int arg1,
@@ -206,5 +210,8 @@
 				     unsigned int config_id,
 				     unsigned int value,
 				     unsigned int *response);
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
+				    uint32_t *bit_mask, uint8_t len);
+enum pm_ret_status check_api_dependency(uint8_t id);
 
 #endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 3324431..2baf960 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,16 @@
 
 #define PM_VERSION	((PM_VERSION_MAJOR << 16) | 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 */
+#define FW_API_VERSION_2		(2U)
+/* Version of APIs implemented in ATF */
+#define ATF_API_BASE_VERSION		(1U)
+
 /* Capabilities for RAM */
 #define PM_CAP_ACCESS	0x1U
 #define PM_CAP_CONTEXT	0x2U
@@ -33,7 +43,18 @@
 #define PM_STATE_CPU_IDLE		0x0U
 #define PM_STATE_SUSPEND_TO_RAM		0xFU
 
+/* APU processor states */
+#define PM_PROC_STATE_FORCEDOFF		0U
+#define PM_PROC_STATE_ACTIVE		1U
+#define PM_PROC_STATE_SLEEP		2U
+#define PM_PROC_STATE_SUSPENDING	3U
+
 #define EM_FUNID_NUM_MASK    0xF0000U
+
+#define PM_GET_CALLBACK_DATA		0xa01
+#define PM_SET_SUSPEND_MODE		0xa02
+#define PM_GET_TRUSTZONE_VERSION	0xa03
+
 /*********************************************************************
  * Enum definitions
  ********************************************************************/
@@ -101,6 +122,9 @@
 	/* PM Register Access API */
 	PM_REGISTER_ACCESS,
 	PM_EFUSE_ACCESS,
+	PM_FPGA_GET_VERSION,
+	PM_FPGA_GET_FEATURE_LIST,
+	PM_FEATURE_CHECK = 63,
 	PM_API_MAX
 };
 
@@ -241,7 +265,8 @@
 	PM_RET_ERROR_DOUBLE_REQ = 2004,
 	PM_RET_ERROR_ABORT_SUSPEND = 2005,
 	PM_RET_ERROR_TIMEOUT = 2006,
-	PM_RET_ERROR_NODE_USED = 2007
+	PM_RET_ERROR_NODE_USED = 2007,
+	PM_RET_ERROR_NO_FEATURE = 2008
 };
 
 /**
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index a49bda8..b789da1 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,12 +23,9 @@
 #include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
+#include "pm_defs.h"
 #include "pm_ipi.h"
 
-#define PM_GET_CALLBACK_DATA	0xa01
-#define PM_SET_SUSPEND_MODE	0xa02
-#define PM_GET_TRUSTZONE_VERSION	0xa03
-
 /* pm_up = !0 - UP, pm_up = 0 - DOWN */
 static int32_t pm_up, ipi_irq_flag;
 
@@ -262,8 +259,11 @@
 			uint64_t x4, void *cookie, void *handle, uint64_t flags)
 {
 	enum pm_ret_status ret;
+	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	uint32_t pm_arg[4];
+	uint32_t result[PAYLOAD_ARG_CNT];
+	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
 	if (!pm_up)
@@ -273,8 +273,11 @@
 	pm_arg[1] = (uint32_t)(x1 >> 32);
 	pm_arg[2] = (uint32_t)x2;
 	pm_arg[3] = (uint32_t)(x2 >> 32);
+	pm_arg[4] = (uint32_t)x3;
 
-	switch (smc_fid & FUNCID_NUM_MASK) {
+	api_id = smc_fid & FUNCID_NUM_MASK;
+
+	switch (api_id) {
 	/* PM API Functions */
 	case PM_SELF_SUSPEND:
 		ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
@@ -318,19 +321,11 @@
 		ret = pm_req_node(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
 
-	case PM_RELEASE_NODE:
-		ret = pm_release_node(pm_arg[0]);
-		SMC_RET1(handle, (uint64_t)ret);
-
 	case PM_SET_REQUIREMENT:
 		ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
 
-	case PM_SET_MAX_LATENCY:
-		ret = pm_set_max_latency(pm_arg[0], pm_arg[1]);
-		SMC_RET1(handle, (uint64_t)ret);
-
 	case PM_GET_API_VERSION:
 		/* Check is PM API version already verified */
 		if (pm_ctx.api_version >= PM_VERSION) {
@@ -348,62 +343,6 @@
 				 ((uint64_t)pm_ctx.api_version << 32));
 		}
 
-	case PM_SET_CONFIGURATION:
-		ret = pm_set_configuration(pm_arg[0]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_INIT_FINALIZE:
-		ret = pm_init_finalize();
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_GET_NODE_STATUS:
-	{
-		uint32_t buff[3];
-
-		ret = pm_get_node_status(pm_arg[0], buff);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buff[0] << 32),
-			 (uint64_t)buff[1] | ((uint64_t)buff[2] << 32));
-	}
-
-	case PM_GET_OP_CHARACTERISTIC:
-	{
-		uint32_t result;
-
-		ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32));
-	}
-
-	case PM_REGISTER_NOTIFIER:
-		ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],
-					   pm_arg[3]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_RESET_ASSERT:
-		ret = pm_reset_assert(pm_arg[0], pm_arg[1]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_RESET_GET_STATUS:
-	{
-		uint32_t reset_status;
-
-		ret = pm_reset_get_status(pm_arg[0], &reset_status);
-		SMC_RET1(handle, (uint64_t)ret |
-			 ((uint64_t)reset_status << 32));
-	}
-
-	/* PM memory access functions */
-	case PM_MMIO_WRITE:
-		ret = pm_mmio_write(pm_arg[0], pm_arg[1], pm_arg[2]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_MMIO_READ:
-	{
-		uint32_t value;
-
-		ret = pm_mmio_read(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
-	}
-
 	case PM_FPGA_LOAD:
 		ret = pm_fpga_load(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
@@ -416,62 +355,16 @@
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
 	}
 
-	case PM_GET_CHIPID:
-	{
-		uint32_t result[2];
-
-		ret = pm_get_chipid(result);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
-			 result[1]);
-	}
-
 	case PM_SECURE_RSA_AES:
 		ret = pm_secure_rsaaes(pm_arg[0], pm_arg[1], pm_arg[2],
 				       pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
 
 	case PM_GET_CALLBACK_DATA:
-	{
-		uint32_t result[4] = {0};
-
 		pm_get_callbackdata(result, ARRAY_SIZE(result));
 		SMC_RET2(handle,
 			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
-	}
-
-	case PM_PINCTRL_REQUEST:
-		ret = pm_pinctrl_request(pm_arg[0]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PINCTRL_RELEASE:
-		ret = pm_pinctrl_release(pm_arg[0]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PINCTRL_GET_FUNCTION:
-	{
-		uint32_t value = 0;
-
-		ret = pm_pinctrl_get_function(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
-	}
-
-	case PM_PINCTRL_SET_FUNCTION:
-		ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1]);
-		SMC_RET1(handle, (uint64_t)ret);
-
-	case PM_PINCTRL_CONFIG_PARAM_GET:
-	{
-		uint32_t value;
-
-		ret = pm_pinctrl_get_config(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
-	}
-
-	case PM_PINCTRL_CONFIG_PARAM_SET:
-		ret = pm_pinctrl_set_config(pm_arg[0], pm_arg[1], pm_arg[2]);
-		SMC_RET1(handle, (uint64_t)ret);
-
 	case PM_IOCTL:
 	{
 		uint32_t value;
@@ -568,8 +461,6 @@
 
 	case PM_SECURE_IMAGE:
 	{
-		uint32_t result[2];
-
 		ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], &result[0]);
 		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
@@ -634,9 +525,37 @@
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
 	}
 
+	case PM_FPGA_GET_VERSION:
+	case PM_FPGA_GET_FEATURE_LIST:
+	{
+		uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+		PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK,
+				 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
+		ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U);
+		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32,
+			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32);
+	}
+
+	case PM_FEATURE_CHECK:
+	{
+		uint32_t version;
+		uint32_t bit_mask[2] = {0};
+
+		ret = pm_feature_check(pm_arg[0], &version, bit_mask,
+				       ARRAY_SIZE(bit_mask));
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32),
+			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32));
+	}
+
 	default:
-		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
-		SMC_RET1(handle, SMC_UNK);
+		/* Send request to the PMU */
+		PM_PACK_PAYLOAD6(payload, api_id, pm_arg[0], pm_arg[1],
+				 pm_arg[2], pm_arg[3], pm_arg[4]);
+		ret = pm_ipi_send_sync(primary_proc, payload, result,
+				       PAYLOAD_ARG_CNT);
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
+			 (uint64_t)result[1] | ((uint64_t)result[2] << 32));
 	}
 }
 
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index bfee2dd..27a8382 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -90,6 +90,21 @@
 				 uint64_t x4,
 				 void *handle);
 
+/******************************************************************************
+ * Builds an SPMD to SPMC direct message request.
+ *****************************************************************************/
+void spmd_build_spmc_message(gp_regs_t *gpregs, uint8_t target_func,
+			     unsigned long long message)
+{
+	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
+	write_ctx_reg(gpregs, CTX_GPREG_X1,
+		(SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
+		 spmd_spmc_id_get());
+	write_ctx_reg(gpregs, CTX_GPREG_X2, BIT(31) | target_func);
+	write_ctx_reg(gpregs, CTX_GPREG_X3, message);
+}
+
+
 /*******************************************************************************
  * This function takes an SPMC context pointer and performs a synchronous
  * SPMC entry.
@@ -543,8 +558,59 @@
 			(ctx->state == SPMC_STATE_RESET)) {
 			ret = FFA_ERROR_NOT_SUPPORTED;
 		} else if (!secure_origin) {
-			ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
-					       spmc_attrs.minor_version);
+			gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
+			uint64_t rc;
+
+			if (spmc_attrs.major_version == 1 &&
+			    spmc_attrs.minor_version == 0) {
+				ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
+						       spmc_attrs.minor_version);
+				SMC_RET8(handle, (uint32_t)ret,
+					 FFA_TARGET_INFO_MBZ,
+					 FFA_TARGET_INFO_MBZ,
+					 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+					 FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+					 FFA_PARAM_MBZ);
+				break;
+			}
+			/* Save non-secure system registers context */
+			cm_el1_sysregs_context_save(NON_SECURE);
+#if SPMD_SPM_AT_SEL2
+			cm_el2_sysregs_context_save(NON_SECURE);
+#endif
+
+			/*
+			 * The incoming request has FFA_VERSION as X0 smc_fid
+			 * and requested version in x1. Prepare a direct request
+			 * from SPMD to SPMC with FFA_VERSION framework function
+			 * identifier in X2 and requested version in X3.
+			 */
+			spmd_build_spmc_message(gpregs,
+						SPMD_FWK_MSG_FFA_VERSION_REQ,
+						input_version);
+
+			rc = spmd_spm_core_sync_entry(ctx);
+
+			if ((rc != 0ULL) ||
+			    (SMC_GET_GP(gpregs, CTX_GPREG_X0) !=
+				FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
+			    (SMC_GET_GP(gpregs, CTX_GPREG_X2) !=
+				(SPMD_FWK_MSG_BIT |
+				 SPMD_FWK_MSG_FFA_VERSION_RESP))) {
+				ERROR("Failed to forward FFA_VERSION\n");
+				ret = FFA_ERROR_NOT_SUPPORTED;
+			} else {
+				ret = SMC_GET_GP(gpregs, CTX_GPREG_X3);
+			}
+
+			/*
+			 * Return here after SPMC has handled FFA_VERSION.
+			 * The returned SPMC version is held in X3.
+			 * Forward this version in X0 to the non-secure caller.
+			 */
+			return spmd_smc_forward(ret, true, FFA_PARAM_MBZ,
+						FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+						FFA_PARAM_MBZ, gpregs);
 		} else {
 			ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
 					       FFA_VERSION_MINOR);
diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
index 6ebafca..b719161 100644
--- a/services/std_svc/spmd/spmd_pm.c
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,21 +20,6 @@
 } g_spmd_pm;
 
 /*******************************************************************************
- * spmd_build_spmc_message
- *
- * Builds an SPMD to SPMC direct message request.
- ******************************************************************************/
-static void spmd_build_spmc_message(gp_regs_t *gpregs, unsigned long long message)
-{
-	write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
-	write_ctx_reg(gpregs, CTX_GPREG_X1,
-		(SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
-		spmd_spmc_id_get());
-	write_ctx_reg(gpregs, CTX_GPREG_X2, FFA_PARAM_MBZ);
-	write_ctx_reg(gpregs, CTX_GPREG_X3, message);
-}
-
-/*******************************************************************************
  * spmd_pm_secondary_ep_register
  ******************************************************************************/
 int spmd_pm_secondary_ep_register(uintptr_t entry_point)
@@ -137,7 +122,8 @@
 	assert(ctx->state != SPMC_STATE_OFF);
 
 	/* Build an SPMD to SPMC direct message request. */
-	spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx), PSCI_CPU_OFF);
+	spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx),
+				SPMD_FWK_MSG_PSCI, PSCI_CPU_OFF);
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 1fe5065..4cd6a74 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,6 +64,16 @@
 
 #define SPMD_DIRECT_MSG_ENDPOINT_ID		U(FFA_ENDPOINT_ID_MAX - 1)
 
+/* Define SPMD target function IDs for framework messages to the SPMC */
+#define SPMD_FWK_MSG_BIT			BIT(31)
+#define SPMD_FWK_MSG_PSCI			U(0)
+#define SPMD_FWK_MSG_FFA_VERSION_REQ		U(0x8)
+#define SPMD_FWK_MSG_FFA_VERSION_RESP		U(0x9)
+
+/* Function to build SPMD to SPMC message */
+void spmd_build_spmc_message(gp_regs_t *gpregs, uint8_t target,
+			     unsigned long long message);
+
 /* Functions used to enter/exit SPMC synchronously */
 uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx);
 __dead2 void spmd_spm_core_sync_exit(uint64_t rc);