summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-06-24 14:52:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-06-25 02:29:10 -0700
commit9a644c429af9f299445962892666685233cb0a1b (patch)
tree43210d5a992b2bff167afc207d323bd25d902c6e
parent264bca7e40cccd6f8576f69a6af32bd5bd0c1bfc (diff)
downloadchrome-ec-9a644c429af9f299445962892666685233cb0a1b.tar.gz
Cr50: Set the default idle action to Sleep
When the Cr50 doesn't have anything else to do and it's been a while since anyone has communicated with it (10 seconds via UART, 1 second via SPI, and the USB bus has stopped sending SOF packets), it enters one of three idle states: wfi = fully powered, just waiting for an interrupt. sleep = low power mode, but RAM is preserved. It resumes quickly. deep sleep = hibernate. RAM is lost, resume is a warm boot You can get/set the idle state with the "idle" console command. BUG=chrome-os-partner:49955,chrome-os-partner:54331 BRANCH=none TEST=make buildall To test it: * I've only tested on the debug board, because I need a serial console (not serial-over-USB) to see if it's asleep or not. * I haven't been able to knowingly force USB Suspend on my workstation, so to fake it I just unplug the USB cables. * Wait 10-12 seconds after typing anything on the serial console, then press a key. If the Cr50 was asleep, the first character will be lost. If it wasn't, you'll see the character echoed immediately. Change-Id: Icc213e50b0c38f8c2b16bcd9960e2e5550b43180 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/356123 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--chip/g/idle.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/chip/g/idle.c b/chip/g/idle.c
index dc003d3eef..1686474ba9 100644
--- a/chip/g/idle.c
+++ b/chip/g/idle.c
@@ -12,13 +12,17 @@
/* What to do when we're just waiting */
static enum {
- IDLE_WFI, /* default */
+ DONT_KNOW,
+ IDLE_WFI,
IDLE_SLEEP,
IDLE_DEEP_SLEEP,
NUM_CHOICES
} idle_action;
+#define IDLE_DEFAULT IDLE_SLEEP
+
static const char const *idle_name[] = {
+ "invalid",
"wfi",
"sleep",
"deep sleep",
@@ -31,7 +35,7 @@ static int command_idle(int argc, char **argv)
if (argc > 1) {
c = tolower(argv[1][0]);
- for (i = 0; i < ARRAY_SIZE(idle_name); i++)
+ for (i = 1; i < ARRAY_SIZE(idle_name); i++)
if (idle_name[i][0] == c) {
idle_action = i;
break;
@@ -129,10 +133,17 @@ void __idle(void)
{
int sleep_ok, sleep_delay_passed;
- /* Preserved across soft reboots, but not hard */
+ /*
+ * This register is preserved across soft reboots, but not hard. It
+ * defaults to zero, which is how we can tell whether this is the
+ * preserved value or not. We only need to remember it because we might
+ * change it with the console command.
+ */
idle_action = GREG32(PMU, PWRDN_SCRATCH17);
- if (idle_action >= NUM_CHOICES)
- idle_action = IDLE_WFI;
+ if (idle_action == DONT_KNOW || idle_action >= NUM_CHOICES) {
+ idle_action = IDLE_DEFAULT;
+ GREG32(PMU, PWRDN_SCRATCH17) = idle_action;
+ }
while (1) {