diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c index f78b88cdf..b2b473a48 100644 --- a/plat/xilinx/zynqmp/plat_psci.c +++ b/plat/xilinx/zynqmp/plat_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -33,6 +33,8 @@ static int zynqmp_pwr_domain_on(u_register_t mpidr) { unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr); const struct pm_proc *proc; + uint32_t buff[3]; + enum pm_ret_status ret; VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr); @@ -40,6 +42,13 @@ static int zynqmp_pwr_domain_on(u_register_t mpidr) return PSCI_E_INTERN_FAIL; proc = pm_get_proc(cpu_id); + + /* Check the APU proc status before wakeup */ + ret = pm_get_node_status(proc->node_id, buff); + if ((ret != PM_RET_SUCCESS) || (buff[0] == PM_PROC_STATE_SUSPENDING)) { + return PSCI_E_INTERN_FAIL; + } + /* Clear power down request */ pm_client_wakeup(proc); diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index 0cc517ec9..410983022 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -2443,8 +2443,6 @@ enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks) * * This function is used by master to get nmae of clock specified * by given clock ID. - * - * @return Returns success. In case of error, name data is 0. */ void pm_api_clock_get_name(unsigned int clock_id, char *name) { diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index 9c5af88bb..a87681b45 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -618,6 +618,7 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, unsigned int *value) { enum pm_ret_status ret; + uint32_t payload[PAYLOAD_ARG_CNT]; switch (ioctl_id) { case IOCTL_GET_RPU_OPER_MODE: @@ -677,14 +678,57 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, case IOCTL_AFI: ret = pm_ioctl_afi(arg1, arg2); break; - case IOCTL_SET_FEATURE_CONFIG: - case IOCTL_GET_FEATURE_CONFIG: - ret = pm_feature_config(ioctl_id, arg1, arg2, value); - break; default: - ret = PM_RET_ERROR_NOTSUPPORTED; + /* Send request to the PMU */ + PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2); + + ret = pm_ipi_send_sync(primary_proc, payload, value, 1); break; } return ret; } + +/** + * pm_update_ioctl_bitmask() - API to get supported IOCTL ID mask + * @bit_mask Returned bit mask of supported IOCTL IDs + */ +enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask) +{ + uint8_t supported_ids[] = { + IOCTL_GET_RPU_OPER_MODE, + IOCTL_SET_RPU_OPER_MODE, + IOCTL_RPU_BOOT_ADDR_CONFIG, + IOCTL_TCM_COMB_CONFIG, + IOCTL_SET_TAPDELAY_BYPASS, + IOCTL_SET_SGMII_MODE, + IOCTL_SD_DLL_RESET, + IOCTL_SET_SD_TAPDELAY, + IOCTL_SET_PLL_FRAC_MODE, + IOCTL_GET_PLL_FRAC_MODE, + IOCTL_SET_PLL_FRAC_DATA, + IOCTL_GET_PLL_FRAC_DATA, + IOCTL_WRITE_GGS, + IOCTL_READ_GGS, + IOCTL_WRITE_PGGS, + IOCTL_READ_PGGS, + IOCTL_ULPI_RESET, + IOCTL_SET_BOOT_HEALTH_STATUS, + IOCTL_AFI, + }; + uint8_t i, ioctl_id; + int ret; + + for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) { + ioctl_id = supported_ids[i]; + if (ioctl_id >= 64U) { + return PM_RET_ERROR_NOTSUPPORTED; + } + ret = check_api_dependency(ioctl_id); + if (ret == PM_RET_SUCCESS) { + bit_mask[ioctl_id / 32] |= BIT(ioctl_id % 32); + } + } + + return PM_RET_SUCCESS; +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h index f18dc00a2..0c5f33fa6 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -49,9 +49,6 @@ enum { IOCTL_AIE_ISR_CLEAR = 24, /* Register SGI to ATF */ IOCTL_REGISTER_SGI = 25, - /* Runtime feature configuration */ - IOCTL_SET_FEATURE_CONFIG = 26, - IOCTL_GET_FEATURE_CONFIG = 27, }; //RPU operation mode @@ -95,4 +92,5 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, unsigned int arg1, unsigned int arg2, unsigned int *value); +enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask); #endif /* PM_API_IOCTL_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index 5d9408cd5..f9af451c0 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,6 +20,225 @@ #include "pm_common.h" #include "pm_ipi.h" +#define PM_QUERY_FEATURE_BITMASK ( \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_NAME) | \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_TOPOLOGY) | \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS) | \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_PARENTS) | \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_ATTRIBUTES) | \ + (1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_PINS) | \ + (1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTIONS) | \ + (1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS) | \ + (1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_NAME) | \ + (1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_GROUPS) | \ + (1ULL << (uint64_t)PM_QID_PINCTRL_GET_PIN_GROUPS) | \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_NUM_CLOCKS) | \ + (1ULL << (uint64_t)PM_QID_CLOCK_GET_MAX_DIVISOR)) + +/** + * struct eemi_api_dependency - Dependent EEMI APIs which are implemented + * on both the ATF and firmware + * + * @id: EEMI API id or IOCTL id to be checked + * @api_id: Dependent EEMI API + */ +typedef struct __attribute__((packed)) { + uint8_t id; + uint8_t api_id; +} eemi_api_dependency; + +/* Dependent APIs for ATF to check their version from firmware */ +static const eemi_api_dependency api_dep_table[] = { + { + .id = PM_SELF_SUSPEND, + .api_id = PM_SELF_SUSPEND, + }, + { + .id = PM_REQ_WAKEUP, + .api_id = PM_REQ_WAKEUP, + }, + { + .id = PM_ABORT_SUSPEND, + .api_id = PM_ABORT_SUSPEND, + }, + { + .id = PM_SET_WAKEUP_SOURCE, + .api_id = PM_SET_WAKEUP_SOURCE, + }, + { + .id = PM_SYSTEM_SHUTDOWN, + .api_id = PM_SYSTEM_SHUTDOWN, + }, + { + .id = PM_GET_API_VERSION, + .api_id = PM_GET_API_VERSION, + }, + { + .id = PM_CLOCK_ENABLE, + .api_id = PM_PLL_SET_MODE, + }, + { + .id = PM_CLOCK_ENABLE, + .api_id = PM_CLOCK_ENABLE, + }, + { + .id = PM_CLOCK_DISABLE, + .api_id = PM_PLL_SET_MODE, + }, + { + .id = PM_CLOCK_DISABLE, + .api_id = PM_CLOCK_DISABLE, + }, + { + .id = PM_CLOCK_GETSTATE, + .api_id = PM_PLL_GET_MODE, + }, + { + .id = PM_CLOCK_GETSTATE, + .api_id = PM_CLOCK_GETSTATE, + }, + { + .id = PM_CLOCK_SETDIVIDER, + .api_id = PM_PLL_SET_PARAMETER, + }, + { + .id = PM_CLOCK_SETDIVIDER, + .api_id = PM_CLOCK_SETDIVIDER, + }, + { + .id = PM_CLOCK_GETDIVIDER, + .api_id = PM_PLL_GET_PARAMETER, + }, + { + .id = PM_CLOCK_GETDIVIDER, + .api_id = PM_CLOCK_GETDIVIDER, + }, + { + .id = PM_CLOCK_SETPARENT, + .api_id = PM_PLL_SET_PARAMETER, + }, + { + .id = PM_CLOCK_SETPARENT, + .api_id = PM_CLOCK_SETPARENT, + }, + { + .id = PM_CLOCK_GETPARENT, + .api_id = PM_PLL_GET_PARAMETER, + }, + { + .id = PM_CLOCK_GETPARENT, + .api_id = PM_CLOCK_GETPARENT, + }, + { + .id = PM_PLL_SET_PARAMETER, + .api_id = PM_PLL_SET_PARAMETER, + }, + { + .id = PM_PLL_GET_PARAMETER, + .api_id = PM_PLL_GET_PARAMETER, + }, + { + .id = PM_PLL_SET_MODE, + .api_id = PM_PLL_SET_MODE, + }, + { + .id = PM_PLL_GET_MODE, + .api_id = PM_PLL_GET_MODE, + }, + { + .id = PM_REGISTER_ACCESS, + .api_id = PM_MMIO_WRITE, + }, + { + .id = PM_REGISTER_ACCESS, + .api_id = PM_MMIO_READ, + }, + { + .id = PM_FEATURE_CHECK, + .api_id = PM_FEATURE_CHECK, + }, + { + .id = IOCTL_SET_TAPDELAY_BYPASS, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_SET_SGMII_MODE, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_SD_DLL_RESET, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_SET_SD_TAPDELAY, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_SET_SD_TAPDELAY, + .api_id = PM_MMIO_READ, + }, + { + .id = IOCTL_SET_PLL_FRAC_DATA, + .api_id = PM_PLL_SET_PARAMETER, + }, + { + .id = IOCTL_GET_PLL_FRAC_DATA, + .api_id = PM_PLL_GET_PARAMETER, + }, + { + .id = IOCTL_WRITE_GGS, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_READ_GGS, + .api_id = PM_MMIO_READ, + }, + { + .id = IOCTL_WRITE_PGGS, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_READ_PGGS, + .api_id = PM_MMIO_READ, + }, + { + .id = IOCTL_ULPI_RESET, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_SET_BOOT_HEALTH_STATUS, + .api_id = PM_MMIO_WRITE, + }, + { + .id = IOCTL_AFI, + .api_id = PM_MMIO_WRITE, + }, +}; + +/* Expected firmware API version to ATF */ +static const uint8_t atf_expected_ver_id[] = { + [PM_SELF_SUSPEND] = FW_API_BASE_VERSION, + [PM_REQ_WAKEUP] = FW_API_BASE_VERSION, + [PM_ABORT_SUSPEND] = FW_API_BASE_VERSION, + [PM_SET_WAKEUP_SOURCE] = FW_API_BASE_VERSION, + [PM_SYSTEM_SHUTDOWN] = FW_API_BASE_VERSION, + [PM_GET_API_VERSION] = FW_API_BASE_VERSION, + [PM_PLL_SET_MODE] = FW_API_BASE_VERSION, + [PM_PLL_GET_MODE] = FW_API_BASE_VERSION, + [PM_CLOCK_ENABLE] = FW_API_BASE_VERSION, + [PM_CLOCK_DISABLE] = FW_API_BASE_VERSION, + [PM_CLOCK_GETSTATE] = FW_API_BASE_VERSION, + [PM_PLL_SET_PARAMETER] = FW_API_BASE_VERSION, + [PM_PLL_GET_PARAMETER] = FW_API_BASE_VERSION, + [PM_CLOCK_SETDIVIDER] = FW_API_BASE_VERSION, + [PM_CLOCK_GETDIVIDER] = FW_API_BASE_VERSION, + [PM_CLOCK_SETPARENT] = FW_API_BASE_VERSION, + [PM_CLOCK_GETPARENT] = FW_API_BASE_VERSION, + [PM_MMIO_WRITE] = FW_API_BASE_VERSION, + [PM_MMIO_READ] = FW_API_BASE_VERSION, + [PM_FEATURE_CHECK] = FW_API_VERSION_2, +}; + /* default shutdown/reboot scope is system(2) */ static unsigned int pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM; @@ -33,38 +252,6 @@ unsigned int pm_get_shutdown_scope(void) return pm_shutdown_scope; } -/** - * Assigning of argument values into array elements. - */ -#define PM_PACK_PAYLOAD1(pl, arg0) { \ - pl[0] = (uint32_t)(arg0); \ -} - -#define PM_PACK_PAYLOAD2(pl, arg0, arg1) { \ - pl[1] = (uint32_t)(arg1); \ - PM_PACK_PAYLOAD1(pl, arg0); \ -} - -#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) { \ - pl[2] = (uint32_t)(arg2); \ - PM_PACK_PAYLOAD2(pl, arg0, arg1); \ -} - -#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) { \ - pl[3] = (uint32_t)(arg3); \ - PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2); \ -} - -#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) { \ - pl[4] = (uint32_t)(arg4); \ - PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3); \ -} - -#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) { \ - pl[5] = (uint32_t)(arg5); \ - PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \ -} - #define EM_PACK_PAYLOAD1(pl, arg0) { \ pl[0] = (uint16_t)(0xE) << 16 | (uint16_t)arg0; \ } @@ -305,36 +492,6 @@ enum pm_ret_status pm_set_requirement(enum pm_node_id nid, return pm_ipi_send(primary_proc, payload); } -/** - * pm_release_node() - PM call to release a node - * @nid Node id of the slave - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_release_node(enum pm_node_id nid) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_set_max_latency() - PM call to set wakeup latency requirements - * @nid Node id of the slave - * @latency Requested maximum wakeup latency - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_set_max_latency(enum pm_node_id nid, - unsigned int latency) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - /* Miscellaneous API functions */ /** @@ -352,36 +509,6 @@ enum pm_ret_status pm_get_api_version(unsigned int *version) return pm_ipi_send_sync(primary_proc, payload, version, 1); } -/** - * pm_set_configuration() - PM call to set system configuration - * @phys_addr Physical 32-bit address of data structure in memory - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_set_configuration(unsigned int phys_addr) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - PM_PACK_PAYLOAD2(payload, PM_SET_CONFIGURATION, phys_addr); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_init_finalize() - Call to notify PMU firmware that master has power - * management enabled and that it has finished its - * initialization - * - * @return Status returned by the PMU firmware - */ -enum pm_ret_status pm_init_finalize(void) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD1(payload, PM_INIT_FINALIZE); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - /** * pm_get_node_status() - PM call to request a node's current status * @nid Node id @@ -401,86 +528,6 @@ enum pm_ret_status pm_get_node_status(enum pm_node_id nid, return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3); } -/** - * pm_register_notifier() - Register the PU to be notified of PM events - * @nid Node id of the slave - * @event The event to be notified about - * @wake Wake up on event - * @enable Enable or disable the notifier - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_register_notifier(enum pm_node_id nid, - unsigned int event, - unsigned int wake, - unsigned int enable) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER, - nid, event, wake, enable); - - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_get_op_characteristic() - PM call to request operating characteristics - * of a node - * @nid Node id of the slave - * @type Type of the operating characteristic - * (power, temperature and latency) - * @result Returns the operating characteristic for the requested node, - * specified by the type - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid, - enum pm_opchar_type type, - uint32_t *result) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type); - return pm_ipi_send_sync(primary_proc, payload, result, 1); -} - -/* Direct-Control API functions */ - -/** - * pm_reset_assert() - Assert reset - * @reset Reset ID - * @assert Assert (1) or de-assert (0) - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_reset_assert(unsigned int reset, - unsigned int assert) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_reset_get_status() - Get current status of a reset line - * @reset Reset ID - * @reset_status Returns current status of selected reset line - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_reset_get_status(unsigned int reset, - unsigned int *reset_status) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset); - return pm_ipi_send_sync(primary_proc, payload, reset_status, 1); -} - /** * pm_mmio_write() - Perform write to protected mmio * @address Address to write to @@ -649,113 +696,6 @@ void pm_get_callbackdata(uint32_t *data, size_t count) pm_ipi_irq_clear(primary_proc); } -/** - * pm_pinctrl_request() - Request Pin from firmware - * @pin Pin number to request - * - * This function requests pin from firmware. - * - * @return Returns status, either success or error+reason. - */ -enum pm_ret_status pm_pinctrl_request(unsigned int pin) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD2(payload, PM_PINCTRL_REQUEST, pin); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_pinctrl_release() - Release Pin from firmware - * @pin Pin number to release - * - * This function releases pin from firmware. - * - * @return Returns status, either success or error+reason. - */ -enum pm_ret_status pm_pinctrl_release(unsigned int pin) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD2(payload, PM_PINCTRL_RELEASE, pin); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_pinctrl_get_function() - Read function id set for the given pin - * @pin Pin number - * @fid ID of function currently set for given pin - * - * This function provides the function currently set for the given pin. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, unsigned int *fid) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - PM_PACK_PAYLOAD2(payload, PM_PINCTRL_GET_FUNCTION, pin); - return pm_ipi_send_sync(primary_proc, payload, fid, 1); -} - -/** - * pm_pinctrl_set_function() - Set function id set for the given pin - * @pin Pin number - * @fid ID of function to set for given pin - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, unsigned int fid) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD3(payload, PM_PINCTRL_SET_FUNCTION, pin, fid); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - -/** - * pm_pinctrl_get_config() - Read value of requested config param for given pin - * @pin Pin number - * @param Parameter values to be read - * @value Buffer for configuration Parameter value - * - * This function provides the configuration parameter value for the given pin. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_pinctrl_get_config(unsigned int pin, - unsigned int param, - unsigned int *value) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - PM_PACK_PAYLOAD3(payload, PM_PINCTRL_CONFIG_PARAM_GET, pin, param); - return pm_ipi_send_sync(primary_proc, payload, value, 1); -} - -/** - * pm_pinctrl_set_config() - Set value of requested config param for given pin - * @pin Pin number - * @param Parameter to set - * @value Parameter value to set - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_pinctrl_set_config(unsigned int pin, - unsigned int param, - unsigned int value) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD4(payload, PM_PINCTRL_CONFIG_PARAM_SET, pin, param, - value); - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); -} - /** * pm_ioctl() - PM IOCTL API for device control and configs * @node_id Node ID of the device @@ -777,6 +717,220 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid, return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value); } +/** + * fw_api_version() - Returns API version implemented in firmware + * @api_id API ID to check + * @version Returned supported API version + * @len Number of words to be returned + * + * @return Returns status, either success or error+reason + */ +static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version, + uint32_t len) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + PM_PACK_PAYLOAD2(payload, PM_FEATURE_CHECK, id); + return pm_ipi_send_sync(primary_proc, payload, version, len); +} + +/** + * check_api_dependency() - API to check dependent EEMI API version + * @id EEMI API ID to check + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status check_api_dependency(uint8_t id) +{ + uint8_t i; + uint32_t version; + int ret; + + for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) { + if (api_dep_table[i].id == id) { + if (api_dep_table[i].api_id == 0U) { + break; + } + + ret = fw_api_version(api_dep_table[i].api_id, + &version, 1); + if (ret != PM_RET_SUCCESS) { + return ret; + } + + /* Check if fw version matches ATF expected version */ + if (version != atf_expected_ver_id[api_dep_table[i].api_id]) { + return PM_RET_ERROR_NOTSUPPORTED; + } + } + } + + return PM_RET_SUCCESS; +} + +/** + * feature_check_atf() - These are API's completely implemented in ATF + * @api_id API ID to check + * @version Returned supported API version + * + * @return Returns status, either success or error+reason + */ +static enum pm_ret_status feature_check_atf(uint32_t api_id, uint32_t *version, + uint32_t *bit_mask) +{ + switch (api_id) { + case PM_QUERY_DATA: + *version = ATF_API_BASE_VERSION; + bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK); + bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32); + return PM_RET_SUCCESS; + case PM_GET_CALLBACK_DATA: + case PM_GET_TRUSTZONE_VERSION: + case PM_SET_SUSPEND_MODE: + *version = ATF_API_BASE_VERSION; + return PM_RET_SUCCESS; + default: + return PM_RET_ERROR_NO_FEATURE; + } +} + +/** + * get_atf_version_for_partial_apis() - Return ATF version for partially + * implemented APIs + * @api_id API ID to check + * @version Returned supported API version + * + * @return Returns status, either success or error+reason + */ +static enum pm_ret_status get_atf_version_for_partial_apis(uint32_t api_id, + uint32_t *version) +{ + switch (api_id) { + case PM_SELF_SUSPEND: + case PM_REQ_WAKEUP: + case PM_ABORT_SUSPEND: + case PM_SET_WAKEUP_SOURCE: + case PM_SYSTEM_SHUTDOWN: + case PM_GET_API_VERSION: + 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_REGISTER_ACCESS: + *version = ATF_API_BASE_VERSION; + return PM_RET_SUCCESS; + case PM_FEATURE_CHECK: + *version = FW_API_VERSION_2; + return PM_RET_SUCCESS; + default: + return PM_RET_ERROR_ARGS; + } +} + +/** + * feature_check_partial() - These are API's partially implemented in + * ATF and firmware both + * @api_id API ID to check + * @version Returned supported API version + * + * @return Returns status, either success or error+reason + */ +static enum pm_ret_status feature_check_partial(uint32_t api_id, + uint32_t *version) +{ + uint32_t status; + + switch (api_id) { + case PM_SELF_SUSPEND: + case PM_REQ_WAKEUP: + case PM_ABORT_SUSPEND: + case PM_SET_WAKEUP_SOURCE: + case PM_SYSTEM_SHUTDOWN: + case PM_GET_API_VERSION: + 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_REGISTER_ACCESS: + case PM_FEATURE_CHECK: + status = check_api_dependency(api_id); + if (status != PM_RET_SUCCESS) { + return status; + } + return get_atf_version_for_partial_apis(api_id, version); + default: + return PM_RET_ERROR_NO_FEATURE; + } +} + +/** + * pm_feature_check() - Returns the supported API version if supported + * @api_id API ID to check + * @version Returned supported API version + * @bit_mask Returned supported IOCTL id version + * @len Number of bytes to be returned in bit_mask variable + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version, + uint32_t *bit_mask, uint8_t len) +{ + uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U}; + uint32_t status; + + /* Get API version implemented in ATF */ + status = feature_check_atf(api_id, version, bit_mask); + if (status != PM_RET_ERROR_NO_FEATURE) { + return status; + } + + /* Get API version implemented by firmware and ATF both */ + status = feature_check_partial(api_id, version); + if (status != PM_RET_ERROR_NO_FEATURE) { + return status; + } + + /* Get API version implemented by firmware */ + status = fw_api_version(api_id, ret_payload, 3); + /* IOCTL call may return failure whose ID is not implemented in + * firmware but implemented in ATF + */ + if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) { + return status; + } + + *version = ret_payload[0]; + + /* Update IOCTL bit mask which are implemented in ATF */ + if (api_id == PM_IOCTL) { + if (len < 2) { + return PM_RET_ERROR_ARGS; + } + bit_mask[0] = ret_payload[1]; + bit_mask[1] = ret_payload[2]; + /* Get IOCTL's implemented by ATF */ + status = atf_ioctl_bitmask(bit_mask); + } else { + /* Requires for MISRA */ + } + + return status; +} + /** * pm_clock_get_max_divisor - PM call to get max divisor * @clock_id Clock ID @@ -1648,36 +1802,3 @@ enum pm_ret_status em_send_errors(unsigned int *value) EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS); return pm_ipi_send_sync(primary_proc, payload, value, 1); } - -/** - * pm_feature_config() - feature configuration at runtime - * - * This function is used to send IPI request to PMUFW to configure feature - * at runtime. The feature can be enable or disable as well as the feature - * can be configure at runtime using an IOCTL call. - * - * @ioctl_id The ioctl id for the feature configuration - * @config_id The config id of the feature to be configured - * @value The value to be configured - * @response Return to reference pointer - * - * @return Returns 0 on success or error value on failure - */ -enum pm_ret_status pm_feature_config(unsigned int ioctl_id, - unsigned int config_id, - unsigned int value, - unsigned int *response) -{ - uint32_t payload[PAYLOAD_ARG_CNT]; - - /* Send request to the PMU */ - PM_PACK_PAYLOAD5(payload, PM_IOCTL, 0, ioctl_id, config_id, value); - - if (ioctl_id == IOCTL_GET_FEATURE_CONFIG) { - return pm_ipi_send_sync(primary_proc, payload, response, 1); - } else if (ioctl_id == IOCTL_SET_FEATURE_CONFIG) { - return pm_ipi_send_sync(primary_proc, payload, NULL, 0); - } else { - return PM_RET_ERROR_ARGS; - } -} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index ca07cef75..4e38c42b4 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -33,6 +33,38 @@ enum pm_register_access_id { CONFIG_REG_READ, }; +/** + * Assigning of argument values into array elements. + */ +#define PM_PACK_PAYLOAD1(pl, arg0) { \ + pl[0] = (uint32_t)(arg0); \ +} + +#define PM_PACK_PAYLOAD2(pl, arg0, arg1) { \ + pl[1] = (uint32_t)(arg1); \ + PM_PACK_PAYLOAD1(pl, arg0); \ +} + +#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) { \ + pl[2] = (uint32_t)(arg2); \ + PM_PACK_PAYLOAD2(pl, arg0, arg1); \ +} + +#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) { \ + pl[3] = (uint32_t)(arg3); \ + PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2); \ +} + +#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) { \ + pl[4] = (uint32_t)(arg4); \ + PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3); \ +} + +#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) { \ + pl[5] = (uint32_t)(arg5); \ + PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \ +} + /********************************************************** * System-level API function declarations **********************************************************/ @@ -72,28 +104,16 @@ enum pm_ret_status pm_req_node(enum pm_node_id nid, unsigned int capabilities, unsigned int qos, enum pm_request_ack ack); -enum pm_ret_status pm_release_node(enum pm_node_id nid); enum pm_ret_status pm_set_requirement(enum pm_node_id nid, unsigned int capabilities, unsigned int qos, enum pm_request_ack ack); -enum pm_ret_status pm_set_max_latency(enum pm_node_id nid, - unsigned int latency); /* Miscellaneous API functions */ enum pm_ret_status pm_get_api_version(unsigned int *version); -enum pm_ret_status pm_set_configuration(unsigned int phys_addr); -enum pm_ret_status pm_init_finalize(void); enum pm_ret_status pm_get_node_status(enum pm_node_id node, uint32_t *ret_buff); -enum pm_ret_status pm_register_notifier(enum pm_node_id nid, - unsigned int event, - unsigned int wake, - unsigned int enable); -enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid, - enum pm_opchar_type type, - uint32_t *result); enum pm_ret_status pm_acknowledge_cb(enum pm_node_id nid, enum pm_ret_status status, unsigned int oppoint); @@ -102,10 +122,6 @@ enum pm_ret_status pm_notify_cb(enum pm_node_id nid, unsigned int oppoint); /* Direct-Control API functions */ -enum pm_ret_status pm_reset_assert(unsigned int reset_id, - unsigned int assert); -enum pm_ret_status pm_reset_get_status(unsigned int reset_id, - unsigned int *reset_status); enum pm_ret_status pm_mmio_write(uintptr_t address, unsigned int mask, unsigned int value); @@ -123,18 +139,6 @@ enum pm_ret_status pm_secure_rsaaes(uint32_t address_high, uint32_t flags); unsigned int pm_get_shutdown_scope(void); void pm_get_callbackdata(uint32_t *data, size_t count); -enum pm_ret_status pm_pinctrl_request(unsigned int pin); -enum pm_ret_status pm_pinctrl_release(unsigned int pin); -enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, - enum pm_node_id *nid); -enum pm_ret_status pm_pinctrl_set_function(unsigned int pin, - enum pm_node_id nid); -enum pm_ret_status pm_pinctrl_get_config(unsigned int pin, - unsigned int param, - unsigned int *value); -enum pm_ret_status pm_pinctrl_set_config(unsigned int pin, - unsigned int param, - unsigned int value); enum pm_ret_status pm_ioctl(enum pm_node_id nid, unsigned int ioctl_id, unsigned int arg1, @@ -206,5 +210,8 @@ enum pm_ret_status pm_feature_config(unsigned int ioctl_id, unsigned int config_id, unsigned int value, unsigned int *response); +enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version, + uint32_t *bit_mask, uint8_t len); +enum pm_ret_status check_api_dependency(uint8_t id); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h index 3324431dd..2baf9607d 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_defs.h +++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,6 +22,16 @@ #define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR) +/** + * PM API versions + */ +/* Expected version of firmware APIs */ +#define FW_API_BASE_VERSION (1U) +/* Expected version of firmware API for feature check */ +#define FW_API_VERSION_2 (2U) +/* Version of APIs implemented in ATF */ +#define ATF_API_BASE_VERSION (1U) + /* Capabilities for RAM */ #define PM_CAP_ACCESS 0x1U #define PM_CAP_CONTEXT 0x2U @@ -33,7 +43,18 @@ #define PM_STATE_CPU_IDLE 0x0U #define PM_STATE_SUSPEND_TO_RAM 0xFU +/* APU processor states */ +#define PM_PROC_STATE_FORCEDOFF 0U +#define PM_PROC_STATE_ACTIVE 1U +#define PM_PROC_STATE_SLEEP 2U +#define PM_PROC_STATE_SUSPENDING 3U + #define EM_FUNID_NUM_MASK 0xF0000U + +#define PM_GET_CALLBACK_DATA 0xa01 +#define PM_SET_SUSPEND_MODE 0xa02 +#define PM_GET_TRUSTZONE_VERSION 0xa03 + /********************************************************************* * Enum definitions ********************************************************************/ @@ -101,6 +122,9 @@ enum pm_api_id { /* PM Register Access API */ PM_REGISTER_ACCESS, PM_EFUSE_ACCESS, + PM_FPGA_GET_VERSION, + PM_FPGA_GET_FEATURE_LIST, + PM_FEATURE_CHECK = 63, PM_API_MAX }; @@ -241,7 +265,8 @@ enum pm_ret_status { PM_RET_ERROR_DOUBLE_REQ = 2004, PM_RET_ERROR_ABORT_SUSPEND = 2005, PM_RET_ERROR_TIMEOUT = 2006, - PM_RET_ERROR_NODE_USED = 2007 + PM_RET_ERROR_NODE_USED = 2007, + PM_RET_ERROR_NO_FEATURE = 2008 }; /** diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index a49bda8d2..b789da14c 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,12 +23,9 @@ #include #include "pm_api_sys.h" #include "pm_client.h" +#include "pm_defs.h" #include "pm_ipi.h" -#define PM_GET_CALLBACK_DATA 0xa01 -#define PM_SET_SUSPEND_MODE 0xa02 -#define PM_GET_TRUSTZONE_VERSION 0xa03 - /* pm_up = !0 - UP, pm_up = 0 - DOWN */ static int32_t pm_up, ipi_irq_flag; @@ -262,8 +259,11 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, void *cookie, void *handle, uint64_t flags) { enum pm_ret_status ret; + uint32_t payload[PAYLOAD_ARG_CNT]; uint32_t pm_arg[4]; + uint32_t result[PAYLOAD_ARG_CNT]; + uint32_t api_id; /* Handle case where PM wasn't initialized properly */ if (!pm_up) @@ -273,8 +273,11 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, pm_arg[1] = (uint32_t)(x1 >> 32); pm_arg[2] = (uint32_t)x2; pm_arg[3] = (uint32_t)(x2 >> 32); + pm_arg[4] = (uint32_t)x3; - switch (smc_fid & FUNCID_NUM_MASK) { + api_id = smc_fid & FUNCID_NUM_MASK; + + switch (api_id) { /* PM API Functions */ case PM_SELF_SUSPEND: ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2], @@ -318,19 +321,11 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, ret = pm_req_node(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); SMC_RET1(handle, (uint64_t)ret); - case PM_RELEASE_NODE: - ret = pm_release_node(pm_arg[0]); - SMC_RET1(handle, (uint64_t)ret); - case PM_SET_REQUIREMENT: ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); SMC_RET1(handle, (uint64_t)ret); - case PM_SET_MAX_LATENCY: - ret = pm_set_max_latency(pm_arg[0], pm_arg[1]); - SMC_RET1(handle, (uint64_t)ret); - case PM_GET_API_VERSION: /* Check is PM API version already verified */ if (pm_ctx.api_version >= PM_VERSION) { @@ -348,62 +343,6 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, ((uint64_t)pm_ctx.api_version << 32)); } - case PM_SET_CONFIGURATION: - ret = pm_set_configuration(pm_arg[0]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_INIT_FINALIZE: - ret = pm_init_finalize(); - SMC_RET1(handle, (uint64_t)ret); - - case PM_GET_NODE_STATUS: - { - uint32_t buff[3]; - - ret = pm_get_node_status(pm_arg[0], buff); - SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buff[0] << 32), - (uint64_t)buff[1] | ((uint64_t)buff[2] << 32)); - } - - case PM_GET_OP_CHARACTERISTIC: - { - uint32_t result; - - ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result); - SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32)); - } - - case PM_REGISTER_NOTIFIER: - ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2], - pm_arg[3]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_RESET_ASSERT: - ret = pm_reset_assert(pm_arg[0], pm_arg[1]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_RESET_GET_STATUS: - { - uint32_t reset_status; - - ret = pm_reset_get_status(pm_arg[0], &reset_status); - SMC_RET1(handle, (uint64_t)ret | - ((uint64_t)reset_status << 32)); - } - - /* PM memory access functions */ - case PM_MMIO_WRITE: - ret = pm_mmio_write(pm_arg[0], pm_arg[1], pm_arg[2]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_MMIO_READ: - { - uint32_t value; - - ret = pm_mmio_read(pm_arg[0], &value); - SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); - } - case PM_FPGA_LOAD: ret = pm_fpga_load(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); SMC_RET1(handle, (uint64_t)ret); @@ -416,62 +355,16 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); } - case PM_GET_CHIPID: - { - uint32_t result[2]; - - ret = pm_get_chipid(result); - SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32), - result[1]); - } - case PM_SECURE_RSA_AES: ret = pm_secure_rsaaes(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); SMC_RET1(handle, (uint64_t)ret); case PM_GET_CALLBACK_DATA: - { - uint32_t result[4] = {0}; - pm_get_callbackdata(result, ARRAY_SIZE(result)); SMC_RET2(handle, (uint64_t)result[0] | ((uint64_t)result[1] << 32), (uint64_t)result[2] | ((uint64_t)result[3] << 32)); - } - - case PM_PINCTRL_REQUEST: - ret = pm_pinctrl_request(pm_arg[0]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_PINCTRL_RELEASE: - ret = pm_pinctrl_release(pm_arg[0]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_PINCTRL_GET_FUNCTION: - { - uint32_t value = 0; - - ret = pm_pinctrl_get_function(pm_arg[0], &value); - SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); - } - - case PM_PINCTRL_SET_FUNCTION: - ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1]); - SMC_RET1(handle, (uint64_t)ret); - - case PM_PINCTRL_CONFIG_PARAM_GET: - { - uint32_t value; - - ret = pm_pinctrl_get_config(pm_arg[0], pm_arg[1], &value); - SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); - } - - case PM_PINCTRL_CONFIG_PARAM_SET: - ret = pm_pinctrl_set_config(pm_arg[0], pm_arg[1], pm_arg[2]); - SMC_RET1(handle, (uint64_t)ret); - case PM_IOCTL: { uint32_t value; @@ -568,8 +461,6 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, case PM_SECURE_IMAGE: { - uint32_t result[2]; - ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3], &result[0]); SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32), @@ -634,9 +525,37 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); } + case PM_FPGA_GET_VERSION: + case PM_FPGA_GET_FEATURE_LIST: + { + uint32_t ret_payload[PAYLOAD_ARG_CNT]; + + PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK, + pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); + ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U); + SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32, + (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32); + } + + case PM_FEATURE_CHECK: + { + uint32_t version; + uint32_t bit_mask[2] = {0}; + + ret = pm_feature_check(pm_arg[0], &version, bit_mask, + ARRAY_SIZE(bit_mask)); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32), + (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32)); + } + default: - WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); - SMC_RET1(handle, SMC_UNK); + /* Send request to the PMU */ + PM_PACK_PAYLOAD6(payload, api_id, pm_arg[0], pm_arg[1], + pm_arg[2], pm_arg[3], pm_arg[4]); + ret = pm_ipi_send_sync(primary_proc, payload, result, + PAYLOAD_ARG_CNT); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32), + (uint64_t)result[1] | ((uint64_t)result[2] << 32)); } }