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>