Tegra: Enable irq as wake-up event for cpu_standby
authorVignesh Radhakrishnan <vigneshr@nvidia.com>
Fri, 20 Apr 2018 21:31:41 +0000 (14:31 -0700)
committerVarun Wadekar <vwadekar@nvidia.com>
Tue, 5 Feb 2019 16:27:43 +0000 (08:27 -0800)
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 <vigneshr@nvidia.com>
plat/nvidia/tegra/common/tegra_pm.c

index fbc0f11688e31bbf65796ae22c8d33b18f0ae1bc..4275cf3f12e85ad47499baaa53c89abab02bf8e6 100644 (file)
@@ -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);
 }
 
 /*******************************************************************************