diff options
author | Manish Pandey <manish.pandey2@arm.com> | 2020-12-09 22:44:44 +0000 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2020-12-09 22:44:44 +0000 |
commit | 852e494075d92199e9bddfe92d364f2107a5a25d (patch) | |
tree | a31260b8196306ada277ef8bcc5603d38062766e | |
parent | c8e862367672d01bd4e9565f8a2109946853ccd5 (diff) | |
parent | 6af1228677a5fed17dbcfa92eacf83cba4b9a92b (diff) |
Merge changes from topic "versal-bug-fixes-and-new-apis" into integration
* changes:
plat: xilinx: versal: Add support of register notifier
plat: xilinx: versal: Add support to get clock rate value
plat: xilinx: versal: Add support of set max latency for the device
plat: versal: Add InitFinalize API call
xilinx: versal: Updated Response of QueryData API call
plat:xilinx:versal: Use defaults when PDI is without sw partitions
plat: xilinx: Mask unnecessary bytes of return error code
xilinx: versal: Skip store/restore of GIC during CPU idle
plat: versal: Update API list in feature check
xilinx: versal: Do not pass ACPU0 always in set_wakeup_source()
-rw-r--r-- | plat/xilinx/common/pm_service/pm_ipi.c | 4 | ||||
-rw-r--r-- | plat/xilinx/versal/bl31_versal_setup.c | 2 | ||||
-rw-r--r-- | plat/xilinx/versal/plat_psci.c | 12 | ||||
-rw-r--r-- | plat/xilinx/versal/pm_service/pm_api_sys.c | 108 | ||||
-rw-r--r-- | plat/xilinx/versal/pm_service/pm_api_sys.h | 7 | ||||
-rw-r--r-- | plat/xilinx/versal/pm_service/pm_client.c | 9 | ||||
-rw-r--r-- | plat/xilinx/versal/pm_service/pm_defs.h | 27 | ||||
-rw-r--r-- | plat/xilinx/versal/pm_service/pm_svc_main.c | 33 |
8 files changed, 180 insertions, 22 deletions
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c index c83d25b0d9..5dcceaea25 100644 --- a/plat/xilinx/common/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.c @@ -18,6 +18,8 @@ #include "pm_ipi.h" +#define ERROR_CODE_MASK 0xFFFFU + DEFINE_BAKERY_LOCK(pm_secure_lock); /** @@ -230,7 +232,7 @@ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc, if (ret != PM_RET_SUCCESS) goto unlock; - ret = pm_ipi_buff_read(proc, value, count); + ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count)); unlock: bakery_lock_release(&pm_secure_lock); diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index 03b7fbbb47..27991d3818 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -97,7 +97,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info, &bl33_image_ep_info, atf_handoff_addr); - if (ret == FSBL_HANDOFF_NO_STRUCT) { + if (ret == FSBL_HANDOFF_NO_STRUCT || ret == FSBL_HANDOFF_INVAL_STRUCT) { bl31_set_default_config(); } else if (ret != FSBL_HANDOFF_SUCCESS) { panic(); diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c index 39550858ad..fda42dfda8 100644 --- a/plat/xilinx/versal/plat_psci.c +++ b/plat/xilinx/versal/plat_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -59,7 +59,9 @@ static void versal_pwr_domain_suspend(const psci_power_state_t *target_state) plat_versal_gic_cpuif_disable(); - plat_versal_gic_save(); + if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { + plat_versal_gic_save(); + } state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ? PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE; @@ -99,11 +101,9 @@ static void versal_pwr_domain_suspend_finish( /* APU was turned off, so restore GIC context */ if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { plat_versal_gic_resume(); - plat_versal_gic_cpuif_enable(); - } else { - plat_versal_gic_cpuif_enable(); - plat_versal_gic_pcpu_init(); } + + plat_versal_gic_cpuif_enable(); } void versal_pwr_domain_on_finish(const psci_power_state_t *target_state) diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index dbe94e6249..df6c9af49e 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,7 @@ #include <plat/common/platform.h> #include "pm_api_sys.h" #include "pm_client.h" +#include "pm_defs.h" /********************************************************************* * Target module IDs macros @@ -84,6 +85,22 @@ enum pm_ret_status pm_get_api_version(unsigned int *version) } /** + * pm_init_finalize() - Call to notify PMC PM 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, LIBPM_MODULE_ID, PM_INIT_FINALIZE); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** * pm_self_suspend() - PM call for processor to suspend itself * @nid Node id of the processor or subsystem * @latency Requested maximum wakeup latency (not supported) @@ -554,6 +571,22 @@ enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent) return pm_ipi_send_sync(primary_proc, payload, parent, 1); } +/** + * pm_clock_get_rate() - Get the rate value for the clock + * @clk_id Clock ID + * @rate: Buffer to store clock rate value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETRATE, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2); +} /** * pm_pll_set_param() - Set PLL parameter @@ -689,12 +722,31 @@ enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype) enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t *data) { + uint32_t ret; + uint32_t version; uint32_t payload[PAYLOAD_ARG_CNT]; + uint32_t fw_api_version; /* Send request to the PMC */ PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_QUERY_DATA, qid, arg1, arg2, arg3); - return pm_ipi_send_sync(primary_proc, payload, data, 4); + + ret = pm_feature_check(PM_QUERY_DATA, &version); + if (PM_RET_SUCCESS == ret){ + fw_api_version = version & 0xFFFF ; + if ((2U == fw_api_version) && + ((XPM_QID_CLOCK_GET_NAME == qid) || + (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) { + ret = pm_ipi_send_sync(primary_proc, payload, data, 8); + ret = data[0]; + data[0] = data[1]; + data[1] = data[2]; + data[2] = data[3]; + } else { + ret = pm_ipi_send_sync(primary_proc, payload, data, 4); + } + } + return ret; } /** * pm_api_ioctl() - PM IOCTL API for device control and configs @@ -780,7 +832,6 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) 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: @@ -798,6 +849,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_SET_REQUIREMENT: case PM_RESET_ASSERT: case PM_RESET_GET_STATUS: + case PM_GET_CHIPID: case PM_PINCTRL_REQUEST: case PM_PINCTRL_RELEASE: case PM_PINCTRL_GET_FUNCTION: @@ -805,7 +857,11 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_PINCTRL_CONFIG_PARAM_GET: case PM_PINCTRL_CONFIG_PARAM_SET: case PM_IOCTL: + *version = (PM_API_BASE_VERSION << 16); + break; case PM_QUERY_DATA: + *version = (PM_API_QUERY_DATA_VERSION << 16); + break; case PM_CLOCK_ENABLE: case PM_CLOCK_DISABLE: case PM_CLOCK_GETSTATE: @@ -813,11 +869,15 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) case PM_CLOCK_GETDIVIDER: case PM_CLOCK_SETPARENT: case PM_CLOCK_GETPARENT: + case PM_CLOCK_GETRATE: case PM_PLL_SET_PARAMETER: case PM_PLL_GET_PARAMETER: case PM_PLL_SET_MODE: case PM_PLL_GET_MODE: case PM_FEATURE_CHECK: + case PM_INIT_FINALIZE: + case PM_SET_MAX_LATENCY: + case PM_REGISTER_NOTIFIER: *version = (PM_API_BASE_VERSION << 16); break; case PM_LOAD_PDI: @@ -883,3 +943,45 @@ enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, device_id, type); return pm_ipi_send_sync(primary_proc, payload, result, 1); } + +/** + * pm_set_max_latency() - PM call to change in the maximum wake-up latency + * requirements for a specific device currently + * used by that CPU. + * @device_id Device ID + * @latency Latency value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_SET_MAX_LATENCY, + device_id, latency); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_register_notifier() - PM call to register a subsystem to be notified + * about the device event + * @device_id Device ID for the Node to which the event is related + * @event Event in question + * @wake Wake subsystem upon capturing the event if value 1 + * @enable Enable the registration for value 1, disable for value 0 + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event, + uint32_t wake, uint32_t enable) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REGISTER_NOTIFIER, + device_id, event, wake, enable); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index 4de592a2f4..84867b638c 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,7 @@ **********************************************************/ enum pm_ret_status pm_get_api_version(unsigned int *version); +enum pm_ret_status pm_init_finalize(void); enum pm_ret_status pm_self_suspend(uint32_t nid, unsigned int latency, unsigned int state, @@ -52,6 +53,7 @@ enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider); enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider); enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent); enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent); +enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate); enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param, uint32_t value); enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param, @@ -72,4 +74,7 @@ enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low, enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, enum pm_opchar_type type, uint32_t *result); +enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency); +enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event, + uint32_t wake, uint32_t enable); #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c index 5b47838e90..9ab921ee7c 100644 --- a/plat/xilinx/versal/pm_service/pm_client.c +++ b/plat/xilinx/versal/pm_service/pm_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -113,8 +113,9 @@ static enum pm_device_node_idx irq_to_pm_node_idx(unsigned int irq) /** * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as * wake sources in the LibPM. + * @node_id: Node id of processor */ -static void pm_client_set_wakeup_sources(void) +static void pm_client_set_wakeup_sources(uint32_t node_id) { uint32_t reg_num; uint32_t device_id; @@ -147,7 +148,7 @@ static void pm_client_set_wakeup_sources(void) (!pm_wakeup_nodes_set[node_idx])) { /* Get device ID from node index */ device_id = PERIPH_DEVID(node_idx); - ret = pm_set_wakeup_source(XPM_DEVID_ACPU_0, + ret = pm_set_wakeup_source(node_id, device_id, 1); pm_wakeup_nodes_set[node_idx] = !ret; } @@ -167,7 +168,7 @@ void pm_client_suspend(const struct pm_proc *proc, unsigned int state) bakery_lock_get(&pm_client_secure_lock); if (state == PM_STATE_SUSPEND_TO_RAM) - pm_client_set_wakeup_sources(); + pm_client_set_wakeup_sources(proc->node_id); /* Set powerdown request */ mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) | diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index 966b00bb50..793f750091 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,10 +39,13 @@ /* PM API Versions */ #define PM_API_BASE_VERSION 1U +#define PM_API_QUERY_DATA_VERSION 2U + /* PM API ids */ #define PM_GET_API_VERSION 1U #define PM_GET_DEVICE_STATUS 3U #define PM_GET_OP_CHARACTERISTIC 4U +#define PM_REGISTER_NOTIFIER 5U #define PM_REQ_SUSPEND 6U #define PM_SELF_SUSPEND 7U #define PM_FORCE_POWERDOWN 8U @@ -53,6 +56,7 @@ #define PM_REQUEST_DEVICE 13U #define PM_RELEASE_DEVICE 14U #define PM_SET_REQUIREMENT 15U +#define PM_SET_MAX_LATENCY 16U #define PM_RESET_ASSERT 17U #define PM_RESET_GET_STATUS 18U #define PM_INIT_FINALIZE 21U @@ -163,4 +167,25 @@ enum pm_ret_status { PM_RET_ERROR_TIMEOUT = 2006, PM_RET_ERROR_NODE_USED = 2007 }; + +/** + * Qids + */ +enum pm_query_id { + XPM_QID_INVALID, + XPM_QID_CLOCK_GET_NAME, + XPM_QID_CLOCK_GET_TOPOLOGY, + XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS, + XPM_QID_CLOCK_GET_MUXSOURCES, + XPM_QID_CLOCK_GET_ATTRIBUTES, + XPM_QID_PINCTRL_GET_NUM_PINS, + XPM_QID_PINCTRL_GET_NUM_FUNCTIONS, + XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS, + XPM_QID_PINCTRL_GET_FUNCTION_NAME, + XPM_QID_PINCTRL_GET_FUNCTION_GROUPS, + XPM_QID_PINCTRL_GET_PIN_GROUPS, + XPM_QID_CLOCK_GET_NUM_CLOCKS, + XPM_QID_CLOCK_GET_MAX_DIVISOR, + XPM_QID_PLD_GET_PARENT, +}; #endif /* PM_DEFS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index 45b2803704..2ed6d27015 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -159,7 +159,8 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, } case PM_INIT_FINALIZE: - SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS); + ret = pm_init_finalize(); + SMC_RET1(handle, (uint64_t)ret); case PM_GET_CALLBACK_DATA: { @@ -214,14 +215,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, case PM_QUERY_DATA: { - uint32_t data[4] = { 0 }; + uint32_t data[8] = { 0 }; ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2], - pm_arg[3], data); + pm_arg[3], data); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32), - (uint64_t)data[1] | ((uint64_t)data[2] << 32)); - } + (uint64_t)data[1] | ((uint64_t)data[2] << 32)); + } case PM_CLOCK_ENABLE: ret = pm_clock_enable(pm_arg[0]); SMC_RET1(handle, (uint64_t)ret); @@ -262,6 +264,15 @@ 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_CLOCK_GETRATE: + { + uint32_t rate[2] = { 0 }; + + ret = pm_clock_get_rate(pm_arg[0], rate); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)rate[0] << 32), + rate[1]); + } + case PM_PLL_SET_PARAMETER: ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2]); SMC_RET1(handle, (uint64_t)ret); @@ -321,6 +332,18 @@ 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)result << 32)); } + case PM_SET_MAX_LATENCY: + { + ret = pm_set_max_latency(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + } + + 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); + } + default: WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); |