summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-03-29 20:31:22 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-03-30 20:38:12 -0700
commit91684d5e33396caccd4b91791e41c0a240764830 (patch)
treee105f879a11bd380dd42405185ea83be59036d23
parent19bfaa46e5d11f57d219962b6968f2518147a371 (diff)
downloadchrome-ec-91684d5e33396caccd4b91791e41c0a240764830.tar.gz
Cr50: Add stubs to support low-power idle
This just adds the framework to use for implementing sleep and deep-sleep. This provides a custom idle task, and a new "idle" console command to control what that task should do (nothing, yet). BUG=chrome-os-partner:49955 BRANCH=none TEST=make buildall; test on Cr50 Other than the new idle command which does nothing, there is no visible change. This is just a stub. Change-Id: I8a9b82ca68dd6d1e3e7275f4f6753a23a7448f1d Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/336420 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--board/cr50/board.h2
-rw-r--r--chip/g/build.mk2
-rw-r--r--chip/g/idle.c77
3 files changed, 81 insertions, 0 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h
index 90635323ae..d7cface787 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -21,6 +21,8 @@
/* TODO(crosbug.com/p/44745): For debugging only */
#define CONFIG_CMD_FLASH
+/* Go to sleep when nothing else is happening */
+#define CONFIG_LOW_POWER_IDLE
/* USB configuration */
#define CONFIG_USB
diff --git a/chip/g/build.mk b/chip/g/build.mk
index 0d8ae631b2..d6df5d228c 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -48,6 +48,8 @@ chip-$(CONFIG_USB_CONSOLE)+=usb_console.o
chip-$(CONFIG_USB_HID)+=usb_hid.o
chip-$(CONFIG_USB_BLOB)+=usb_blob.o
+chip-$(CONFIG_LOW_POWER_IDLE)+=idle.o
+
chip-$(CONFIG_FLASH)+=flash.o
dirs-y += chip/g/dcrypto
diff --git a/chip/g/idle.c b/chip/g/idle.c
new file mode 100644
index 0000000000..fc955e0b30
--- /dev/null
+++ b/chip/g/idle.c
@@ -0,0 +1,77 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "util.h"
+
+/* This function is assumed to exist, but we don't use it */
+void clock_refresh_console_in_use(void)
+{
+}
+
+/* What to do when we're just waiting */
+static enum {
+ IDLE_WFI, /* default */
+ IDLE_SLEEP,
+ IDLE_DEEP_SLEEP,
+ NUM_CHOICES
+} idle_action;
+
+static const char const *idle_name[] = {
+ "wfi",
+ "sleep",
+ "deep sleep",
+};
+BUILD_ASSERT(ARRAY_SIZE(idle_name) == NUM_CHOICES);
+
+static int command_idle(int argc, char **argv)
+{
+ int c, i;
+
+ if (argc > 1) {
+ c = tolower(argv[1][0]);
+ for (i = 0; i < ARRAY_SIZE(idle_name); i++)
+ if (idle_name[i][0] == c) {
+ idle_action = i;
+ break;
+ }
+ }
+
+ ccprintf("idle action: %s\n", idle_name[idle_action]);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(idle, command_idle,
+ "[w|s|d]",
+ "Set or show the idle action: wfi, sleep, deep sleep",
+ NULL);
+
+/* Custom idle task, executed when no tasks are ready to be scheduled. */
+void __idle(void)
+{
+ while (1) {
+
+ /* Don't even bother unless we've enabled it */
+ if (idle_action == IDLE_WFI)
+ goto wfi;
+
+ /* TODO(wfrichar): sleep/deep-sleep stuff goes here... */
+
+wfi:
+ /* Wait for the next irq event. This stops the CPU clock and
+ * may trigger sleep or deep sleep if enabled. */
+ asm("wfi");
+
+ /*
+ * TODO: Normal sleep resumes by handling the interrupt, but we
+ * need to clear PMU_LOW_POWER_DIS right away or we might sleep
+ * again by accident. We can't do that here because we don't
+ * get here until the next idle, so we'll have to do it in the
+ * interrupt handler or when task switching. Deep sleep resumes
+ * with a warm boot, which handles it differently.
+ */
+ }
+}