From 07faf4d8c5823700bb2e87606ad365a26512c3cd Mon Sep 17 00:00:00 2001 From: Vignesh Radhakrishnan Date: Fri, 20 Apr 2018 14:31:41 -0700 Subject: [PATCH] Tegra: Enable irq as wake-up event for cpu_standby As per ARM ARM D1.17.2, any physical IRQ interrupt received by the PE will be treated as a wake-up event, if SCR_EL3.IRQ is set to '1', irrespective of the value of the PSTATE.I bit value. This patch programs the SCR_EL3.IRQ bit before entering CPU standby state, to allow an IRQ to wake the PE. On waking up, the previous SCR_EL3 value is restored. Change-Id: Ie81cf3a7668f5ac35f4bf2ecc461b91b9b60650c Signed-off-by: Vignesh Radhakrishnan --- plat/nvidia/tegra/common/tegra_pm.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index fbc0f1168..4275cf3f1 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -146,18 +146,37 @@ void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) ******************************************************************************/ void tegra_cpu_standby(plat_local_state_t cpu_state) { + u_register_t saved_scr_el3; + (void)cpu_state; /* Tegra SoC specific handler */ if (tegra_soc_cpu_standby(cpu_state) != PSCI_E_SUCCESS) ERROR("%s failed\n", __func__); + saved_scr_el3 = read_scr_el3(); + + /* + * As per ARM ARM D1.17.2, any physical IRQ interrupt received by the + * PE will be treated as a wake-up event, if SCR_EL3.IRQ is set to '1', + * irrespective of the value of the PSTATE.I bit value. + */ + write_scr_el3(saved_scr_el3 | SCR_IRQ_BIT); + /* * Enter standby state - * dsb is good practice before using wfi to enter low power states + * + * dsb & isb is good practice before using wfi to enter low power states */ dsb(); + isb(); wfi(); + + /* + * Restore saved scr_el3 that has IRQ bit cleared as we don't want EL3 + * handling any further interrupts + */ + write_scr_el3(saved_scr_el3); } /*******************************************************************************