Merge changes from topic "fix-power-up-dwn-issue" into integration
* changes:
fix(versal-net): enable wake interrupt during client suspend
fix(versal-net): disable wakeup interrupt during client wakeup
fix(versal-net): clear power down bit during wakeup
fix(versal-net): fix setting power down state
fix(versal-net): clear power down interrupt status before enable
fix(versal-net): resolve misra rule 20.7 warnings
fix(versal-net): resolve misra 10.6 warnings
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 8cb5bf3..929186a 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -53,9 +53,9 @@
#define PSX_CRF_RST_TIMESTAMP_OFFSET U(0x33C)
-#define APU_PCLI U(0xECB10000)
-#define APU_PCLI_CPU_STEP U(0x30)
-#define APU_PCLI_CLUSTER_CPU_STEP (4U * APU_PCLI_CPU_STEP)
+#define APU_PCLI (0xECB10000ULL)
+#define APU_PCLI_CPU_STEP (0x30ULL)
+#define APU_PCLI_CLUSTER_CPU_STEP (4ULL * APU_PCLI_CPU_STEP)
#define APU_PCLI_CLUSTER_OFFSET U(0x8000)
#define APU_PCLI_CLUSTER_STEP U(0x1000)
#define PCLI_PREQ_OFFSET U(0x4)
@@ -67,13 +67,29 @@
/* Firmware Image Package */
#define VERSAL_NET_PRIMARY_CPU U(0)
-#define CORE_0_IEN_POWER_OFFSET (0x00000018U)
+#define CORE_0_ISR_WAKE_OFFSET (0x00000020ULL)
+#define APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id) (APU_PCLI + (CORE_0_ISR_WAKE_OFFSET + \
+ (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_WAKE_MASK (0x00000001U)
+#define CORE_0_IEN_WAKE_OFFSET (0x00000028ULL)
+#define APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id) (APU_PCLI + (CORE_0_IEN_WAKE_OFFSET + \
+ (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_WAKE_MASK (0x00000001U)
+#define CORE_0_IDS_WAKE_OFFSET (0x0000002CULL)
+#define APU_PCIL_CORE_X_IDS_WAKE_REG(cpu_id) (APU_PCLI + (CORE_0_IDS_WAKE_OFFSET + \
+ (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_WAKE_MASK (0x00000001U)
+#define CORE_0_ISR_POWER_OFFSET (0x00000010ULL)
+#define APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id) (APU_PCLI + (CORE_0_ISR_POWER_OFFSET + \
+ (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_POWER_MASK U(0x00000001)
+#define CORE_0_IEN_POWER_OFFSET (0x00000018ULL)
#define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id) (APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
- (0x30 * cpu_id)))
+ (APU_PCLI_CPU_STEP * (cpu_id))))
#define APU_PCIL_CORE_X_IEN_POWER_MASK (0x00000001U)
-#define CORE_0_IDS_POWER_OFFSET (0x0000001CU)
+#define CORE_0_IDS_POWER_OFFSET (0x0000001CULL)
#define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id) (APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
- (0x30 * cpu_id)))
+ (APU_PCLI_CPU_STEP * (cpu_id))))
#define APU_PCIL_CORE_X_IDS_POWER_MASK (0x00000001U)
#define CORE_PWRDN_EN_BIT_MASK (0x1U)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 8beaa9a..c713061 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -196,6 +196,7 @@
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
int32_t pstate = psci_get_pstate_type(power_state);
+ uint64_t i;
assert(req_state);
@@ -203,7 +204,8 @@
if (pstate == PSTATE_TYPE_STANDBY) {
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
} else {
- req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+ for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
}
/* We expect the 'state id' to be zero */
@@ -221,8 +223,10 @@
*/
static void versal_net_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
- req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
- req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
+ uint64_t i;
+
+ for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
}
static const struct plat_psci_ops versal_net_nopmc_psci_ops = {
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
index 6487324..f543193 100644
--- a/plat/xilinx/versal_net/pm_service/pm_client.c
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -164,8 +164,18 @@
isb();
+ /* Clear power down interrupt status before enabling */
+ mmio_write_32(APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id),
+ APU_PCIL_CORE_X_ISR_POWER_MASK);
+ /* Enable power down interrupt */
mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id),
APU_PCIL_CORE_X_IEN_POWER_MASK);
+ /* Clear wakeup interrupt status before enabling */
+ mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id),
+ APU_PCIL_CORE_X_ISR_WAKE_MASK);
+ /* Enable wake interrupt */
+ mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id),
+ APU_PCIL_CORE_X_IEN_WAKE_MASK);
bakery_lock_release(&pm_client_secure_lock);
}
@@ -197,6 +207,7 @@
void pm_client_wakeup(const struct pm_proc *proc)
{
uint32_t cpuid = pm_get_cpuid(proc->node_id);
+ uintptr_t val;
if (cpuid == UNDEFINED_CPUID) {
return;
@@ -204,7 +215,22 @@
bakery_lock_get(&pm_client_secure_lock);
- /* TODO: clear powerdown bit for affected cpu */
+ /* Clear powerdown request */
+ val = read_cpu_pwrctrl_val();
+ val &= ~CORE_PWRDN_EN_BIT_MASK;
+ write_cpu_pwrctrl_val(val);
+
+ isb();
+
+ /* Disabled power down interrupt */
+ mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpuid),
+ APU_PCIL_CORE_X_IDS_POWER_MASK);
+ /* Clear wakeup interrupt status before disabling */
+ mmio_write_32(APU_PCIL_CORE_X_ISR_WAKE_REG(cpuid),
+ APU_PCIL_CORE_X_ISR_WAKE_MASK);
+ /* Disable wake interrupt */
+ mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid),
+ APU_PCIL_CORE_X_IDS_WAKE_MASK);
bakery_lock_release(&pm_client_secure_lock);
}