aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish Pandey <manish.pandey2@arm.com>2020-12-09 22:44:44 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2020-12-09 22:44:44 +0000
commit852e494075d92199e9bddfe92d364f2107a5a25d (patch)
treea31260b8196306ada277ef8bcc5603d38062766e
parentc8e862367672d01bd4e9565f8a2109946853ccd5 (diff)
parent6af1228677a5fed17dbcfa92eacf83cba4b9a92b (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.c4
-rw-r--r--plat/xilinx/versal/bl31_versal_setup.c2
-rw-r--r--plat/xilinx/versal/plat_psci.c12
-rw-r--r--plat/xilinx/versal/pm_service/pm_api_sys.c108
-rw-r--r--plat/xilinx/versal/pm_service/pm_api_sys.h7
-rw-r--r--plat/xilinx/versal/pm_service/pm_client.c9
-rw-r--r--plat/xilinx/versal/pm_service/pm_defs.h27
-rw-r--r--plat/xilinx/versal/pm_service/pm_svc_main.c33
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);