feat(amd): add test for pin EEMI APIs

Add test for the pin-related EEMI APIs within the TF-A test
framework. The purpose of these tests is to validate the
functionality and reliability of various pin operations.

Test cover the following EEMI APIs:
- xpm_pinctrl_request
- xpm_pinctrl_release
- xpm_pinctrl_set_function
- xpm_pinctrl_get_function
- xpm_pinctrl_set_parameter
- xpm_pinctrl_get_parameter

Note: This initial test does not cover all the pin ids, as the
purpose of the test is to validate the pin EEMI APIs interface.

Change-Id: I50142ee110e5cb7427ffaeae7f413aa0e6662006
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 95096ce..470f0dc 100644
--- a/tftf/tests/plat/amd/common/common_files/eemi_api.c
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.c
@@ -330,3 +330,68 @@
 
 	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);
+}
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 fdcaa8e..8489a4a 100644
--- a/tftf/tests/plat/amd/common/common_files/eemi_api.h
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.h
@@ -54,5 +54,14 @@
 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);
 
 #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
index e96f958..8235c89 100644
--- a/tftf/tests/plat/amd/common/common_files/xpm_defs.h
+++ b/tftf/tests/plat/amd/common/common_files/xpm_defs.h
@@ -120,6 +120,68 @@
 	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
@@ -148,4 +210,35 @@
 	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 */
+};
+
 #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
index 3ea8e59..8a6afd1 100644
--- a/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
+++ b/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
@@ -23,4 +23,14 @@
 #define PM_CLK_QSPI_REF         0x8208039U
 #define PM_CLK_GEM0_REF         0x8208058U
 
+/*
+ * MIO Nodes
+ */
+#define PM_STMIC_LMIO_0         0x14104001U
+
+/*
+ * Reset Nodes
+ */
+#define PM_RST_GEM_0            0xC104033U
+
 #endif /* XPM_NODEID_H_ */
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/tests-versal.xml b/tftf/tests/tests-versal.xml
index 6cc6dae..67c3cf8 100644
--- a/tftf/tests/tests-versal.xml
+++ b/tftf/tests/tests-versal.xml
@@ -24,6 +24,10 @@
       <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" />
     </testsuite>
 
   </testsuites>