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);