summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Marheine <pmarheine@chromium.org>2022-07-04 12:33:49 +1000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-07-29 00:41:54 +0000
commite616b66c76ddbdf03ed8d2179516c9c67cfc045a (patch)
tree90270512abb3355c7051bcfdda0f0b92eda2bcb1
parent0298bfc009cc659e0f8c2d92b7a121cbcede158e (diff)
downloadchrome-ec-e616b66c76ddbdf03ed8d2179516c9c67cfc045a.tar.gz
it8xxx2: disable eSPI inputs when in G3
eSPI CS# goes low when the AP is off, which prevents the EC from entering deep doze to save power. Disable the eSPI pad on G3 entry and re-enable before exiting G3 to enable EC power saving. This optimization is expected to be relevant to all boards that use eSPI to manage AP power with IT8xxx2, so the code is located such that it will be included for every board that has appropriate configuration. BUG=b:237717730 TEST=Nereid still boots from G3 and returns to G3 correctly; debug logs indicate eSPI pad control is running. BRANCH=none Signed-off-by: Peter Marheine <pmarheine@chromium.org> Change-Id: Ia2f245b0fc84cdddf28471a13a69e73b6188f932 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3742840 Reviewed-by: Andrew McRae <amcrae@google.com> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--zephyr/app/ec/CMakeLists.txt2
-rw-r--r--zephyr/app/ec/chip/CMakeLists.txt1
-rw-r--r--zephyr/app/ec/chip/riscv/CMakeLists.txt1
-rw-r--r--zephyr/app/ec/chip/riscv/riscv-ite/CMakeLists.txt3
-rw-r--r--zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c63
5 files changed, 70 insertions, 0 deletions
diff --git a/zephyr/app/ec/CMakeLists.txt b/zephyr/app/ec/CMakeLists.txt
index fc7205462d..6ddac15080 100644
--- a/zephyr/app/ec/CMakeLists.txt
+++ b/zephyr/app/ec/CMakeLists.txt
@@ -7,3 +7,5 @@ zephyr_library_sources(ec_app_main.c)
if(NOT DEFINED CONFIG_ZTEST)
zephyr_library_sources(main_shim.c)
endif()
+
+add_subdirectory(chip) \ No newline at end of file
diff --git a/zephyr/app/ec/chip/CMakeLists.txt b/zephyr/app/ec/chip/CMakeLists.txt
new file mode 100644
index 0000000000..e92dbc5d5d
--- /dev/null
+++ b/zephyr/app/ec/chip/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory_ifdef(CONFIG_RISCV riscv) \ No newline at end of file
diff --git a/zephyr/app/ec/chip/riscv/CMakeLists.txt b/zephyr/app/ec/chip/riscv/CMakeLists.txt
new file mode 100644
index 0000000000..b11c4e9a90
--- /dev/null
+++ b/zephyr/app/ec/chip/riscv/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory_ifdef(CONFIG_SOC_FAMILY_RISCV_ITE riscv-ite) \ No newline at end of file
diff --git a/zephyr/app/ec/chip/riscv/riscv-ite/CMakeLists.txt b/zephyr/app/ec/chip/riscv/riscv-ite/CMakeLists.txt
new file mode 100644
index 0000000000..69608c33e3
--- /dev/null
+++ b/zephyr/app/ec/chip/riscv/riscv-ite/CMakeLists.txt
@@ -0,0 +1,3 @@
+if (CONFIG_ESPI_IT8XXX2)
+ zephyr_library_sources_ifdef(CONFIG_AP_POWER_CONTROL it8xxx2-espi.c)
+endif () \ No newline at end of file
diff --git a/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c b/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c
new file mode 100644
index 0000000000..81d96c4328
--- /dev/null
+++ b/zephyr/app/ec/chip/riscv/riscv-ite/it8xxx2-espi.c
@@ -0,0 +1,63 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <soc_espi.h>
+#include <ap_power/ap_power.h>
+#include <chipset.h>
+#include <devicetree.h>
+#include <logging/log.h>
+
+LOG_MODULE_REGISTER(ec_chip_it8xxx2_espi, CONFIG_ESPI_LOG_LEVEL);
+
+/*
+ * When eSPI CS# is held low, it prevents IT8xxx2 from entering deep doze.
+ * To allow deep doze and save power, disable the eSPI inputs while the AP is
+ * in G3.
+ */
+static const struct device *const espi_device =
+ DEVICE_DT_GET(DT_NODELABEL(espi0));
+
+static void espi_enable_callback(struct ap_power_ev_callback *cb,
+ struct ap_power_ev_data data)
+{
+ switch (data.event) {
+ case AP_POWER_INITIALIZED:
+ /* When AP power state becomes known, sync eSPI enable */
+ if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) {
+ LOG_DBG("AP off; disabling eSPI");
+ espi_it8xxx2_enable_pad_ctrl(espi_device, false);
+ }
+ break;
+ case AP_POWER_PRE_INIT:
+ case AP_POWER_HARD_OFF: {
+ bool enable = data.event == AP_POWER_PRE_INIT;
+
+ LOG_DBG("%sabling eSPI in response to AP power event",
+ enable ? "en" : "dis");
+ espi_it8xxx2_enable_pad_ctrl(espi_device, enable);
+ break;
+ }
+ default:
+ __ASSERT(false, "%s: unhandled event: %d", __func__,
+ data.event);
+ break;
+ }
+}
+
+static int init_espi_enable_callback(const struct device *unused)
+{
+ static struct ap_power_ev_callback cb;
+
+ if (!device_is_ready(espi_device))
+ k_oops();
+
+ ap_power_ev_init_callback(&cb, espi_enable_callback,
+ AP_POWER_INITIALIZED | AP_POWER_PRE_INIT |
+ AP_POWER_HARD_OFF);
+ ap_power_ev_add_callback(&cb);
+
+ return 0;
+}
+/* Should run before power sequencing init so INITIALIZED callback can fire */
+SYS_INIT(init_espi_enable_callback, APPLICATION, 0);