xilinx: versal: Add feature check API
Add API to check availability of given API in ATF
as well as platform management controller and returns
the supported version number.
Signed-off-by: Ravi Patel <ravi.patel@xilinx.com>
Signed-off-by: Jolly Shah <jolly.shah@xilinx.com>
Change-Id: I608b38f60b36c4d105b7a205ecb8b02de0c00f3c
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index 216bc98..54fd6e1 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -747,3 +747,73 @@
wkup_device, enable);
return pm_ipi_send(primary_proc, payload);
}
+
+/**
+ * pm_feature_check() - Returns the supported API version if supported
+ * @api_id API ID to check
+ * @value Returned supported API version
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
+ uint32_t status;
+
+ switch (api_id) {
+ case PM_GET_CALLBACK_DATA:
+ case PM_GET_TRUSTZONE_VERSION:
+ case PM_INIT_FINALIZE:
+ *version = (PM_API_BASE_VERSION << 16);
+ return PM_RET_SUCCESS;
+ case PM_GET_API_VERSION:
+ case PM_GET_DEVICE_STATUS:
+ case PM_REQ_SUSPEND:
+ case PM_SELF_SUSPEND:
+ case PM_FORCE_POWERDOWN:
+ case PM_ABORT_SUSPEND:
+ case PM_REQ_WAKEUP:
+ case PM_SET_WAKEUP_SOURCE:
+ case PM_SYSTEM_SHUTDOWN:
+ case PM_REQUEST_DEVICE:
+ case PM_RELEASE_DEVICE:
+ case PM_SET_REQUIREMENT:
+ case PM_RESET_ASSERT:
+ case PM_RESET_GET_STATUS:
+ case PM_PINCTRL_REQUEST:
+ case PM_PINCTRL_RELEASE:
+ case PM_PINCTRL_GET_FUNCTION:
+ case PM_PINCTRL_SET_FUNCTION:
+ case PM_PINCTRL_CONFIG_PARAM_GET:
+ case PM_PINCTRL_CONFIG_PARAM_SET:
+ case PM_IOCTL:
+ case PM_QUERY_DATA:
+ case PM_CLOCK_ENABLE:
+ case PM_CLOCK_DISABLE:
+ case PM_CLOCK_GETSTATE:
+ case PM_CLOCK_SETDIVIDER:
+ case PM_CLOCK_GETDIVIDER:
+ case PM_CLOCK_SETPARENT:
+ case PM_CLOCK_GETPARENT:
+ case PM_PLL_SET_PARAMETER:
+ case PM_PLL_GET_PARAMETER:
+ case PM_PLL_SET_MODE:
+ case PM_PLL_GET_MODE:
+ case PM_FEATURE_CHECK:
+ *version = (PM_API_BASE_VERSION << 16);
+ break;
+ default:
+ *version = 0U;
+ return PM_RET_ERROR_NOFEATURE;
+ }
+
+ PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_FEATURE_CHECK, api_id);
+
+ status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
+ if (status != PM_RET_SUCCESS)
+ return status;
+
+ *version |= fw_api_version;
+
+ return PM_RET_SUCCESS;
+}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 282c175..4e884e0 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -65,5 +65,5 @@
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data);
unsigned int pm_get_shutdown_scope(void);
-
+enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version);
#endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
index 281494a..a7b0a02 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -33,6 +33,12 @@
XPM_NODESUBCL_DEV_PERIPH, \
XPM_NODETYPE_DEV_PERIPH, (IDX))
+#define PM_GET_CALLBACK_DATA 0xa01
+#define PM_GET_TRUSTZONE_VERSION 0xa03
+
+/* PM API Versions */
+#define PM_API_BASE_VERSION 1U
+
/* PM API ids */
#define PM_GET_API_VERSION 1U
#define PM_GET_DEVICE_STATUS 3U
@@ -70,6 +76,7 @@
#define PM_PLL_GET_PARAMETER 49U
#define PM_PLL_SET_MODE 50U
#define PM_PLL_GET_MODE 51U
+#define PM_FEATURE_CHECK 63U
/* IOCTL IDs for clock driver */
#define IOCTL_SET_PLL_FRAC_MODE 8
@@ -121,6 +128,7 @@
* @PM_RET_SUCCESS: success
* @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated)
* @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated)
+ * @PM_RET_ERROR_NOFEATURE: feature is not available
* @PM_RET_ERROR_INTERNAL: internal error
* @PM_RET_ERROR_CONFLICT: conflict
* @PM_RET_ERROR_ACCESS: access rights violation
@@ -134,6 +142,7 @@
PM_RET_SUCCESS,
PM_RET_ERROR_ARGS = 1,
PM_RET_ERROR_NOTSUPPORTED = 4,
+ PM_RET_ERROR_NOFEATURE = 19,
PM_RET_ERROR_INTERNAL = 2000,
PM_RET_ERROR_CONFLICT = 2001,
PM_RET_ERROR_ACCESS = 2002,
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index 8140b66..b5a6783 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -17,9 +17,6 @@
#include "pm_client.h"
#include "pm_ipi.h"
-#define PM_GET_CALLBACK_DATA 0xa01
-#define PM_GET_TRUSTZONE_VERSION 0xa03
-
/* pm_up = true - UP, pm_up = false - DOWN */
static bool pm_up;
@@ -293,6 +290,14 @@
SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
((uint64_t)VERSAL_TZ_VERSION << 32));
+ case PM_FEATURE_CHECK:
+ {
+ uint32_t version;
+
+ ret = pm_feature_check(pm_arg[0], &version);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)version << 32));
+ }
+
default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);