summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Lin <tim2.lin@ite.corp-partner.google.com>2021-08-20 16:08:49 +0800
committerCommit Bot <commit-bot@chromium.org>2021-09-10 17:34:46 +0000
commitd32852ee9bbb890dd82e60c36b50a08631c683dd (patch)
tree9b96b94fe4f508d80bc09f6c9fe8999fb9214f5c
parent77c74fa5ed663478062f652559eb17e015363b6f (diff)
downloadchrome-ec-d32852ee9bbb890dd82e60c36b50a08631c683dd.tar.gz
zephyr: cros_system: add hibernate mode to IT8xxx2 chipset
Add hibernate function. EC can be waked-up by a specified seconds or GPIO interrupts from sleep mode. BUG=b:198305804 BRANCH=none TEST=zmake testall Cq-Depend: chromium:3093834 Change-Id: I55fbd18b916f343b198c8ba8e5dce1bd592261f6 Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3109273 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org> Commit-Queue: Keith Short <keithshort@chromium.org>
-rw-r--r--zephyr/drivers/cros_system/cros_system_it8xxx2.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/zephyr/drivers/cros_system/cros_system_it8xxx2.c b/zephyr/drivers/cros_system/cros_system_it8xxx2.c
index e058fa6980..5731dcf984 100644
--- a/zephyr/drivers/cros_system/cros_system_it8xxx2.c
+++ b/zephyr/drivers/cros_system/cros_system_it8xxx2.c
@@ -11,7 +11,9 @@
#include <soc.h>
#include <soc/ite_it8xxx2/reg_def_cros.h>
+#include "gpio.h"
#include "system.h"
+#include "util.h"
LOG_MODULE_REGISTER(cros_system, LOG_LEVEL_ERR);
@@ -133,7 +135,7 @@ static int cros_system_it8xxx2_soc_reset(const struct device *dev)
/* Disable interrupts to avoid task swaps during reboot. */
interrupt_disable_all();
- if (chip_reset_flags & EC_RESET_FLAG_HARD)
+ if (chip_reset_flags & (EC_RESET_FLAG_HARD | EC_RESET_FLAG_HIBERNATE))
gctrl_base->GCTRL_ETWDUARTCR |= IT8XXX2_GCTRL_ETWD_HW_RST_EN;
/*
@@ -155,7 +157,72 @@ static int cros_system_it8xxx2_hibernate(const struct device *dev,
uint32_t seconds,
uint32_t microseconds)
{
- /* TODO: To implement the hibernate mode */
+ struct wdt_it8xxx2_regs *const wdt_base = WDT_IT8XXX2_REG_BASE;
+
+ /* Disable all interrupts. */
+ interrupt_disable_all();
+
+ /* Save and disable interrupts */
+ if (IS_ENABLED(CONFIG_ITE_IT8XXX2_INTC))
+ ite_intc_save_and_disable_interrupts();
+
+ /* bit5: watchdog is disabled. */
+ wdt_base->ETWCTRL |= IT8XXX2_WDT_EWDSCEN;
+
+ /*
+ * Setup GPIOs for hibernate. On some boards, it's possible that this
+ * may not return at all. On those boards, power to the EC is likely
+ * being turn off entirely.
+ */
+ if (board_hibernate_late) {
+ /*
+ * Set reset flag in case board_hibernate_late() doesn't
+ * return.
+ */
+ chip_save_reset_flags(EC_RESET_FLAG_HIBERNATE);
+ board_hibernate_late();
+ }
+
+ if (seconds || microseconds) {
+ /*
+ * Convert milliseconds(or at least 1 ms) to 32 Hz
+ * free run timer count for hibernate.
+ */
+ uint32_t c = (seconds * 1000 + microseconds / 1000 + 1) *
+ 32 / 1000;
+
+ /* Enable a 32-bit timer and clock source is 32 Hz */
+ /* Disable external timer x */
+ IT8XXX2_EXT_CTRLX(FREE_RUN_TIMER) &= ~IT8XXX2_EXT_ETXEN;
+ irq_disable(FREE_RUN_TIMER_IRQ);
+ IT8XXX2_EXT_PSRX(FREE_RUN_TIMER) = EXT_PSR_32;
+ IT8XXX2_EXT_CNTX(FREE_RUN_TIMER) = c & FREE_RUN_TIMER_MAX_CNT;
+ /* Enable and re-start external timer x */
+ IT8XXX2_EXT_CTRLX(FREE_RUN_TIMER) |=
+ (IT8XXX2_EXT_ETXEN | IT8XXX2_EXT_ETXRST);
+ irq_enable(FREE_RUN_TIMER_IRQ);
+ }
+
+ static const int wakeup_pin_list[] = {
+#if DT_NODE_EXISTS(SYSTEM_DT_NODE_HIBERNATE_CONFIG)
+ UTIL_LISTIFY(SYSTEM_DT_NODE_WAKEUP_PIN_LEN,
+ SYSTEM_DT_WAKEUP_GPIO_ENUM_BY_IDX, _)
+#endif
+ };
+
+ /* Reconfigure wake-up GPIOs */
+ for (int i = 0; i < ARRAY_SIZE(wakeup_pin_list); i++)
+ /* Re-enable interrupt for wake-up inputs */
+ gpio_enable_interrupt(wakeup_pin_list[i]);
+
+ /* EC sleep mode */
+ chip_pll_ctrl(CHIP_PLL_SLEEP);
+
+ /* Chip sleep and wait timer wake it up */
+ __asm__ volatile ("wfi");
+
+ /* Reset EC when wake up from sleep mode (system hibernate) */
+ system_reset(SYSTEM_RESET_HIBERNATE);
return 0;
}