summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMulin Chao <mlchao@nuvoton.com>2016-08-18 13:33:07 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-08-22 14:52:22 -0700
commit746eb2c600248504ad030bfba1fad6ae431c254e (patch)
tree3aac0ef660a2cf3af9017fea35df00bfcfe726de
parentd614eaf1bf1f22b8a4bec8139a94fafd3e3328b0 (diff)
downloadchrome-ec-746eb2c600248504ad030bfba1fad6ae431c254e.tar.gz
npcx: Apply deep idle bypass for hibernate
Although probability is small, we still have chance to encounter the same symptom which CPU's behavior is abnormal after wake-up from deep idle. Apply the same bypass in task.c but not enable interrupt to solve it. Modified sources: 1. system.c: Apply deep idle bypass for hibernate. BRANCH=none BUG=chrome-os-partner:34346 TEST=make buildall; test "hibernate"&"hibernate 10" on wheatley. Change-Id: Ib00b9932ac34414d6a177d60668664ab31284a79 Signed-off-by: Mulin Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/373300 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Amit Maoz <Amit.Maoz@nuvoton.com>
-rw-r--r--chip/npcx/system.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/chip/npcx/system.c b/chip/npcx/system.c
index ca20c7ae91..f9d4d1f584 100644
--- a/chip/npcx/system.c
+++ b/chip/npcx/system.c
@@ -255,6 +255,15 @@ void system_mpu_config(void)
void __keep __attribute__ ((section(".lowpower_ram")))
__enter_hibernate_in_lpram(void)
{
+ /*
+ * TODO (ML): Set stack pointer to upper 512B of Suspend RAM.
+ * Our bypass needs stack instructions but FW will turn off main ram
+ * later for better power consumption.
+ */
+ asm (
+ "ldr r0, =0x40001800\n"
+ "mov sp, r0\n"
+ );
/* Disable Code RAM first */
SET_BIT(NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_5), NPCX_PWDWN_CTL5_MRFSH_DIS);
@@ -262,8 +271,22 @@ __enter_hibernate_in_lpram(void)
/* Set deep idle mode*/
NPCX_PMCSR = 0x6;
+
/* Enter deep idle, wake-up by GPIOxx or RTC */
- asm("wfi");
+ /*
+ * TODO (ML): Although the probability is small, it still has chance
+ * to meet the same symptom that CPU's behavior is abnormal after
+ * wake-up from deep idle.
+ * Workaround: Apply the same bypass of idle but don't enable interrupt.
+ */
+ asm (
+ "push {r0-r5}\n" /* Save needed registers */
+ "ldr r0, =0x40001600\n" /* Set r0 to Suspend RAM addr */
+ "wfi\n" /* Wait for int to enter idle */
+ "ldm r0, {r0-r5}\n" /* Add a delay after WFI */
+ "pop {r0-r5}\n" /* Restore regs before enabling ints */
+ "isb\n" /* Flush the cpu pipeline */
+ );
/* RTC wake-up */
if (IS_BIT_SET(NPCX_WTC, NPCX_WTC_PTO))