feat(amd): add test for force powerdown EEMI API

Add tests for the EEMI APIs that handle force power down and request
wakeup within the TF-A test framework. The force power down API is
used to terminate an unresponsive subsystem and automatically release
its resources. The request wakeup API is used to power up a CPU node
within the same PU or to power up another PU.

Change-Id: I4fa6da87a3044c52834ab34621141cce5e136948
Signed-off-by: Madhav Bhatt <madhav.bhatt@amd.com>
diff --git a/tftf/tests/plat/amd/common/common_files/eemi_api.c b/tftf/tests/plat/amd/common/common_files/eemi_api.c
index 838b560..1d95bc6 100644
--- a/tftf/tests/plat/amd/common/common_files/eemi_api.c
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.c
@@ -525,3 +525,20 @@
 
 	return ret;
 }
+
+int xpm_force_powerdown(const uint32_t node_id, const uint32_t ack)
+{
+	uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+	return eemi_call(PM_FORCE_POWERDOWN, ((uint64_t)ack << 32 | node_id), 0,
+					      0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_request_wakeup(const uint32_t node_id, const uint32_t set_address,
+		       const uint32_t address, const uint32_t ack)
+{
+	uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+	return eemi_call(PM_REQUEST_WAKEUP, ((uint64_t)set_address << 32 | node_id),
+			 ((uint64_t)ack << 32 | address), 0, 0, 0, 0, 0, ret_payload);
+}
diff --git a/tftf/tests/plat/amd/common/common_files/eemi_api.h b/tftf/tests/plat/amd/common/common_files/eemi_api.h
index 650d326..5fb7b1f 100644
--- a/tftf/tests/plat/amd/common/common_files/eemi_api.h
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.h
@@ -102,5 +102,8 @@
 			  const uint32_t enable);
 int xpm_query_data(const uint32_t qid, const uint32_t arg1, const uint32_t arg2,
 		   const uint32_t arg3, uint32_t *output);
+int xpm_force_powerdown(const uint32_t node_id, const uint32_t ack);
+int xpm_request_wakeup(const uint32_t node_id, const uint32_t set_address, const uint32_t address,
+		       const uint32_t ack);
 
 #endif /* __EEMI_API_H__ */
diff --git a/tftf/tests/plat/amd/common/force_powerdown/force_powerdown.c b/tftf/tests/plat/amd/common/force_powerdown/force_powerdown.c
new file mode 100644
index 0000000..9cdb28e
--- /dev/null
+++ b/tftf/tests/plat/amd/common/force_powerdown/force_powerdown.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+#include "xpm_nodeid.h"
+
+#define PM_SUBSYS_RPU0_0	0x1C000005
+#define TARGET_SUBSYSTEM	PM_SUBSYS_RPU0_0
+#define TARGET_DEVICEID		PM_DEV_RPU0_0
+#define WAKEUP_ADDR		0xFFE00000U
+
+/*
+ * This function is used to force power down the subsystem if the
+ * subsystem is unresponsive and by calling this API all the resources of
+ * that subsystem will be automatically released.
+ *
+ * This function is used to force power down the subsystem if the
+ * subsystem is unresponsive. By calling this API, all the resources of
+ * that subsystem will be automatically released.
+ *
+ * Force power down support for individual processors and power domains has been
+ * deprecated. As a result, the only available option now is to force power down
+ * the entire subsystem.
+ *
+ * To support this, another subsystem (RPU) needs to be present. For example,
+ * the RPU subsystem can be added with only a NOP CDO (which contains only a
+ * single "nop" instruction). This allows the force power down feature to be
+ * tested without requiring an actual executable partition for the RPU.
+ */
+test_result_t test_force_powerdown(void)
+{
+	int32_t status;
+
+	status = xpm_force_powerdown(TARGET_SUBSYSTEM, 1);
+	if (status != PM_RET_SUCCESS) {
+		tftf_testcase_printf("%s ERROR force powering down system: 0x%x, "
+				     "Status: 0x%x\n", __func__, TARGET_SUBSYSTEM, status);
+		return TEST_RESULT_FAIL;
+	}
+
+	tftf_testcase_printf("Waiting for 10 seconds before waking up the target\n\r");
+	waitms(10000);
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function can be used to request power up of a CPU node
+ * within the same PU, or to power up another PU.
+ */
+test_result_t test_request_wake_up(void)
+{
+	int32_t status;
+
+	status = xpm_request_wakeup(TARGET_SUBSYSTEM, 1, WAKEUP_ADDR, 0);
+	if (status != PM_RET_SUCCESS) {
+		tftf_testcase_printf("%s ERROR requesting wake-up for %x, "
+				     "Status: 0x%x\n", __func__, TARGET_SUBSYSTEM, status);
+		return TEST_RESULT_FAIL;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-versal.xml b/tftf/tests/tests-versal.xml
index e8e4712..c18e558 100644
--- a/tftf/tests/tests-versal.xml
+++ b/tftf/tests/tests-versal.xml
@@ -42,6 +42,8 @@
       <testcase name="Set Wake Up Source" function="test_set_wakeup_source" />
       <testcase name="Self Suspend" function="test_self_suspend" />
       <testcase name="Query Data" function="test_query_data" />
+      <testcase name="Force Powerdown" function="test_force_powerdown" />
+      <testcase name="Request Wakeup" function="test_request_wake_up" />
     </testsuite>
 
   </testsuites>