Merge changes from topic "amd_pm_tests"
* changes:
feat(amd): add test for get reset status EEMI API
feat(amd): add test for force powerdown EEMI API
feat(amd): add test for query data EEMI API
feat(amd): add test for self suspend EEMI API
feat(amd): add test for pll EEMI APIs
feat(amd): add test for system shutdown EEMI API
feat(amd): add test for operating characteristics EEMI API
feat(amd): add test for TF-A register sgi API
feat(amd): add test for TF-A feature check API
feat(amd): add test for trustzone version API
feat(amd): add test for init finalize EEMI API
feat(amd): add test for pin EEMI APIs
feat(amd): add test for clock EEMI APIs
feat(amd): add test for node EEMI APIs
feat(amd): add test for IOCTL EEMI API
feat(amd): add test for register notifier EEMI API
feat(amd): add platform specific test cases
diff --git a/tftf/tests/plat/amd/common/clock_test/clock_test.c b/tftf/tests/plat/amd/common/clock_test/clock_test.c
new file mode 100644
index 0000000..863da5a
--- /dev/null
+++ b/tftf/tests/plat/amd/common/clock_test/clock_test.c
@@ -0,0 +1,191 @@
+/*
+ * 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_CLOCK_ENABLE 1U
+#define PM_CLOCK_DISABLE 0U
+
+struct test_clocks {
+ uint32_t clock_id;
+ uint32_t device_id;
+};
+
+struct test_clocks test_clock_list[] = {
+ {
+ .clock_id = PM_CLK_QSPI_REF,
+ .device_id = PM_DEV_QSPI,
+ },
+ {
+ .clock_id = PM_CLK_GEM0_REF,
+ .device_id = PM_DEV_GEM_0,
+ },
+};
+
+/*
+ * This function will test the clock apis without requesting the device.
+ * function should return an error when enabling the clock of a node
+ * that is not requested.
+ */
+test_result_t test_clock_control_without_device_request(void)
+{
+ int32_t test_clock_num = ARRAY_SIZE(test_clock_list);
+ uint32_t result = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_clock_num; i++) {
+ uint32_t clock_id = test_clock_list[i].clock_id;
+ uint32_t device_id = test_clock_list[i].device_id;
+
+ status = xpm_clock_get_status(clock_id, &result);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the clock status of 0x%x clockid, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (result == PM_CLOCK_ENABLE) {
+ status = xpm_clock_disable(clock_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to disable 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(device_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, device_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ status = xpm_clock_enable(clock_id);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR clock 0x%x enabled without device request, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function will test clock apis after requesting the device.
+ * First it will request a device later it will test all controls of
+ * clock api like enabling, disabling, set parent, get parent,
+ * set divider, get divider etc., after performing all clock apis it
+ * will disable the particular clock.
+ */
+test_result_t test_clock_control_with_device_request(void)
+{
+ int32_t test_clock_num = ARRAY_SIZE(test_clock_list);
+ int32_t parent_id = 1U;
+ int32_t divider = 10U;
+ uint32_t result = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_clock_num; i++) {
+ uint32_t clock_id = test_clock_list[i].clock_id;
+ uint32_t device_id = test_clock_list[i].device_id;
+
+ status = xpm_clock_get_status(clock_id, &result);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the clock status of 0x%x clockid, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_request_node(device_id, PM_CAP_ACCESS, 0, 0);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, device_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_enable(clock_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to enable 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_disable(clock_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to disable 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_get_status(clock_id, &result);
+ if (status != PM_RET_SUCCESS || result != PM_CLOCK_DISABLE) {
+ tftf_testcase_printf("%s ERROR to get the clock status of 0x%x clockid, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_enable(clock_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to enable 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_get_status(clock_id, &result);
+ if (status != PM_RET_SUCCESS || result != PM_CLOCK_ENABLE) {
+ tftf_testcase_printf("%s ERROR to get the clock status of 0x%x clockid, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_set_parent(clock_id, parent_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the parent for 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_get_parent(clock_id, &result);
+ if (status != PM_RET_SUCCESS || parent_id != result) {
+ tftf_testcase_printf("%s ERROR to get the parent for 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_set_divider(clock_id, divider);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the divider for 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_get_divider(clock_id, &result);
+ if (status != PM_RET_SUCCESS || divider != result) {
+ tftf_testcase_printf("%s ERROR to set the divider for 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_clock_disable(clock_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to disable 0x%x clock, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(device_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, device_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/common_files/eemi_api.c b/tftf/tests/plat/amd/common/common_files/eemi_api.c
new file mode 100644
index 0000000..6fac33e
--- /dev/null
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+xpm_notifier * notifier_store = NULL;
+
+static int do_feature_check(const uint32_t api_id)
+{
+ smc_args args;
+ smc_ret_values ret;
+
+ args.fid = (PM_SIP_SVC | PM_FEATURE_CHECK);
+ args.arg1 = api_id;
+
+ ret = tftf_smc(&args);
+
+ return lower_32_bits(ret.ret0);
+}
+
+static int eemi_call(const uint32_t arg0, const uint64_t arg1, const uint64_t arg2,
+ const uint64_t arg3, const uint64_t arg4, const uint64_t arg5,
+ const uint64_t arg6, const uint64_t arg7,
+ uint32_t *const ret_payload)
+{
+ smc_args args;
+ smc_ret_values ret;
+ int32_t status;
+
+ args.fid = (PM_SIP_SVC | arg0);
+ args.arg1 = arg1;
+ args.arg2 = arg2;
+ args.arg3 = arg3;
+ args.arg4 = arg4;
+ args.arg5 = arg5;
+ args.arg6 = arg6;
+ args.arg7 = arg7;
+
+ /*
+ * 'arg0' represents the API ID. This check ensures that the API is supported
+ * by TF-A/PLM before making the actual API call.
+ */
+ status = do_feature_check(arg0);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR Status:0x%x, Feature Check Failed for "
+ "API Id:0x%x\n", __func__, status, arg0);
+ return status;
+ }
+
+ ret = tftf_smc(&args);
+
+ if (ret_payload) {
+ ret_payload[0] = lower_32_bits(ret.ret0);
+ ret_payload[1] = upper_32_bits(ret.ret0);
+ ret_payload[2] = lower_32_bits(ret.ret1);
+ ret_payload[3] = upper_32_bits(ret.ret1);
+ ret_payload[4] = lower_32_bits(ret.ret2);
+ ret_payload[5] = upper_32_bits(ret.ret2);
+ ret_payload[6] = lower_32_bits(ret.ret3);
+ }
+
+ return lower_32_bits(ret.ret0);
+}
+
+int xpm_get_api_version(uint32_t *version)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_GET_API_VERSION, 0, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *version = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_get_chip_id(uint32_t *id_code, uint32_t *version)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_GET_CHIPID, 0, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS) {
+ *id_code = ret_payload[1];
+ *version = ret_payload[2];
+ }
+
+ return ret;
+}
+
+int xpm_feature_check(const uint32_t api_id, uint32_t *const version)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_FEATURE_CHECK, api_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *version = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_request_node(const uint32_t device_id, const uint32_t capabilities,
+ const uint32_t qos, const uint32_t ack)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_REQUEST_NODE, ((uint64_t)capabilities << 32 | device_id),
+ ((uint64_t)ack << 32 | qos), 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_release_node(const uint32_t device_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_RELEASE_NODE, device_id, 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_set_requirement(const uint32_t device_id, const uint32_t capabilities,
+ const uint32_t qos, const uint32_t ack)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_SET_REQUIREMENT, ((uint64_t)capabilities << 32 | device_id),
+ ((uint64_t)ack << 32 | qos), 0, 0, 0, 0, 0, ret_payload);
+}
+
+irq_handler_t xpm_notifier_cb(void *data)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ /* Get the IPI payload from TF-A */
+ (void)eemi_call(PM_GET_CALLBACK_DATA, 0, 0, 0, 0, 0, 0, 0, ret_payload);
+
+ if (!notifier_store)
+ return NULL;
+
+ if (ret_payload[0] != PM_NOTIFY_CB) {
+ notifier_store->received = 0;
+ tftf_testcase_printf("unexpected callback type\n");
+ } else {
+ notifier_store->received = 1;
+ }
+
+ (void)notifier_store->callback(notifier_store);
+
+ return 0;
+}
+
+int xpm_register_notifier(xpm_notifier * const notifier)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ uint32_t wake = 1U;
+ uint32_t enable = 1U;
+ uint32_t sgi_num = NOTIFIER_SGI;
+ uint32_t reset = 0U;
+ int ret;
+
+ if (!notifier)
+ return PM_RET_ERROR_ARGS;
+
+ /* Save the pointer to the structure so the notifier handler can access it */
+ notifier_store = notifier;
+
+ ret = tftf_irq_register_handler(sgi_num, (irq_handler_t)xpm_notifier_cb);
+ if (ret != PM_RET_SUCCESS) {
+ tftf_testcase_printf("failed to register the irq handler\n");
+ return ret;
+ }
+
+ tftf_irq_enable(sgi_num, IRQ_PRIORITY);
+
+ /* Register PM event notifier */
+ ret = eemi_call(PM_REGISTER_NOTIFIER, ((uint64_t)notifier->event << 32 | notifier->node),
+ ((uint64_t)enable << 32 | wake), 0, 0, 0, 0, 0, ret_payload);
+ if (ret != PM_RET_SUCCESS) {
+ tftf_testcase_printf("failed to register the event notifier\n");
+ return ret;
+ }
+
+ /* Register the SGI number with TF-A */
+ ret = eemi_call(TF_A_PM_REGISTER_SGI, ((uint64_t)reset << 32 | sgi_num),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret != PM_RET_SUCCESS)
+ tftf_testcase_printf("failed to register the SGI with TF-A\n");
+
+ return ret;
+}
+
+int xpm_unregister_notifier(xpm_notifier * const notifier)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ uint32_t wake = 0U;
+ uint32_t enable = 0U;
+ uint32_t reset = 1U;
+ int ret;
+
+ /* Unregister PM event notifier */
+ ret = eemi_call(PM_REGISTER_NOTIFIER, ((uint64_t)notifier->event << 32 | notifier->node),
+ ((uint64_t)enable << 32 | wake), 0, 0, 0, 0, 0, ret_payload);
+ if (ret != PM_RET_SUCCESS) {
+ tftf_testcase_printf("failed to unregister the event notifier\n");
+ return ret;
+ }
+
+ /* Unregister the SGI number with TF-A */
+ ret = eemi_call(TF_A_PM_REGISTER_SGI, ((uint64_t)reset << 32 | 0),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret != PM_RET_SUCCESS) {
+ tftf_testcase_printf("failed to unregister the SGI with TF-A\n");
+ return ret;
+ }
+
+ tftf_irq_disable(NOTIFIER_SGI);
+
+ tftf_irq_unregister_handler(NOTIFIER_SGI);
+ if (ret != PM_RET_SUCCESS)
+ tftf_testcase_printf("failed to unregister the IRQ handler\n");
+
+ return ret;
+}
+
+int xpm_ioctl(const uint32_t node_id, const uint32_t ioctl_id, const uint32_t arg1,
+ const uint32_t arg2, uint32_t *const response)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_IOCTL, ((uint64_t)ioctl_id << 32 | node_id),
+ ((uint64_t)arg2 << 32 | arg1), 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *response = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_set_max_latency(const uint32_t device_id, const uint32_t latency)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_SET_MAX_LATENCY, ((uint64_t)latency << 32 | device_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_get_node_status(const uint32_t device_id, xpm_node_status * const node_status)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ if (!node_status)
+ return PM_RET_ERROR_ARGS;
+
+ ret = eemi_call(PM_GET_NODE_STATUS, device_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ node_status->status = ret_payload[1];
+ node_status->requirements = ret_payload[2];
+ node_status->usage = ret_payload[3];
+
+ return ret;
+}
+
+int xpm_clock_get_status(const uint32_t clock_id, uint32_t *const state)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_CLOCK_GETSTATE, clock_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *state = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_clock_enable(const uint32_t clock_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_clock_disable(const uint32_t clock_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_clock_set_parent(const uint32_t clock_id, const uint32_t parent_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_CLOCK_SETPARENT, ((uint64_t)parent_id << 32 | clock_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_clock_get_parent(const uint32_t clock_id, uint32_t *const parent_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_CLOCK_GETPARENT, clock_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *parent_id = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_clock_set_divider(const uint32_t clock_id, const uint32_t divider)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_CLOCK_SETDIVIDER, ((uint64_t)divider << 32 | clock_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_clock_get_divider(const uint32_t clock_id, uint32_t *const divider)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_CLOCK_GETDIVIDER, clock_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *divider = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_pinctrl_set_function(const uint32_t pin_id, const uint32_t function_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_PINCTRL_SET_FUNCTION, ((uint64_t)function_id << 32 | pin_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_pinctrl_get_function(const uint32_t pin_id, uint32_t *const function_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int32_t ret;
+
+ ret = eemi_call(PM_PINCTRL_GET_FUNCTION, pin_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *function_id = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_pinctrl_request(const uint32_t pin_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_PINCTRL_REQUEST, pin_id, 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_pinctrl_release(const uint32_t pin_id)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_PINCTRL_RELEASE, pin_id, 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_reset_assert(const uint32_t reset_id, const uint32_t action)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_RESET_ASSERT, ((uint64_t)action << 32 | reset_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_pinctrl_get_parameter(const uint32_t pin_id, const uint32_t param_id,
+ uint32_t *const param_val)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int32_t ret;
+
+ ret = eemi_call(PM_PINCTRL_CONFIG_PARAM_GET, ((uint64_t)param_id << 32 | pin_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *param_val = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_pinctrl_set_parameter(const uint32_t pin_id, const uint32_t param_id,
+ const uint32_t param_val)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_PINCTRL_CONFIG_PARAM_SET, ((uint64_t)param_id << 32 | pin_id),
+ param_val, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_init_finalize(void)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_INIT_FINALIZE, 0, 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int get_trustzone_version(uint32_t *tz_version)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_GET_TRUSTZONE_VERSION, 0, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *tz_version = ret_payload[1];
+
+ return ret;
+}
+
+int tf_a_feature_check(const uint32_t api_id, uint32_t *const version)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(TF_A_FEATURE_CHECK, api_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *version = ret_payload[1];
+
+ return ret;
+}
+
+int tf_a_pm_register_sgi(uint32_t sgi_num, uint32_t reset)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(TF_A_PM_REGISTER_SGI, ((uint64_t)reset << 32 | sgi_num),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_op_characteristics(uint32_t const device_id, uint32_t const type, uint32_t *result)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_GET_OP_CHARACTERISTIC, ((uint64_t)type << 32 | device_id),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *result = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_system_shutdown(const uint32_t type, const uint32_t subtype)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_SYSTEM_SHUTDOWN, ((uint64_t)subtype << 32 | type),
+ 0, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_pll_set_parameter(const uint32_t clock_id, const uint32_t param_id, const uint32_t value)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_PLL_SET_PARAMETER, ((uint64_t)param_id << 32 | clock_id),
+ value, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_pll_get_parameter(const uint32_t clock_id, const uint32_t param_id, uint32_t *value)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_PLL_GET_PARAMETER, clock_id, param_id, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *value = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_pll_set_mode(const uint32_t clock_id, const uint32_t value)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_PLL_SET_MODE, ((uint64_t)value << 32 | clock_id), 0,
+ 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_pll_get_mode(const uint32_t clock_id, uint32_t *value)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_PLL_GET_MODE, clock_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *value = ret_payload[1];
+
+ return ret;
+}
+
+int xpm_self_suspend(const uint32_t device_id, const uint32_t latency, const uint8_t state,
+ uint32_t address)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_SELF_SUSPEND, ((uint64_t)latency << 32 | device_id),
+ (uint64_t)address << 32 | state, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_set_wakeup_source(const uint32_t target_node_id, const uint32_t source_node_id,
+ const uint32_t enable)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+
+ return eemi_call(PM_SET_WAKEUP_SOURCE, ((uint64_t)source_node_id << 32 | target_node_id),
+ enable, 0, 0, 0, 0, 0, ret_payload);
+}
+
+int xpm_query_data(const uint32_t qid, const uint32_t arg1, const uint32_t arg2,
+ const uint32_t arg3, uint32_t *output)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int32_t ret;
+
+ ret = eemi_call(PM_QUERY_DATA, qid, arg1, arg2, arg3, 0, 0, 0, ret_payload);
+ *output = ret_payload[1];
+
+ 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);
+}
+
+int xpm_reset_get_status(const uint32_t reset_id, uint32_t *status)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int32_t ret;
+
+ ret = eemi_call(PM_RESET_GET_STATUS, reset_id, 0, 0, 0, 0, 0, 0, ret_payload);
+ *status = ret_payload[1];
+
+ return ret;
+}
diff --git a/tftf/tests/plat/amd/common/common_files/eemi_api.h b/tftf/tests/plat/amd/common/common_files/eemi_api.h
new file mode 100644
index 0000000..8527a2e
--- /dev/null
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __EEMI_API_H__
+#define __EEMI_API_H__
+
+#include "xpm_defs.h"
+
+typedef struct xpm_notifier {
+ void(*const callback)(struct xpm_notifier * const notifier); /**< Callback handler */
+ const uint32_t node; /**< Node to receive notifications about */
+ uint32_t event; /**< Event type to receive notifications about */
+ uint32_t received_event; /**< Event received from PLM */
+ uint32_t flags; /**< Flags */
+ uint32_t oppoint; /**< Operating point in node */
+ uint32_t received; /**< How many times the notification has been received */
+ struct xpm_notifier *next; /**< Pointer to next notifier in linked list */
+} xpm_notifier;
+
+struct test_ioctl {
+ uint32_t node_id; /**< Node ID */
+ uint32_t ioctl_id; /**< Ioctl ID */
+ uint32_t ioctl_arg1; /**< Arg1 for Ioctl-ID if required */
+ uint32_t ioctl_arg2; /**< Arg2 for Ioctl-ID if required */
+};
+
+typedef struct xpm_ndstatus {
+ uint32_t status; /**< Node power state */
+ uint32_t requirements; /**< Requirements on node (slaves only) */
+ uint32_t usage; /**< Indicates which master is using the slave */
+} xpm_node_status;
+
+struct register_sgi {
+ uint32_t sgi_num; /**< SGI number to be used for communication */
+ uint32_t reset; /**< Reset to invalid SGI when reset=1 */
+};
+
+struct sys_shutdown {
+ uint32_t shutdown_type; /**< Shutdown type (shutdown/restart) */
+ uint32_t shutdown_subtype; /**< Shutdown subtype (subsystem-only/PU-only/system) */
+};
+
+struct test_pll_api {
+ uint32_t clock_id; /**< Clock ID */
+};
+
+struct test_query {
+ uint32_t query_id; /**< Query ID */
+ uint32_t query_arg1; /**< Arg1 for Query-ID if required */
+ uint32_t query_arg2; /**< Arg2 for Query-ID if required */
+ uint32_t query_arg3; /**< Arg3 for Query-ID if required */
+};
+
+int xpm_get_api_version(uint32_t *version);
+int xpm_get_chip_id(uint32_t *id_code, uint32_t *version);
+int xpm_feature_check(const uint32_t api_id, uint32_t *const version);
+int xpm_request_node(const uint32_t device_id, const uint32_t capabilities,
+ const uint32_t qos, const uint32_t ack);
+int xpm_release_node(const uint32_t device_id);
+int xpm_set_requirement(const uint32_t device_id, const uint32_t capabilities,
+ const uint32_t qos, const uint32_t ack);
+int xpm_register_notifier(xpm_notifier * const notifier);
+int xpm_unregister_notifier(xpm_notifier * const notifier);
+int xpm_ioctl(const uint32_t node_id, const uint32_t ioctl_id, const uint32_t arg1,
+ const uint32_t arg2, uint32_t *const response);
+int xpm_set_max_latency(const uint32_t device_id, const uint32_t latency);
+int xpm_get_node_status(const uint32_t device_id, xpm_node_status * const node_status);
+int xpm_clock_get_status(const uint32_t clock_id, uint32_t *const state);
+int xpm_clock_enable(const uint32_t clock_id);
+int xpm_clock_disable(const uint32_t clock_id);
+int xpm_clock_set_parent(const uint32_t clock_id, const uint32_t parent_id);
+int xpm_clock_get_parent(const uint32_t clock_id, uint32_t *const parent_id);
+int xpm_clock_set_divider(const uint32_t clock_id, const uint32_t divider);
+int xpm_clock_get_divider(const uint32_t clock_id, uint32_t *const divider);
+int xpm_pinctrl_set_function(const uint32_t pin_id, const uint32_t function_id);
+int xpm_pinctrl_get_function(const uint32_t pin_id, uint32_t *const function_id);
+int xpm_pinctrl_request(const uint32_t pin_id);
+int xpm_pinctrl_release(const uint32_t pin_id);
+int xpm_reset_assert(const uint32_t reset_id, const uint32_t action);
+int xpm_pinctrl_get_parameter(const uint32_t pin_id, const uint32_t param_id,
+ uint32_t *const param_val);
+int xpm_pinctrl_set_parameter(const uint32_t pin_id, const uint32_t param_id,
+ const uint32_t param_val);
+int xpm_init_finalize(void);
+int get_trustzone_version(uint32_t *tz_version);
+int tf_a_feature_check(const uint32_t api_id, uint32_t *const version);
+int tf_a_pm_register_sgi(uint32_t sgi_num, uint32_t reset);
+int xpm_op_characteristics(uint32_t const device_id, uint32_t const type, uint32_t *result);
+int xpm_system_shutdown(const uint32_t type, const uint32_t subtype);
+int xpm_pll_set_parameter(const uint32_t clock_id, const uint32_t param_id,
+ const uint32_t value);
+int xpm_pll_get_parameter(const uint32_t clock_id, const uint32_t param_id,
+ uint32_t *value);
+int xpm_pll_set_mode(const uint32_t clock_id, const uint32_t value);
+int xpm_pll_get_mode(const uint32_t clock_id, uint32_t *value);
+int xpm_self_suspend(const uint32_t device_id, const uint32_t latency,
+ const uint8_t state, uint32_t address);
+int xpm_set_wakeup_source(const uint32_t target_node_id, const uint32_t source_node_id,
+ 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);
+int xpm_reset_get_status(const uint32_t reset_id, uint32_t *status);
+
+#endif /* __EEMI_API_H__ */
diff --git a/tftf/tests/plat/amd/common/common_files/xpm_defs.h b/tftf/tests/plat/amd/common/common_files/xpm_defs.h
new file mode 100644
index 0000000..ee9d725
--- /dev/null
+++ b/tftf/tests/plat/amd/common/common_files/xpm_defs.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef XPM_DEFS_H_
+#define XPM_DEFS_H_
+
+#include <irq.h>
+#include <smccc.h>
+#include <tftf_lib.h>
+
+#define PM_SIP_SVC 0xC2000000U
+#define PAYLOAD_ARG_CNT 7U
+#define NOTIFIER_SGI 15U
+#define IRQ_PRIORITY 0U
+#define PM_MAX_QOS 100
+
+#define upper_32_bits(n) ((uint32_t)(((n) >> 32U)))
+#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffffU))
+
+#define VERSION_MAJOR(v) ((v) >> 16)
+#define VERSION_MINOR(v) ((v) & 0xFFFF)
+
+#define PM_RET_SUCCESS 0U
+#define PM_RET_ERROR_ARGS 1U
+#define PM_NO_ACCESS 2002L
+#define PM_ERR_VERSION 2014L
+
+/* TF-A only commands */
+#define TF_A_FEATURE_CHECK 0xa00U
+#define PM_GET_CALLBACK_DATA 0xa01U
+#define PM_GET_TRUSTZONE_VERSION 0xa03U
+#define TF_A_PM_REGISTER_SGI 0xa04U
+
+/* RPU operation mode */
+#define XPM_RPU_MODE_LOCKSTEP 0U
+#define XPM_RPU_MODE_SPLIT 1U
+
+/* Requirement limits */
+#define XPM_MAX_LATENCY 0xFFFFU
+
+/* SGI number used for Event management driver */
+#define XLNX_EVENT_SGI_NUM (15)
+
+/**
+ * System shutdown macros
+ */
+#define PM_SHUTDOWN_TYPE_SHUTDOWN (0U)
+#define PM_SHUTDOWN_TYPE_RESET (1U)
+
+#define PM_SHUTDOWN_SUBTYPE_RST_SUBSYSTEM (0U)
+#define PM_SHUTDOWN_SUBTYPE_RST_PS_ONLY (1U)
+#define PM_SHUTDOWN_SUBTYPE_RST_SYSTEM (2U)
+
+/**
+ * State arguments of the self suspend
+ */
+#define PM_SUSPEND_STATE_CPU_IDLE 0x0U
+#define PM_SUSPEND_STATE_CPU_OFF 0x1U
+#define PM_SUSPEND_STATE_SUSPEND_TO_RAM 0xFU
+
+/* API IDs */
+enum pm_api_id {
+ PM_API_MIN, /**< 0x0 */
+ PM_GET_API_VERSION, /**< 0x1 */
+ PM_SET_CONFIGURATION, /**< 0x2 */
+ PM_GET_NODE_STATUS, /**< 0x3 */
+ PM_GET_OP_CHARACTERISTIC, /**< 0x4 */
+ PM_REGISTER_NOTIFIER, /**< 0x5 */
+ PM_REQUEST_SUSPEND, /**< 0x6 */
+ PM_SELF_SUSPEND, /**< 0x7 */
+ PM_FORCE_POWERDOWN, /**< 0x8 */
+ PM_ABORT_SUSPEND, /**< 0x9 */
+ PM_REQUEST_WAKEUP, /**< 0xA */
+ PM_SET_WAKEUP_SOURCE, /**< 0xB */
+ PM_SYSTEM_SHUTDOWN, /**< 0xC */
+ PM_REQUEST_NODE, /**< 0xD */
+ PM_RELEASE_NODE, /**< 0xE */
+ PM_SET_REQUIREMENT, /**< 0xF */
+ PM_SET_MAX_LATENCY, /**< 0x10 */
+ PM_RESET_ASSERT, /**< 0x11 */
+ PM_RESET_GET_STATUS, /**< 0x12 */
+ PM_MMIO_WRITE, /**< 0x13 */
+ PM_MMIO_READ, /**< 0x14 */
+ PM_INIT_FINALIZE, /**< 0x15 */
+ PM_FPGA_LOAD, /**< 0x16 */
+ PM_FPGA_GET_STATUS, /**< 0x17 */
+ PM_GET_CHIPID, /**< 0x18 */
+ PM_SECURE_RSA_AES, /**< 0x19 */
+ PM_SECURE_SHA, /**< 0x1A */
+ PM_SECURE_RSA, /**< 0x1B */
+ PM_PINCTRL_REQUEST, /**< 0x1C */
+ PM_PINCTRL_RELEASE, /**< 0x1D */
+ PM_PINCTRL_GET_FUNCTION, /**< 0x1E */
+ PM_PINCTRL_SET_FUNCTION, /**< 0x1F */
+ PM_PINCTRL_CONFIG_PARAM_GET, /**< 0x20 */
+ PM_PINCTRL_CONFIG_PARAM_SET, /**< 0x21 */
+ PM_IOCTL, /**< 0x22 */
+ PM_QUERY_DATA, /**< 0x23 */
+ PM_CLOCK_ENABLE, /**< 0x24 */
+ PM_CLOCK_DISABLE, /**< 0x25 */
+ PM_CLOCK_GETSTATE, /**< 0x26 */
+ PM_CLOCK_SETDIVIDER, /**< 0x27 */
+ PM_CLOCK_GETDIVIDER, /**< 0x28 */
+ PM_CLOCK_SETRATE, /**< 0x29 */
+ /* PM_CLOCK_GETRATE API is deprecated */
+ PM_RESERVE_ID, /**< 0x2A */
+ PM_CLOCK_SETPARENT, /**< 0x2B */
+ PM_CLOCK_GETPARENT, /**< 0x2C */
+ PM_SECURE_IMAGE, /**< 0x2D */
+ PM_FPGA_READ, /**< 0x2E */
+ PM_SECURE_AES, /**< 0x2F */
+ PM_PLL_SET_PARAMETER, /**< 0x30 */
+ PM_PLL_GET_PARAMETER, /**< 0x31 */
+ PM_PLL_SET_MODE, /**< 0x32 */
+ PM_PLL_GET_MODE, /**< 0x33 */
+ PM_REGISTER_ACCESS, /**< 0x34 */
+ PM_EFUSE_ACCESS, /**< 0x35 */
+ PM_ADD_SUBSYSTEM, /**< 0x36 */
+ PM_DESTROY_SUBSYSTEM, /**< 0x37 */
+ PM_DESCRIBE_NODES, /**< 0x38 */
+ PM_ADD_NODE, /**< 0x39 */
+ PM_ADD_NODE_PARENT, /**< 0x3A */
+ PM_ADD_NODE_NAME, /**< 0x3B */
+ PM_ADD_REQUIREMENT, /**< 0x3C */
+ PM_SET_CURRENT_SUBSYSTEM, /**< 0x3D */
+ PM_INIT_NODE, /**< 0x3E */
+ PM_FEATURE_CHECK, /**< 0x3F */
+ PM_ISO_CONTROL, /**< 0x40 */
+ PM_ACTIVATE_SUBSYSTEM, /**< 0x41 */
+ PM_SET_NODE_ACCESS, /**< 0x42 */
+ PM_BISR, /**< 0x43 */
+ PM_APPLY_TRIM, /**< 0x44 */
+ PM_NOC_CLOCK_ENABLE, /**< 0x45 */
+ PM_IF_NOC_CLOCK_ENABLE, /**< 0x46 */
+ PM_FORCE_HOUSECLEAN, /**< 0x47 */
+ PM_FPGA_GET_VERSION, /**< 0x48 */
+ PM_FPGA_GET_FEATURE_LIST, /**< 0x49 */
+ PM_HNICX_NPI_DATA_XFER, /**< 0x4A */
+ PM_API_MAX /**< 0x4B */
+};
+
+/**
+ * Pin Function IDs
+ */
+enum pm_pin_fun_ids {
+ PIN_FUNC_SPI0, /**< Pin function ID of SPI0 */
+ PIN_FUNC_SPI0_SS, /**< Pin function ID of SPI0_SS */
+ PIN_FUNC_SPI1, /**< Pin function ID of SPI1 */
+ PIN_FUNC_SPI1_SS, /**< Pin function ID of SPI1_SS */
+ PIN_FUNC_CAN0, /**< Pin function ID of CAN0 */
+ PIN_FUNC_CAN1, /**< Pin function ID of CAN1 */
+ PIN_FUNC_I2C0, /**< Pin function ID of I2C0 */
+ PIN_FUNC_I2C1, /**< Pin function ID of I2C1 */
+ PIN_FUNC_I2C_PMC, /**< Pin function ID of I2C_PMC */
+ PIN_FUNC_TTC0_CLK, /**< Pin function ID of TTC0_CLK */
+ PIN_FUNC_TTC0_WAV, /**< Pin function ID of TTC0_WAV */
+ PIN_FUNC_TTC1_CLK, /**< Pin function ID of TTC1_CLK */
+ PIN_FUNC_TTC1_WAV, /**< Pin function ID of TTC1_WAV */
+ PIN_FUNC_TTC2_CLK, /**< Pin function ID of TTC2_CLK */
+ PIN_FUNC_TTC2_WAV, /**< Pin function ID of TTC2_WAV */
+ PIN_FUNC_TTC3_CLK, /**< Pin function ID of TTC3_CLK */
+ PIN_FUNC_TTC3_WAV, /**< Pin function ID of TTC3_WAV */
+ PIN_FUNC_WWDT0, /**< Pin function ID of WWDT0 */
+ PIN_FUNC_WWDT1, /**< Pin function ID of WWDT1 */
+ PIN_FUNC_SYSMON_I2C0, /**< Pin function ID of SYSMON_I2C0 */
+ PIN_FUNC_SYSMON_I2C0_ALERT, /**< Pin function ID of SYSMON_I2C0_AL */
+ PIN_FUNC_UART0, /**< Pin function ID of UART0 */
+ PIN_FUNC_UART0_CTRL, /**< Pin function ID of UART0_CTRL */
+ PIN_FUNC_UART1, /**< Pin function ID of UART1 */
+ PIN_FUNC_UART1_CTRL, /**< Pin function ID of UART1_CTRL */
+ PIN_FUNC_GPIO0, /**< Pin function ID of GPIO0 */
+ PIN_FUNC_GPIO1, /**< Pin function ID of GPIO1 */
+ PIN_FUNC_GPIO2, /**< Pin function ID of GPIO2 */
+ PIN_FUNC_EMIO0, /**< Pin function ID of EMIO0 */
+ PIN_FUNC_GEM0, /**< Pin function ID of GEM0 */
+ PIN_FUNC_GEM1, /**< Pin function ID of GEM1 */
+ PIN_FUNC_TRACE0, /**< Pin function ID of TRACE0 */
+ PIN_FUNC_TRACE0_CLK, /**< Pin function ID of TRACE0_CLK */
+ PIN_FUNC_MDIO0, /**< Pin function ID of MDIO0 */
+ PIN_FUNC_MDIO1, /**< Pin function ID of MDIO1 */
+ PIN_FUNC_GEM_TSU0, /**< Pin function ID of GEM_TSU0 */
+ PIN_FUNC_PCIE0, /**< Pin function ID of PCIE0 */
+ PIN_FUNC_SMAP0, /**< Pin function ID of SMAP0 */
+ PIN_FUNC_USB0, /**< Pin function ID of USB0 */
+ PIN_FUNC_SD0, /**< Pin function ID of SD0 */
+ PIN_FUNC_SD0_PC, /**< Pin function ID of SD0_PC */
+ PIN_FUNC_SD0_CD, /**< Pin function ID of SD0_CD */
+ PIN_FUNC_SD0_WP, /**< Pin function ID of SD0_WP */
+ PIN_FUNC_SD1, /**< Pin function ID of SD1 */
+ PIN_FUNC_SD1_PC, /**< Pin function ID of SD1_PC */
+ PIN_FUNC_SD1_CD, /**< Pin function ID of SD1_CD */
+ PIN_FUNC_SD1_WP, /**< Pin function ID of SD1_WP */
+ PIN_FUNC_OSPI0, /**< Pin function ID of OSPI0 */
+ PIN_FUNC_OSPI0_SS, /**< Pin function ID of OSPI0_SS */
+ PIN_FUNC_QSPI0, /**< Pin function ID of QSPI0 */
+ PIN_FUNC_QSPI0_FBCLK, /**< Pin function ID of QSPI0_FBCLK */
+ PIN_FUNC_QSPI0_SS, /**< Pin function ID of QSPI0_SS */
+ PIN_FUNC_TEST_CLK, /**< Pin function ID of TEST_CLK */
+ PIN_FUNC_TEST_SCAN, /**< Pin function ID of TEST_SCAN */
+ PIN_FUNC_TAMPER_TRIGGER, /**< Pin function ID of TAMPER_TRIGGER */
+ MAX_FUNCTION, /**< Max Pin function */
+};
+
+/* Node capabilities */
+#define PM_CAP_ACCESS 1U
+#define PM_CAP_CONTEXT 2U
+
+/*
+ * PM notify events
+ */
+enum xpm_notify_event {
+ EVENT_STATE_CHANGE = 1U, /**< State change event */
+ EVENT_ZERO_USERS = 2U, /**< Zero user event */
+ EVENT_CPU_IDLE_FORCE_PWRDWN = 4U, /**< CPU idle event during force pwr down */
+};
+
+/**
+ * PM API callback IDs
+ */
+enum pm_api_cb_id {
+ PM_INIT_SUSPEND_CB = 30U, /**< Suspend callback */
+ PM_ACKNOWLEDGE_CB = 31U, /**< Acknowledge callback */
+ PM_NOTIFY_CB = 32U, /**< Notify callback */
+};
+
+/* IOCTL IDs */
+typedef enum {
+ IOCTL_GET_RPU_OPER_MODE = 0, /**< Get RPU mode */
+ IOCTL_SET_RPU_OPER_MODE = 1, /**< Set RPU mode */
+} pm_ioctl_id;
+
+/*
+ * Reset configuration argument
+ */
+enum xpm_reset_actions {
+ PM_RESET_ACTION_RELEASE, /**< Reset action release */
+ PM_RESET_ACTION_ASSERT, /**< Reset action assert */
+ PM_RESET_ACTION_PULSE, /**< Reset action pulse */
+};
+
+/*
+ * Pin Control Configuration
+ */
+enum pm_pinctrl_config_param {
+ PINCTRL_CONFIG_SLEW_RATE, /**< Pin config slew rate */
+ PINCTRL_CONFIG_BIAS_STATUS, /**< Pin config bias status */
+ PINCTRL_CONFIG_PULL_CTRL, /**< Pin config pull control */
+ PINCTRL_CONFIG_SCHMITT_CMOS, /**< Pin config schmitt CMOS */
+ PINCTRL_CONFIG_DRIVE_STRENGTH, /**< Pin config drive strength */
+ PINCTRL_CONFIG_VOLTAGE_STATUS, /**< Pin config voltage status */
+ PINCTRL_CONFIG_TRI_STATE, /**< Pin config tri state */
+ PINCTRL_CONFIG_MAX, /**< Max Pin config */
+};
+
+/*
+ * Pin Control Slew Rate
+ */
+enum pm_pinctrl_slew_rate {
+ PINCTRL_SLEW_RATE_FAST, /**< Fast slew rate */
+ PINCTRL_SLEW_RATE_SLOW, /**< Slow slew rate */
+};
+
+/**
+ * PM operating characteristic types
+ */
+enum xpm_opchar_type {
+ PM_OPCHAR_TYPE_POWER = 1, /**< Operating characteristic ID power */
+ PM_OPCHAR_TYPE_TEMP, /**< Operating characteristic ID temp */
+ PM_OPCHAR_TYPE_LATENCY, /**< Operating characteristic ID latency */
+};
+
+/**
+ * PLL parameters
+ */
+enum xpm_pll_config_params {
+ PM_PLL_PARAM_ID_DIV2, /**< PLL param ID DIV2 */
+ PM_PLL_PARAM_ID_FBDIV, /**< PLL param ID FBDIV */
+ PM_PLL_PARAM_ID_DATA, /**< PLL param ID DATA */
+ PM_PLL_PARAM_ID_PRE_SRC, /**< PLL param ID PRE_SRC */
+ PM_PLL_PARAM_ID_POST_SRC, /**< PLL param ID POST_SRC */
+ PM_PLL_PARAM_ID_LOCK_DLY, /**< PLL param ID LOCK_DLY */
+ PM_PLL_PARAM_ID_LOCK_CNT, /**< PLL param ID LOCK_CNT */
+ PM_PLL_PARAM_ID_LFHF, /**< PLL param ID LFHF */
+ PM_PLL_PARAM_ID_CP, /**< PLL param ID CP */
+ PM_PLL_PARAM_ID_RES, /**< PLL param ID RES */
+ PM_PLL_PARAM_MAX, /**< PLL param ID max */
+};
+
+/**
+ * PLL modes
+ */
+enum xpm_pll_mode {
+ PM_PLL_MODE_INTEGER = (0U), /**< PLL mode integer */
+ PM_PLL_MODE_FRACTIONAL = (1U), /**< PLL mode fractional */
+ PM_PLL_MODE_RESET = (2U), /**< PLL mode reset */
+};
+
+/**
+ * Query IDs
+ */
+enum pm_query_id {
+ XPM_QID_INVALID, /**< Invalid Query ID */
+ XPM_QID_CLOCK_GET_NAME, /**< Get clock name */
+ XPM_QID_CLOCK_GET_TOPOLOGY, /**< Get clock topology */
+ XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS, /**< Get clock fixedfactor parameter */
+ XPM_QID_CLOCK_GET_MUXSOURCES, /**< Get clock mux sources */
+ XPM_QID_CLOCK_GET_ATTRIBUTES, /**< Get clock attributes */
+ XPM_QID_PINCTRL_GET_NUM_PINS, /**< Get total pins */
+ XPM_QID_PINCTRL_GET_NUM_FUNCTIONS, /**< Get total pin functions */
+ XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS, /**< Get total pin function groups */
+ XPM_QID_PINCTRL_GET_FUNCTION_NAME, /**< Get pin function name */
+ XPM_QID_PINCTRL_GET_FUNCTION_GROUPS, /**< Get pin function groups */
+ XPM_QID_PINCTRL_GET_PIN_GROUPS, /**< Get pin groups */
+ XPM_QID_CLOCK_GET_NUM_CLOCKS, /**< Get number of clocks */
+ XPM_QID_CLOCK_GET_MAX_DIVISOR, /**< Get max clock divisor */
+ XPM_QID_PLD_GET_PARENT, /**< Get PLD parent */
+ XPM_QID_PINCTRL_GET_ATTRIBUTES, /**< Get pin attributes */
+};
+
+#endif /* XPM_DEFS_H_ */
diff --git a/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h b/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
new file mode 100644
index 0000000..3a1d619
--- /dev/null
+++ b/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef XPM_NODEID_H_
+#define XPM_NODEID_H_
+
+/*
+ * Device Nodes
+ */
+#define PM_DEV_ACPU_0 0x1810C003U
+#define PM_DEV_RPU0_0 0x18110005U
+#define PM_DEV_RPU0_0 0x18110005U
+#define PM_DEV_USB_0 0x18224018U
+#define PM_DEV_TTC_0 0x18224024U
+#define PM_DEV_GEM_0 0x18224019U
+#define PM_DEV_QSPI 0x1822402BU
+#define PM_DEV_RTC 0x18224034U
+#define PM_DEV_SOC 0x18428044U
+#define PM_DEV_PLD_0 0x18700000U
+
+/*
+ * Clock Nodes
+ */
+#define PM_CLK_PMC_PLL 0x8104001U
+#define PM_CLK_APU_PLL 0x8104002U
+#define PM_CLK_RPU_PLL 0x8104003U
+#define PM_CLK_PMC_PRESRC 0x8208007U
+#define PM_CLK_PMC_PLL_OUT 0x8208009U
+#define PM_CLK_QSPI_REF 0x8208039U
+#define PM_CLK_GEM0_REF 0x8208058U
+
+/*
+ * MIO Nodes
+ */
+#define PM_STMIC_LMIO_0 0x14104001U
+#define PM_STMIC_LMIO_3 0x14104003U
+
+/*
+ * Reset Nodes
+ */
+#define PM_RST_GEM_0 0xC104033U
+
+#endif /* XPM_NODEID_H_ */
diff --git a/tftf/tests/plat/amd/common/feature_check/feature_check.c b/tftf/tests/plat/amd/common/feature_check/feature_check.c
new file mode 100644
index 0000000..50095dd
--- /dev/null
+++ b/tftf/tests/plat/amd/common/feature_check/feature_check.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+/*
+ * This function tests the behavior of the xpm_feature_check() function, which
+ * queries information about the feature version.
+ */
+
+int api_id[] = {
+ PM_GET_API_VERSION,
+ PM_GET_NODE_STATUS,
+ PM_FEATURE_CHECK
+};
+
+test_result_t test_feature_check(void)
+{
+ uint32_t version = 0U;
+ int32_t status, index;
+
+ for (index = 0; index < ARRAY_SIZE(api_id); index++) {
+ status = xpm_feature_check(api_id[index], &version);
+
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR querying feature version for API Id:0x%x, "
+ "Status: 0x%x\n", __func__, api_id[index], status);
+ return TEST_RESULT_FAIL;
+ }
+
+ tftf_testcase_printf("Api Id: 0x%x Version: %u\n\n", api_id[index], version);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
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/plat/amd/common/get_api_version_test/get_api_version_test.c b/tftf/tests/plat/amd/common/get_api_version_test/get_api_version_test.c
new file mode 100644
index 0000000..b1a3bd4
--- /dev/null
+++ b/tftf/tests/plat/amd/common/get_api_version_test/get_api_version_test.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+/*
+ * This function tests the behavior of the xpm_get_api_version() function,
+ * which retrieves the API version of the Energy Efficient Management
+ * Interface (EEMI) on AMD-Xilinx platforms.
+ */
+test_result_t test_pm_api_version(void)
+{
+ uint32_t version = 0U;
+ uint32_t major, minor;
+ int32_t status;
+
+ status = xpm_get_api_version(&version);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR reading PM API version\n", __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ major = VERSION_MAJOR(version);
+ minor = VERSION_MINOR(version);
+ tftf_testcase_printf("%s PM API version: %d.%d\n", __func__, major, minor);
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/get_chipid_test/get_chipid_test.c b/tftf/tests/plat/amd/common/get_chipid_test/get_chipid_test.c
new file mode 100644
index 0000000..1190ce2
--- /dev/null
+++ b/tftf/tests/plat/amd/common/get_chipid_test/get_chipid_test.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+/*
+ * This function tests the behavior of the xpm_get_chip_id() function, which
+ * retrieves the Chip ID and version information from the Energy Efficient
+ * Management Interface (EEMI) on AMD-Xilinx platforms.
+ */
+test_result_t test_get_chip_id(void)
+{
+ uint32_t id_code = 0U;
+ uint32_t version = 0U;
+ int32_t status;
+
+ status = xpm_get_chip_id(&id_code, &version);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR reading chip id, Status: 0x%x\n", __func__, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ tftf_testcase_printf("%s id_code = 0x%08x, version = 0x%08x\n", __func__,
+ id_code, version);
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/get_trustzone_version/get_trustzone_version.c b/tftf/tests/plat/amd/common/get_trustzone_version/get_trustzone_version.c
new file mode 100644
index 0000000..16cfa31
--- /dev/null
+++ b/tftf/tests/plat/amd/common/get_trustzone_version/get_trustzone_version.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+/*
+ * This function tests the behavior of the get_trustzone_version() function,
+ * which retrieves the trustzone version.
+ */
+test_result_t test_trustzone_version(void)
+{
+ uint32_t tz_version = 0U;
+ uint32_t major, minor;
+ int32_t status;
+
+ status = get_trustzone_version(&tz_version);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR reading trustzone version, "
+ "Status: 0x%x\n", __func__, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ major = VERSION_MAJOR(tz_version);
+ minor = VERSION_MINOR(tz_version);
+ tftf_testcase_printf("%s Trustzone version: %d.%d\n", __func__, major, minor);
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/init_finalize/init_finalize.c b/tftf/tests/plat/amd/common/init_finalize/init_finalize.c
new file mode 100644
index 0000000..a434514
--- /dev/null
+++ b/tftf/tests/plat/amd/common/init_finalize/init_finalize.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_nodeid.h"
+
+/*
+ * This function is called to notify the power management controller
+ * about the completed power management initialization.
+ */
+test_result_t test_init_finalize(void)
+{
+ int32_t status;
+
+ status = xpm_init_finalize();
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR Power management initialization, "
+ "Status: 0x%x\n", __func__, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/ioctl_test/ioctl_test.c b/tftf/tests/plat/amd/common/ioctl_test/ioctl_test.c
new file mode 100644
index 0000000..e2c0170
--- /dev/null
+++ b/tftf/tests/plat/amd/common/ioctl_test/ioctl_test.c
@@ -0,0 +1,63 @@
+/*
+ * 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"
+
+struct test_ioctl test_ioctl_list[] = {
+ {
+ .node_id = PM_DEV_RPU0_0,
+ .ioctl_id = IOCTL_GET_RPU_OPER_MODE,
+ .ioctl_arg1 = 0U,
+ .ioctl_arg2 = 0U,
+ },
+ {
+ .node_id = PM_DEV_RPU0_0,
+ .ioctl_id = IOCTL_SET_RPU_OPER_MODE,
+ .ioctl_arg1 = XPM_RPU_MODE_SPLIT,
+ .ioctl_arg2 = 0U,
+ },
+ {
+ .node_id = PM_DEV_RPU0_0,
+ .ioctl_id = IOCTL_GET_RPU_OPER_MODE,
+ .ioctl_arg1 = 0U,
+ .ioctl_arg2 = 0U,
+ },
+};
+
+/*
+ * This function calls IOCTL to firmware for device control and
+ * configuration.
+ */
+test_result_t test_ioctl_api(void)
+{
+ uint32_t ioctl_response = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < (int32_t)ARRAY_SIZE(test_ioctl_list); i++) {
+ status = xpm_ioctl(test_ioctl_list[i].node_id,
+ test_ioctl_list[i].ioctl_id,
+ test_ioctl_list[i].ioctl_arg1,
+ test_ioctl_list[i].ioctl_arg2,
+ &ioctl_response);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR Fails for IOCTL Id: %u, Status: 0x%x",
+ __func__, test_ioctl_list[i].ioctl_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (test_ioctl_list[i].ioctl_id == IOCTL_GET_RPU_OPER_MODE) {
+ tftf_testcase_printf("%s RPU_OPER_MODE: 0x%x\n", __func__,
+ ioctl_response);
+ } else {
+ tftf_testcase_printf("%s Mode Set done successfully\n",
+ __func__);
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/node_test/node_test.c b/tftf/tests/plat/amd/common/node_test/node_test.c
new file mode 100644
index 0000000..3154b8d
--- /dev/null
+++ b/tftf/tests/plat/amd/common/node_test/node_test.c
@@ -0,0 +1,281 @@
+/*
+ * 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"
+
+uint32_t test_node_list[] = {
+ PM_DEV_USB_0,
+ PM_DEV_RTC
+};
+
+/*
+ * This function iterates over a list of test nodes, requesting each
+ * node, releasing it, and then attempting to release the same node
+ * again to verify the expected behavior when a node is already
+ * released. It checks the success of each operation to ensure proper
+ * functionality of the API.
+ */
+test_result_t test_release_already_released_node(void)
+{
+ int32_t test_node_num = ARRAY_SIZE(test_node_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ xpm_node_status node_status = {0U};
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_node_num; i++) {
+ uint32_t node_id = test_node_list[i];
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, Status: 0x%x\n",
+ __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, Status: 0x%x\n",
+ __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release already released 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates over a list of test nodes, first requesting
+ * each node, then attempting to request the same node again to verify
+ * the expected behavior when a node is already in use. It checks the
+ * success of each operation to ensure proper functionality of the API.
+ */
+test_result_t test_request_already_requested_node(void)
+{
+ int32_t test_node_num = ARRAY_SIZE(test_node_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ xpm_node_status node_status = {0U};
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_node_num; i++) {
+ uint32_t node_id = test_node_list[i];
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request already request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates over a list of test nodes, requesting each
+ * node, setting the maximum latency for each node, and
+ * verifying the success of each operation to ensure the proper
+ * functionality of the API.
+ */
+test_result_t test_set_max_latency(void)
+{
+ int32_t test_node_num = ARRAY_SIZE(test_node_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t max_latency = XPM_MAX_LATENCY;
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_node_num; i++) {
+ uint32_t node_id = test_node_list[i];
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_set_max_latency(node_id, max_latency);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the max latency for 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates over a list of test nodes, requesting each
+ * node, setting requirements with specific capabilities, and
+ * verifying the status before and after each operation to ensure
+ * proper functionality of the API.
+ */
+test_result_t test_set_requirement(void)
+{
+ int32_t test_node_num = ARRAY_SIZE(test_node_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t capabilities2 = PM_CAP_CONTEXT;
+ xpm_node_status node_status = {0U};
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_node_num; i++) {
+ uint32_t node_id = test_node_list[i];
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_set_requirement(node_id, capabilities2, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set requirement for 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates over a list of test nodes, verifying the
+ * status of each node before and after requesting and releasing
+ * access, ensuring that each API call succeeds and behaves as expected.
+ */
+test_result_t test_get_node_status(void)
+{
+ int32_t test_node_num = ARRAY_SIZE(test_node_list);
+ xpm_node_status node_status = {0U};
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_node_num; i++) {
+ uint32_t node_id = test_node_list[i];
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_get_node_status(node_id, &node_status);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the status of 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/op_characteristics/op_characteristics.c b/tftf/tests/plat/amd/common/op_characteristics/op_characteristics.c
new file mode 100644
index 0000000..d3b275b
--- /dev/null
+++ b/tftf/tests/plat/amd/common/op_characteristics/op_characteristics.c
@@ -0,0 +1,52 @@
+/*
+ * 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"
+
+/*
+ * This function will request the power management controller to
+ * return information about an operating characteristic of a component.
+ */
+test_result_t test_op_characteristics(void)
+{
+ int32_t status;
+ uint32_t result;
+ uint32_t type = PM_OPCHAR_TYPE_TEMP;
+
+ status = xpm_op_characteristics(PM_DEV_SOC, type, &result);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR getting op characteristics, type = %x, "
+ "Status: 0x%x\n", __func__, type, status);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("Temp = %x\n", result);
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function will request the power management controller to
+ * return information about an operating characteristic of a component,
+ * but with an invalid parameter to test error handling.
+ */
+test_result_t test_op_characteristics_invalid_param(void)
+{
+ int32_t status;
+ uint32_t result;
+ uint32_t type = PM_OPCHAR_TYPE_TEMP;
+
+ status = xpm_op_characteristics(PM_DEV_USB_0, type, &result);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR getting op characteristics, type = %x, "
+ "Status: 0x%x\n", __func__, type, status);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("Temp = %x\n", result);
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/pin_test/pin_test.c b/tftf/tests/plat/amd/common/pin_test/pin_test.c
new file mode 100644
index 0000000..23964b0
--- /dev/null
+++ b/tftf/tests/plat/amd/common/pin_test/pin_test.c
@@ -0,0 +1,355 @@
+/*
+ * 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"
+
+struct test_pins {
+ uint32_t node_id;
+ uint32_t pin_id;
+ uint32_t function_id;
+};
+
+struct test_pins test_pin_list[] = {
+ {
+ .node_id = PM_DEV_GEM_0,
+ .pin_id = PM_STMIC_LMIO_0,
+ .function_id = PIN_FUNC_GEM0,
+ },
+};
+
+/*
+ * This function iterates through a list of test pins, requests the associated
+ * device node, attempts to set both the pin function and a pin configuration
+ * parameter (slew rate in this case) without prior pin request, and verifies
+ * that both operations fail as expected. It releases the device node after each
+ * pin operation and logs errors if any step fails.
+ */
+test_result_t test_set_pin_parameter_of_unrequested_pin(void)
+{
+ int32_t test_pin_num = ARRAY_SIZE(test_pin_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t param_id = PINCTRL_CONFIG_SLEW_RATE;
+ uint32_t set_param_val = 0U;
+ uint32_t get_param_val = 0U;
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_pin_num; i++) {
+ uint32_t node_id = test_pin_list[i].node_id;
+ uint32_t pin_id = test_pin_list[i].pin_id;
+ uint32_t set_function_id = test_pin_list[i].function_id;
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_set_function(pin_id, set_function_id);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR set pinctrl func w/o requesting 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_parameter(pin_id, param_id, &get_param_val);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the parameter of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (get_param_val != PINCTRL_SLEW_RATE_SLOW)
+ set_param_val = PINCTRL_SLEW_RATE_SLOW;
+ else
+ set_param_val = PINCTRL_SLEW_RATE_FAST;
+
+ status = xpm_pinctrl_set_parameter(pin_id, param_id, set_param_val);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR set pin parameter w/o requesting 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates through a list of test pins, requests the associated
+ * device node, attempts to retrieve and set the pin function without prior pin
+ * request, and verifies that the set operation fails as expected. It releases
+ * the device node after each pin operation and logs errors if any step fails.
+ */
+test_result_t test_set_pin_function_of_unrequested_pin(void)
+{
+ int32_t test_pin_num = ARRAY_SIZE(test_pin_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t get_function_id = 0U;
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_pin_num; i++) {
+ uint32_t node_id = test_pin_list[i].node_id;
+ uint32_t pin_id = test_pin_list[i].pin_id;
+ uint32_t set_function_id = test_pin_list[i].function_id;
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_function(pin_id, &get_function_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the function of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_set_function(pin_id, set_function_id);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR set pinctrl func w/o requesting 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_function(pin_id, &get_function_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the function of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates through a list of test pins, requests the associated
+ * device and pin, sets a specified pin function, sets and verifies a pin
+ * configuration parameter (slew rate in this case), and releases both the pin
+ * and device after each operation. It performs checks for successful operations
+ * and logs errors if any step fails.
+ */
+test_result_t test_set_pin_config_param(void)
+{
+ int32_t test_pin_num = ARRAY_SIZE(test_pin_list);
+ uint32_t param_id = PINCTRL_CONFIG_SLEW_RATE;
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t set_param_val = 0U;
+ uint32_t get_param_val = 0U;
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_pin_num; i++) {
+ uint32_t node_id = test_pin_list[i].node_id;
+ uint32_t pin_id = test_pin_list[i].pin_id;
+ uint32_t set_function_id = test_pin_list[i].function_id;
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_request(pin_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_reset_assert(PM_RST_GEM_0, PM_RESET_ACTION_PULSE);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to reset assert\n", __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_set_function(pin_id, set_function_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the function of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_parameter(pin_id, param_id, &get_param_val);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the parameter of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (get_param_val != PINCTRL_SLEW_RATE_SLOW)
+ set_param_val = PINCTRL_SLEW_RATE_SLOW;
+ else
+ set_param_val = PINCTRL_SLEW_RATE_FAST;
+
+ status = xpm_pinctrl_set_parameter(pin_id, param_id, set_param_val);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the parameter of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_parameter(pin_id, param_id, &get_param_val);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the parameter of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (set_param_val != get_param_val) {
+ tftf_testcase_printf("%s ERROR pin parameter do not match\n",
+ __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (get_param_val != PINCTRL_SLEW_RATE_SLOW)
+ set_param_val = PINCTRL_SLEW_RATE_SLOW;
+ else
+ set_param_val = PINCTRL_SLEW_RATE_FAST;
+
+ status = xpm_pinctrl_set_parameter(pin_id, param_id, set_param_val);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the parameter of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_parameter(pin_id, param_id, &get_param_val);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the parameter of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (set_param_val != get_param_val) {
+ tftf_testcase_printf("%s ERROR pin parameter do not match\n",
+ __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_release(pin_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function iterates through a list of test pins, requests the associated
+ * device and pin, sets a specified pin function, verifies the function setting,
+ * and releases both the pin and device after each operation. It performs checks
+ * for successful operations and logs errors if any step fails.
+ */
+test_result_t test_set_pin_function(void)
+{
+ int32_t test_pin_num = ARRAY_SIZE(test_pin_list);
+ uint32_t capabilities = PM_CAP_ACCESS;
+ uint32_t get_function_id = 0U;
+ uint32_t ack = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < test_pin_num; i++) {
+ uint32_t node_id = test_pin_list[i].node_id;
+ uint32_t pin_id = test_pin_list[i].pin_id;
+ uint32_t set_function_id = test_pin_list[i].function_id;
+
+ status = xpm_request_node(node_id, capabilities, PM_MAX_QOS, ack);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_request(pin_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_reset_assert(PM_RST_GEM_0, PM_RESET_ACTION_PULSE);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to reset assert\n", __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_function(pin_id, &get_function_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the function of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_set_function(pin_id, set_function_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to set the function of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_get_function(pin_id, &get_function_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to get the function of 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (set_function_id != get_function_id) {
+ tftf_testcase_printf("%s ERROR function ids do not match\n",
+ __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_pinctrl_release(pin_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x pin, "
+ "Status: 0x%x\n", __func__, pin_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ status = xpm_release_node(node_id);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request 0x%x node, "
+ "Status: 0x%x\n", __func__, node_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/pll_test/pll_test.c b/tftf/tests/plat/amd/common/pll_test/pll_test.c
new file mode 100644
index 0000000..245d5a4
--- /dev/null
+++ b/tftf/tests/plat/amd/common/pll_test/pll_test.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_nodeid.h"
+
+struct test_pll_api test_pll[] = {
+ {
+ .clock_id = PM_CLK_RPU_PLL,
+ },
+};
+
+/*
+ * This function is used to set the parameters for specified PLL clock.
+ */
+test_result_t test_pll_set_parameter(void)
+{
+ int32_t status, i;
+
+ for (i = 0; i < ARRAY_SIZE(test_pll); i++) {
+ uint32_t clock_id = test_pll[i].clock_id;
+
+ status = xpm_pll_set_parameter(clock_id, PM_PLL_PARAM_ID_FBDIV, 10);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR PLL Set Parameter for Clock ID: 0x%x, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function is used to get the parameter of specified PLL clock.
+ */
+test_result_t test_pll_get_parameter(void)
+{
+ int32_t status, i;
+ uint32_t value;
+
+ for (i = 0; i < ARRAY_SIZE(test_pll); i++) {
+ uint32_t clock_id = test_pll[i].clock_id;
+
+ status = xpm_pll_get_parameter(clock_id, PM_PLL_PARAM_ID_FBDIV, &value);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR PLL Get Parameter for Clock ID: 0x%x, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("Value = %x\n\r", value);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function is used to set the mode of specified PLL clock
+ */
+test_result_t test_pll_set_mode(void)
+{
+ int32_t status, i;
+
+ for (i = 0; i < ARRAY_SIZE(test_pll); i++) {
+ uint32_t clock_id = test_pll[i].clock_id;
+
+ status = xpm_pll_set_mode(clock_id, PM_PLL_MODE_RESET);
+ if (status == PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR PLL Set Mode for Clock ID: 0x%x, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function is used to get the mode of specified PLL clock
+ */
+test_result_t test_pll_get_mode(void)
+{
+ int32_t status, i;
+ uint32_t value;
+
+ for (i = 0; i < ARRAY_SIZE(test_pll); i++) {
+ uint32_t clock_id = test_pll[i].clock_id;
+
+ status = xpm_pll_get_mode(clock_id, &value);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR PLL Get Mode for Clock ID: 0x%x, "
+ "Status: 0x%x\n", __func__, clock_id, status);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("Mode = %x\n\r", value);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/query_data/query_data.c b/tftf/tests/plat/amd/common/query_data/query_data.c
new file mode 100644
index 0000000..b785d2a
--- /dev/null
+++ b/tftf/tests/plat/amd/common/query_data/query_data.c
@@ -0,0 +1,55 @@
+/*
+ * 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"
+
+struct test_query test_query_list[] = {
+ {
+ .query_id = XPM_QID_CLOCK_GET_NUM_CLOCKS,
+ },
+ {
+ .query_id = XPM_QID_PINCTRL_GET_NUM_PINS,
+ },
+ {
+ .query_id = XPM_QID_PINCTRL_GET_NUM_FUNCTIONS,
+ },
+ {
+ .query_id = XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
+ .query_arg1 = PIN_FUNC_I2C0,
+ },
+};
+
+/**
+ * This function queries information about the platform resources.
+ */
+int test_query_data(void)
+{
+ int32_t status;
+ uint32_t i;
+
+ for (i = 0; i < ARRAY_SIZE(test_query_list); i++) {
+ uint32_t query_data[4] = {0};
+
+ status = xpm_query_data(test_query_list[i].query_id,
+ test_query_list[i].query_arg1,
+ test_query_list[i].query_arg2,
+ test_query_list[i].query_arg3,
+ query_data);
+
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("ERROR: Failed XPm_Query for qid 0x%x, Status: 0x%x\n",
+ test_query_list[i].query_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ tftf_testcase_printf("Query Id = %x Output = %x\n\r",
+ test_query_list[i].query_id, query_data[0]);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/register_notifier_test/register_notifier_test.c b/tftf/tests/plat/amd/common/register_notifier_test/register_notifier_test.c
new file mode 100644
index 0000000..748c5f5
--- /dev/null
+++ b/tftf/tests/plat/amd/common/register_notifier_test/register_notifier_test.c
@@ -0,0 +1,120 @@
+/*
+ * 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"
+#include <timer.h>
+
+#define TIMEOUT_MS 0x1000U
+
+static void test_notify_cb(xpm_notifier *notifier);
+
+xpm_notifier notifier = {
+ .callback = test_notify_cb,
+ .node = PM_DEV_USB_0,
+ .event = EVENT_STATE_CHANGE,
+ .flags = 0,
+};
+
+/*
+ * This callback routine is invoked when the notification arrives.
+ */
+void test_notify_cb(xpm_notifier *notifier)
+{
+ tftf_testcase_printf("Received notification: Node=0x%x, Event=%d, OPP=%d\n",
+ notifier->node, (int)notifier->event, (int)notifier->oppoint);
+}
+
+/*
+ * This function is used to register a notification with change state
+ * mode and change the requirements of the particular node.
+ */
+static int test_register_notifier(void)
+{
+ int32_t status;
+
+ status = xpm_request_node(notifier.node, PM_CAP_ACCESS, 0, 0);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to request the node for Node Id: 0x%x, "
+ "Status: 0x%x\n", __func__, notifier.node, status);
+ return status;
+ }
+
+ status = xpm_register_notifier(¬ifier);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to register the notifier, Status: 0x%x\n",
+ __func__, status);
+ return status;
+ }
+
+ /*
+ * Setting the requirement to 0 after registering the notifier triggers the
+ * EVENT_STATE_CHANGE event for the PM_DEV_USB_0 node.
+ */
+ status = xpm_set_requirement(notifier.node, 0, 0, 0);
+ if (status != PM_RET_SUCCESS)
+ tftf_testcase_printf("%s ERROR to set the requirement for Node Id: 0x%x, "
+ "Status: 0x%x\n", __func__, notifier.node, status);
+
+ return status;
+}
+
+/*
+ * This function is used to unregister the notifier.
+ */
+static int test_unregister_notifier(void)
+{
+ int32_t status;
+
+ status = xpm_unregister_notifier(¬ifier);
+ if (status != PM_RET_SUCCESS)
+ tftf_testcase_printf("%s ERROR to unregister the notifier\n", __func__);
+
+ status = xpm_release_node(notifier.node);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR to release 0x%x node, "
+ "Status: 0x%x\n", __func__, notifier.node, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ return status;
+}
+
+/*
+ * This function tests the register notification handling in the test
+ * environment. It first attempts to register a notifier using
+ * test_register_notifier(). If successful, it waits for a notification to be
+ * received within a specified timeout period. If a notification is received
+ * before the timeout, it proceeds to unregister the notifier using
+ * test_unregister_notifier().
+ */
+test_result_t test_notifier_api(void)
+{
+ uint32_t timeout_counter = 0U;
+ int32_t status;
+ test_result_t result = TEST_RESULT_SUCCESS;
+
+ status = test_register_notifier();
+ if (status != PM_RET_SUCCESS)
+ result = TEST_RESULT_FAIL;
+
+ while ((notifier.received == 0) && (timeout_counter < TIMEOUT_MS)) {
+ tftf_timer_sleep(1); // Sleep for 1 millisecond
+ timeout_counter++;
+ }
+
+ if (!notifier.received) {
+ tftf_testcase_printf("%s ERROR timeout\n", __func__);
+ result = TEST_RESULT_FAIL;
+ }
+
+ status = test_unregister_notifier();
+ if (status != PM_RET_SUCCESS)
+ result = TEST_RESULT_FAIL;
+
+ return result;
+}
diff --git a/tftf/tests/plat/amd/common/reset_get_status/reset_get_status.c b/tftf/tests/plat/amd/common/reset_get_status/reset_get_status.c
new file mode 100644
index 0000000..2db9e1b
--- /dev/null
+++ b/tftf/tests/plat/amd/common/reset_get_status/reset_get_status.c
@@ -0,0 +1,30 @@
+/*
+ * 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"
+
+/*
+ * This function reads the device reset state.
+ */
+test_result_t test_reset_get_status(void)
+{
+ int32_t status;
+ uint32_t result;
+ uint32_t reset_id = PM_RST_GEM_0;
+
+ status = xpm_reset_get_status(reset_id, &result);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR getting reset status for reset_id: 0x%x, "
+ "Status: 0x%x\n", __func__, reset_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ tftf_testcase_printf("State = %x\n", result);
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/self_suspend/self_suspend.c b/tftf/tests/plat/amd/common/self_suspend/self_suspend.c
new file mode 100644
index 0000000..15cbea3
--- /dev/null
+++ b/tftf/tests/plat/amd/common/self_suspend/self_suspend.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_nodeid.h"
+
+#define PROC_DEV_ID PM_DEV_ACPU_0
+
+/* Extern Variable */
+extern void __attribute__((weak)) *_vector_table;
+
+/*
+ * This function is used by a CPU to set wakeup source.
+ */
+test_result_t test_set_wakeup_source(void)
+{
+ int32_t status;
+
+ status = xpm_set_wakeup_source(PROC_DEV_ID, PM_DEV_TTC_0, 1);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR Set WakeUp Source: 0x%x, Status: 0x%x\n",
+ __func__, PM_DEV_TTC_0, status);
+
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * This function is used by a CPU to declare that it is about to
+ * suspend itself.
+ */
+test_result_t test_self_suspend(void)
+{
+ int32_t status;
+
+ status = xpm_self_suspend(PROC_DEV_ID, 0xFFFFFFFF,
+ PM_SUSPEND_STATE_SUSPEND_TO_RAM,
+ (uint64_t)&_vector_table);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR Self-suspend, Status: 0x%x\n", __func__, status);
+
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/system_shutdown/system_shutdown.c b/tftf/tests/plat/amd/common/system_shutdown/system_shutdown.c
new file mode 100644
index 0000000..463016e
--- /dev/null
+++ b/tftf/tests/plat/amd/common/system_shutdown/system_shutdown.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+struct sys_shutdown system_shutdown[] = {
+ {
+ .shutdown_type = PM_SHUTDOWN_TYPE_RESET,
+ .shutdown_subtype = PM_SHUTDOWN_SUBTYPE_RST_SUBSYSTEM,
+ },
+};
+
+/*
+ * This function can be used by a subsystem to shutdown self or restart
+ * self, Ps or system.
+ */
+test_result_t test_system_shutdown(void)
+{
+ int32_t status, i;
+
+ for (i = 0; i < ARRAY_SIZE(system_shutdown); i++) {
+ uint32_t type = system_shutdown[i].shutdown_type;
+ uint32_t subtype = system_shutdown[i].shutdown_subtype;
+
+ status = xpm_system_shutdown(type, subtype);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR shutting down system, "
+ "Status: 0x%x\n", __func__, status);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("Success for type = %d and subtype = %d\n",
+ type, subtype);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/tf_a_feature_check/tf_a_feature_check.c b/tftf/tests/plat/amd/common/tf_a_feature_check/tf_a_feature_check.c
new file mode 100644
index 0000000..1eea396
--- /dev/null
+++ b/tftf/tests/plat/amd/common/tf_a_feature_check/tf_a_feature_check.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+int api_id_list[] = {
+ PM_GET_CALLBACK_DATA,
+ PM_GET_TRUSTZONE_VERSION,
+ TF_A_PM_REGISTER_SGI,
+ TF_A_FEATURE_CHECK,
+};
+
+/*
+ * This function tests the behavior of the tf_a_feature_check() function, which
+ * retrieves the supported API Version.
+ */
+test_result_t test_tf_a_feature_check(void)
+{
+ uint32_t version = 0U;
+ int32_t status, index;
+
+ for (index = 0; index < ARRAY_SIZE(api_id_list); index++) {
+ status = tf_a_feature_check(api_id_list[index], &version);
+
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR fetching the supported version for %x, "
+ "Status: 0x%x\n", __func__, api_id_list[index],
+ status);
+ return TEST_RESULT_FAIL;
+ }
+
+ tftf_testcase_printf("Api Id: 0x%x Version: %u Status: %s\n\n",
+ api_id_list[index], version,
+ ((status == 0U) ? "Supported" : "Not Supported"));
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/plat/amd/common/tf_a_register_sgi/tf_a_register_sgi.c b/tftf/tests/plat/amd/common/tf_a_register_sgi/tf_a_register_sgi.c
new file mode 100644
index 0000000..1488083
--- /dev/null
+++ b/tftf/tests/plat/amd/common/tf_a_register_sgi/tf_a_register_sgi.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+
+struct register_sgi sgi_register_list[] = {
+ {
+ .sgi_num = XLNX_EVENT_SGI_NUM,
+ .reset = 0,
+ },
+};
+
+/*
+ * This function register the IPI interrupt.
+ */
+test_result_t test_tf_a_register_sgi(void)
+{
+ int32_t status, i;
+
+ for (i = 0; i < ARRAY_SIZE(sgi_register_list); i++) {
+ uint32_t sgi_number = sgi_register_list[i].sgi_num;
+ uint32_t reset = sgi_register_list[i].reset;
+
+ status = tf_a_pm_register_sgi(sgi_number, reset);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR registering sgi, "
+ "Status: 0x%x\n", __func__, status);
+ return TEST_RESULT_FAIL;
+ }
+ tftf_testcase_printf("Registered SGI num : %d\n", sgi_number);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-versal.mk b/tftf/tests/tests-versal.mk
index 6717ee5..0a2ad54 100644
--- a/tftf/tests/tests-versal.mk
+++ b/tftf/tests/tests-versal.mk
@@ -1,12 +1,12 @@
#
-# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-TESTS_SOURCES += $(addprefix tftf/tests/plat/xilinx/common/, \
- plat_pm.c \
-)
+TFTF_INCLUDES += -Itftf/tests/plat/amd/common/common_files/
+
+TESTS_SOURCES += $(wildcard tftf/tests/plat/amd/common/*/*.c)
include tftf/tests/tests-standard.mk
TESTS_SOURCES += $(sort ${TESTS_SOURCES})
diff --git a/tftf/tests/tests-versal.xml b/tftf/tests/tests-versal.xml
index 6c8f519..28201e9 100644
--- a/tftf/tests/tests-versal.xml
+++ b/tftf/tests/tests-versal.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -12,8 +12,40 @@
<testsuites>
<testsuite name="AMD-Xilinx tests" description="AMD-Xilinx common platform tests" >
- <testcase name="Read PM API Version" function="test_pmapi_version" />
- <testcase name="Get Platform Chip ID" function="test_get_chipid" />
+ <testcase name="Read PM API Version" function="test_pm_api_version" />
+ <testcase name="Get Platform Chip ID" function="test_get_chip_id" />
+ <testcase name="Feature Check" function="test_feature_check" />
+ <testcase name="Notifier EEMI API" function="test_notifier_api" />
+ <testcase name="Ioctl EEMI API" function="test_ioctl_api" />
+ <testcase name="Get node status functionality" function="test_get_node_status" />
+ <testcase name="Set requirement functionality" function="test_set_requirement" />
+ <testcase name="Set max latency functionality" function="test_set_max_latency" />
+ <testcase name="Request already requested node" function="test_request_already_requested_node" />
+ <testcase name="Release already released node" function="test_release_already_released_node" />
+ <testcase name="Clock control with device request" function="test_clock_control_with_device_request" />
+ <testcase name="Clock control without device request" function="test_clock_control_without_device_request" />
+ <testcase name="Set pin function" function="test_set_pin_function" />
+ <testcase name="Set pin configuration parameter" function="test_set_pin_config_param" />
+ <testcase name="Set pin function without requesting pin" function="test_set_pin_function_of_unrequested_pin" />
+ <testcase name="Set pin parameter without requesting pin" function="test_set_pin_parameter_of_unrequested_pin" />
+ <testcase name="PM Init Finalize" function="test_init_finalize" />
+ <testcase name="Trustzone version" function="test_trustzone_version" />
+ <testcase name="TF-A feature check" function="test_tf_a_feature_check" />
+ <testcase name="TF-A register sgi" function="test_tf_a_register_sgi" />
+ <testcase name="Get operating characteristics" function="test_op_characteristics" />
+ <testcase name="Get operating characteristics with invalid params" function="test_op_characteristics_invalid_param" />
+ <testcase name="System Shutdown" function="test_system_shutdown" />
+ <testcase name="Set PLL Mode" function="test_pll_set_mode" />
+ <testcase name="Get PLL Mode" function="test_pll_get_mode" />
+ <testcase name="Set PLL parameter " function="test_pll_set_parameter" />
+ <testcase name="Get PLL parameter " function="test_pll_get_parameter" />
+ <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" />
+ <testcase name="Get Reset Status" function="test_reset_get_status" />
+
</testsuite>
</testsuites>