summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortim <tim2.lin@ite.corp-partner.google.com>2021-04-14 14:19:12 +0800
committerCommit Bot <commit-bot@chromium.org>2021-08-30 15:47:16 +0000
commit01ca8a6f2ff363a8a370870c3c6e58d364212b20 (patch)
treeff2c92e09443538bd243bf40c8bc18dc15fb6af3
parentc14c0bbb15207670ef83270899312a93fda48383 (diff)
downloadchrome-ec-01ca8a6f2ff363a8a370870c3c6e58d364212b20.tar.gz
zephyr/drivers: it8xxx2: add cros_system driver
This system module provides hardware specific implementat. BUG=b:185202623 BRANCH=none TEST=console command: version 21-08-19 14:38:29.441 Chip: ite it81202 bx reset cause: watchdog reset -> pass reset-pin -> pass power-on -> pass sort reset: reboot [soft] [preserve] [ap-off] [wait-ext] [cancel] [ap-off-in-ro] [ro] -> pass Cq-Depend: chromium:3102366 Change-Id: I65861a5066a555b51eb26c52b0b1e90aa7999097 Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2835525 Commit-Queue: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--zephyr/drivers/cros_system/CMakeLists.txt1
-rw-r--r--zephyr/drivers/cros_system/Kconfig21
-rw-r--r--zephyr/drivers/cros_system/cros_system_it8xxx2.c171
3 files changed, 193 insertions, 0 deletions
diff --git a/zephyr/drivers/cros_system/CMakeLists.txt b/zephyr/drivers/cros_system/CMakeLists.txt
index 7898442202..733b8be450 100644
--- a/zephyr/drivers/cros_system/CMakeLists.txt
+++ b/zephyr/drivers/cros_system/CMakeLists.txt
@@ -2,4 +2,5 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_IT8XXX2 cros_system_it8xxx2.c)
zephyr_library_sources_ifdef(CONFIG_CROS_SYSTEM_NPCX cros_system_npcx.c)
diff --git a/zephyr/drivers/cros_system/Kconfig b/zephyr/drivers/cros_system/Kconfig
index 09d47ad7e7..c5d98b6081 100644
--- a/zephyr/drivers/cros_system/Kconfig
+++ b/zephyr/drivers/cros_system/Kconfig
@@ -24,3 +24,24 @@ config CROS_SYSTEM_NPCX_INIT_PRIORITY
higher priority than CONFIG_SYSTEM_PRE_INIT_PRIORITY.
endif # CROS_SYSTEM_NPCX
+
+config CROS_SYSTEM_IT8XXX2
+ bool "ITE IT8XXX2 cros system driver"
+ depends on SOC_FAMILY_RISCV_ITE
+ default y
+ help
+ This option enables the cros system driver for the it8xxx2 family of
+ processors.
+
+if CROS_SYSTEM_IT8XXX2
+
+config CROS_SYSTEM_IT8XXX2_INIT_PRIORITY
+ int "cros_system it8xxx2 initialization priority"
+ default 10
+ help
+ This sets the it8xxx2 cros_system driver initialization priority.
+ The cros_system driver provides access to the it8xxx2 reset cause
+ and must be higher priority than
+ CONFIG_PLATFORM_EC_SYSTEM_PRE_INIT_PRIORITY.
+
+endif # CROS_SYSTEM_IT8XXX2
diff --git a/zephyr/drivers/cros_system/cros_system_it8xxx2.c b/zephyr/drivers/cros_system/cros_system_it8xxx2.c
new file mode 100644
index 0000000000..922a88d826
--- /dev/null
+++ b/zephyr/drivers/cros_system/cros_system_it8xxx2.c
@@ -0,0 +1,171 @@
+/* Copyright 2021 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.
+ */
+
+#define DT_DRV_COMPAT ite_it8xxx2_gctrl
+
+#include <device.h>
+#include <drivers/cros_system.h>
+#include <logging/log.h>
+#include <soc.h>
+#include <soc/ite_it8xxx2/reg_def_cros.h>
+
+#include "system.h"
+
+LOG_MODULE_REGISTER(cros_system, LOG_LEVEL_ERR);
+
+#define GCTRL_IT8XXX2_REG_BASE \
+ ((struct gctrl_it8xxx2_regs *)DT_INST_REG_ADDR(0))
+
+#define WDT_IT8XXX2_REG_BASE \
+ ((struct wdt_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(twd0)))
+
+static const char *cros_system_it8xxx2_get_chip_vendor(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ return "ite";
+}
+
+static uint32_t system_get_chip_id(void)
+{
+ struct gctrl_it8xxx2_regs *const gctrl_base = GCTRL_IT8XXX2_REG_BASE;
+
+ return (gctrl_base->GCTRL_ECHIPID1 << 16) |
+ (gctrl_base->GCTRL_ECHIPID2 << 8) |
+ gctrl_base->GCTRL_ECHIPID3;
+}
+
+static uint8_t system_get_chip_version(void)
+{
+ struct gctrl_it8xxx2_regs *const gctrl_base = GCTRL_IT8XXX2_REG_BASE;
+
+ /* bit[3-0], chip version */
+ return gctrl_base->GCTRL_ECHIPVER & 0x0F;
+}
+
+static const char *cros_system_it8xxx2_get_chip_name(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ static char buf[8] = {'i', 't'};
+ uint32_t chip_id = system_get_chip_id();
+ int num = 4;
+
+ for (int n = 2; num >= 0; n++, num--)
+ snprintf(buf+n, (sizeof(buf)-n), "%x",
+ chip_id >> (num * 4) & 0xF);
+
+ return buf;
+}
+
+static const char *cros_system_it8xxx2_get_chip_revision(const struct device
+ *dev)
+{
+ ARG_UNUSED(dev);
+
+ static char buf[3];
+ uint8_t rev = system_get_chip_version();
+
+ snprintf(buf, sizeof(buf), "%1xx", rev+0xa);
+
+ return buf;
+}
+
+static int cros_system_it8xxx2_get_reset_cause(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+ struct gctrl_it8xxx2_regs *const gctrl_base = GCTRL_IT8XXX2_REG_BASE;
+ /* system reset flag */
+ uint32_t system_flags = chip_read_reset_flags();
+ int chip_reset_cause = 0;
+ uint8_t raw_reset_cause = gctrl_base->GCTRL_RSTS & IT8XXX2_GCTRL_LRS;
+ uint8_t raw_reset_cause2 = gctrl_base->GCTRL_SPCTRL4 &
+ (IT8XXX2_GCTRL_LRSIWR | IT8XXX2_GCTRL_LRSIPWRSWTR |
+ IT8XXX2_GCTRL_LRSIPGWR);
+
+ /* Clear reset cause. */
+ gctrl_base->GCTRL_RSTS |= IT8XXX2_GCTRL_LRS;
+ gctrl_base->GCTRL_SPCTRL4 |= (IT8XXX2_GCTRL_LRSIWR |
+ IT8XXX2_GCTRL_LRSIPWRSWTR | IT8XXX2_GCTRL_LRSIPGWR);
+
+ /* Determine if watchdog reset or power on reset. */
+ if (raw_reset_cause & IT8XXX2_GCTRL_IWDTR) {
+ system_flags |= EC_RESET_FLAG_WATCHDOG;
+ chip_reset_cause = WATCHDOG_RST;
+ } else if (raw_reset_cause < 2) {
+ system_flags |= EC_RESET_FLAG_POWER_ON;
+ chip_reset_cause = POWERUP;
+ }
+ /* Determine reset-pin reset. */
+ if (raw_reset_cause2 & IT8XXX2_GCTRL_LRSIWR) {
+ system_flags |= EC_RESET_FLAG_RESET_PIN;
+ chip_reset_cause = VCC1_RST_PIN;
+ }
+
+ /* watchdog module triggers these reset */
+ if (system_flags & (EC_RESET_FLAG_HARD | EC_RESET_FLAG_SOFT))
+ system_flags &= ~EC_RESET_FLAG_WATCHDOG;
+
+ /* Set the system reset flags. */
+ system_set_reset_flags(system_flags);
+
+ return chip_reset_cause;
+}
+
+static int cros_system_it8xxx2_init(const struct device *dev)
+{
+ ARG_UNUSED(dev);
+
+ return 0;
+}
+
+static int cros_system_it8xxx2_soc_reset(const struct device *dev)
+{
+ struct wdt_it8xxx2_regs *const wdt_base = WDT_IT8XXX2_REG_BASE;
+
+ /* Disable interrupts to avoid task swaps during reboot. */
+ interrupt_disable_all();
+
+ /*
+ * Writing invalid key to watchdog module triggers a soft or hardware
+ * reset. It depends on the setting of bit0 at ETWDUARTCR register.
+ */
+ wdt_base->ETWCFG |= IT8XXX2_WDT_EWDKEYEN;
+ wdt_base->EWDKEYR = 0x00;
+
+ /* Spin and wait for reboot */
+ while (1)
+ ;
+
+ /* Should never return */
+ return 0;
+}
+
+static int cros_system_it8xxx2_hibernate(const struct device *dev,
+ uint32_t seconds,
+ uint32_t microseconds)
+{
+ /* TODO: To implement the hibernate mode */
+
+ return 0;
+}
+
+static const struct cros_system_driver_api cros_system_driver_it8xxx2_api = {
+ .get_reset_cause = cros_system_it8xxx2_get_reset_cause,
+ .soc_reset = cros_system_it8xxx2_soc_reset,
+ .hibernate = cros_system_it8xxx2_hibernate,
+ .chip_vendor = cros_system_it8xxx2_get_chip_vendor,
+ .chip_name = cros_system_it8xxx2_get_chip_name,
+ .chip_revision = cros_system_it8xxx2_get_chip_revision,
+};
+
+#if CONFIG_CROS_SYSTEM_IT8XXX2_INIT_PRIORITY >= \
+ CONFIG_PLATFORM_EC_SYSTEM_PRE_INIT_PRIORITY
+#error "CROS_SYSTEM must initialize before the SYSTEM_PRE initialization"
+#endif
+DEVICE_DEFINE(cros_system_it8xxx2_0, "CROS_SYSTEM", cros_system_it8xxx2_init,
+ NULL, NULL, NULL, PRE_KERNEL_1,
+ CONFIG_CROS_SYSTEM_IT8XXX2_INIT_PRIORITY,
+ &cros_system_driver_it8xxx2_api);