fix(zynqmp): query node status to power up APU
If APU is in suspending state and if wakeup request comes then
PMUFW returns error which is not handled at ATF side.
To fix this, get the APU node status before calling wakeup and
return error if found in suspending state.
Here, we can not handle the error code of pm_req_wakeup() from PMUFW
because ATF is already calling pm_client_wakeup() before calling
pm_req_wakeup().
Signed-off-by: Ravi Patel <ravi.patel@xilinx.com>
Signed-off-by: Ronak Jain <ronak.jain@xilinx.com>
Change-Id: I18d47384e46e22ae49e804093ad0641b7a6349e2
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index f78b88c..b2b473a 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 @@
{
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 @@
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_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 1933b87..2baf960 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
*/
@@ -43,6 +43,12 @@
#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