summaryrefslogtreecommitdiff
path: root/zephyr/drivers/cros_system
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/drivers/cros_system')
-rw-r--r--zephyr/drivers/cros_system/CMakeLists.txt6
-rw-r--r--zephyr/drivers/cros_system/Kconfig47
-rw-r--r--zephyr/drivers/cros_system/cros_system_it8xxx2.c246
-rw-r--r--zephyr/drivers/cros_system/cros_system_npcx.c556
4 files changed, 0 insertions, 855 deletions
diff --git a/zephyr/drivers/cros_system/CMakeLists.txt b/zephyr/drivers/cros_system/CMakeLists.txt
deleted file mode 100644
index 733b8be450..0000000000
--- a/zephyr/drivers/cros_system/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# 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.
-
-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
deleted file mode 100644
index c5d98b6081..0000000000
--- a/zephyr/drivers/cros_system/Kconfig
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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.
-
-menuconfig CROS_SYSTEM_NPCX
- bool "Nuvoton NPCX cros system driver"
- depends on SOC_FAMILY_NPCX
- default y
- help
- This option enables the cros system driver for the NPCX family of
- processors. Currently, Zephyr doesn't provide the system related API.
- The cros system driver provides the low-level driver related to
- chromium ec system functionality.
-
-if CROS_SYSTEM_NPCX
-
-config CROS_SYSTEM_NPCX_INIT_PRIORITY
- int "cros_system npcx initialization priority"
- default 10
- range 10 19
- help
- This sets the npcx cros_system driver initialization priority. The
- cros_system driver provides access to the NPCX reset cause and must be
- 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
deleted file mode 100644
index 5731dcf984..0000000000
--- a/zephyr/drivers/cros_system/cros_system_it8xxx2.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* 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 "gpio.h"
-#include "system.h"
-#include "util.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)
-{
- struct gctrl_it8xxx2_regs *const gctrl_base = GCTRL_IT8XXX2_REG_BASE;
-
- /* System triggers a soft reset by default (command: reboot). */
- gctrl_base->GCTRL_ETWDUARTCR &= ~IT8XXX2_GCTRL_ETWD_HW_RST_EN;
-
- return 0;
-}
-
-static int cros_system_it8xxx2_soc_reset(const struct device *dev)
-{
- struct gctrl_it8xxx2_regs *const gctrl_base = GCTRL_IT8XXX2_REG_BASE;
- struct wdt_it8xxx2_regs *const wdt_base = WDT_IT8XXX2_REG_BASE;
- uint32_t chip_reset_flags = chip_read_reset_flags();
-
- /* Disable interrupts to avoid task swaps during reboot. */
- interrupt_disable_all();
-
- if (chip_reset_flags & (EC_RESET_FLAG_HARD | EC_RESET_FLAG_HIBERNATE))
- gctrl_base->GCTRL_ETWDUARTCR |= IT8XXX2_GCTRL_ETWD_HW_RST_EN;
-
- /*
- * 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)
-{
- 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;
-}
-
-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);
diff --git a/zephyr/drivers/cros_system/cros_system_npcx.c b/zephyr/drivers/cros_system/cros_system_npcx.c
deleted file mode 100644
index e3d3bc29b2..0000000000
--- a/zephyr/drivers/cros_system/cros_system_npcx.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/* 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.
- */
-
-#include <arch/arm/aarch32/cortex_m/cmsis.h>
-#include <drivers/cros_system.h>
-#include <drivers/gpio.h>
-#include <drivers/watchdog.h>
-#include <logging/log.h>
-#include <soc.h>
-#include <soc/nuvoton_npcx/reg_def_cros.h>
-#include <sys/util.h>
-
-#include "gpio.h"
-#include "rom_chip.h"
-#include "soc_gpio.h"
-#include "soc_miwu.h"
-#include "system.h"
-
-LOG_MODULE_REGISTER(cros_system, LOG_LEVEL_ERR);
-
-/* Driver config */
-struct cros_system_npcx_config {
- /* hardware module base address */
- uintptr_t base_scfg;
- uintptr_t base_twd;
- uintptr_t base_mswc;
-};
-
-/* Driver data */
-struct cros_system_npcx_data {
- int reset; /* reset cause */
-};
-
-/* Driver convenience defines */
-#define DRV_CONFIG(dev) ((const struct cros_system_npcx_config *)(dev)->config)
-
-#define HAL_SCFG_INST(dev) (struct scfg_reg *)(DRV_CONFIG(dev)->base_scfg)
-#define HAL_TWD_INST(dev) (struct twd_reg *)(DRV_CONFIG(dev)->base_twd)
-#define HAL_MSWC_INST(dev) (struct mswc_reg *)(DRV_CONFIG(dev)->base_mswc)
-
-#define DRV_DATA(dev) ((struct cros_system_npcx_data *)(dev)->data)
-
-#define SYSTEM_DT_NODE_SOC_ID_CONFIG DT_INST(0, nuvoton_npcx_soc_id)
-
-/* Chip info devicetree data */
-#define NPCX_FAMILY_ID DT_PROP(SYSTEM_DT_NODE_SOC_ID_CONFIG, family_id)
-
-#define NPCX_CHIP_ID DT_PROP(SYSTEM_DT_NODE_SOC_ID_CONFIG, chip_id)
-
-#define NPCX_DEVICE_ID DT_PROP(SYSTEM_DT_NODE_SOC_ID_CONFIG, device_id)
-
-#define NPCX_REVISION_ADDR \
- DT_PROP_BY_IDX(SYSTEM_DT_NODE_SOC_ID_CONFIG, revision_reg, 0)
-#define NPCX_REVISION_LEN \
- DT_PROP_BY_IDX(SYSTEM_DT_NODE_SOC_ID_CONFIG, revision_reg, 1)
-
-/* RAM block size in npcx family (Unit: bytes) */
-#define NPCX_RAM_BLOCK_SIZE (32 * 1024)
-/* RAM block number in npcx7 series */
-
-/* Calculate the number of RAM blocks:
- * total RAM size = code ram + data ram + extra 2K for ROM functions
- * divided by the block size 32k.
- */
-#define DATA_RAM_SIZE DT_REG_SIZE(DT_NODELABEL(sram0))
-#define CODE_RAM_SIZE DT_REG_SIZE(DT_NODELABEL(flash0))
-#define NPCX_RAM_BLOCK_COUNT \
- ((DATA_RAM_SIZE + CODE_RAM_SIZE + KB(2)) / NPCX_RAM_BLOCK_SIZE)
-
-/* Valid bit-depth of RAM block Power-Down control (RAM_PD) registers. Use its
- * mask to power down all unnecessary RAM blocks before hibernating.
- */
-#define NPCX_RAM_PD_DEPTH DT_PROP(DT_NODELABEL(pcc), ram_pd_depth)
-#define NPCX_RAM_BLOCK_PD_MASK (BIT(NPCX_RAM_PD_DEPTH) - 1)
-
-/* Get saved reset flag address in battery-backed ram */
-#define BBRAM_SAVED_RESET_FLAG_ADDR \
- (DT_REG_ADDR(DT_INST(0, nuvoton_npcx_bbram)) + \
- DT_PROP(DT_PATH(named_bbram_regions, saved_reset_flags), offset))
-
-/* Soc specific system local functions */
-static int system_npcx_watchdog_stop(void)
-{
- if (IS_ENABLED(CONFIG_WATCHDOG)) {
- const struct device *wdt_dev = DEVICE_DT_GET(
- DT_NODELABEL(twd0));
- if (!device_is_ready(wdt_dev)) {
- LOG_ERR("Error: device %s is not ready", wdt_dev->name);
- return -ENODEV;
- }
-
- wdt_disable(wdt_dev);
- }
-
- return 0;
-}
-
-static void system_npcx_set_flash_pins_tri_state(const struct device *dev)
-{
- struct scfg_reg *const inst_scfg = HAL_SCFG_INST(dev);
-
- inst_scfg->DEVCNT |= BIT(NPCX_DEVCNT_F_SPI_TRIS);
-}
-
-static void system_npcx_init_watchdog_reset(const struct device *dev)
-{
- struct twd_reg *const inst_twd = HAL_TWD_INST(dev);
-
- /* Enable early touch */
- inst_twd->T0CSR &= ~BIT(NPCX_T0CSR_TESDIS);
- /* watchdog touched by writing 5Ch to WDSDM */
- inst_twd->TWCFG |= BIT(NPCX_TWCFG_WDSDME);
-}
-
-static void system_npcx_turn_off_adc(void)
-{
- struct adc_reg *const inst_adc =
- (struct adc_reg *)(DT_REG_ADDR(DT_INST(0, nuvoton_npcx_adc)));
-
- inst_adc->ADCCNF = 0;
- /* Wait for 1000 us to make sure conversion is completed. */
- k_busy_wait(1000);
-}
-
-static void system_npcx_turn_off_kernel_timer(void)
-{
- static struct itim32_reg *const evt_tmr =
- (struct itim32_reg *)DT_REG_ADDR_BY_NAME(
- DT_INST(0, nuvoton_npcx_itim_timer), evt_itim);
-
- evt_tmr->ITCTS32 &= ~BIT(NPCX_ITCTSXX_ITEN);
-}
-
-static void system_npcx_disable_instant_wakeup(void)
-{
- struct pmc_reg *const inst_pmc = (struct pmc_reg *)(DT_REG_ADDR_BY_NAME(
- DT_INST(0, nuvoton_npcx_pcc), pmc));
-
- inst_pmc->ENIDL_CTL &= ~BIT(NPCX_ENIDL_CTL_LP_WK_CTL);
-}
-
-static void system_npcx_set_wakeup_gpios_before_hibernate(void)
-{
- const uintptr_t miwu_base[] = {
- DT_REG_ADDR(DT_INST(0, nuvoton_npcx_miwu)),
- DT_REG_ADDR(DT_INST(1, nuvoton_npcx_miwu)),
- DT_REG_ADDR(DT_INST(2, nuvoton_npcx_miwu)),
- };
-
- /* Disable all MIWU inputs before entering hibernate */
- for (int table = 0; table < ARRAY_SIZE(miwu_base); table++) {
- for (int group = 0; group < NPCX_MIWU_GROUP_COUNT; group++) {
- /* Disable all wake-ups */
- NPCX_WKEN(miwu_base[table], group) = 0x00;
- /* Clear all pending bits of wake-ups */
- NPCX_WKPCL(miwu_base[table], group) = 0xFF;
- /*
- * Disable all inputs of wake-ups to prevent leakage
- * caused by input floating.
- */
- NPCX_WKINEN(miwu_base[table], group) = 0x00;
- }
- }
-
- 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++) {
- gpio_reset(wakeup_pin_list[i]);
- /* Re-enable interrupt for wake-up inputs */
- gpio_enable_interrupt(wakeup_pin_list[i]);
- }
-}
-
-/*
- * Hibernate function locates in the last 32K ram block in npcx7 series.
- * Do not use global variables or call functions since we have turned off
- * the other ram blocks.
- */
-noreturn void __keep __attribute__((section(".lfw.hiber")))
-system_npcx_hibernate_by_lfw_in_last_ram(const struct device *dev,
- uint32_t pd_ram_mask)
-{
- /* Modules used for hibernating */
- struct twd_reg *const inst_twd = HAL_TWD_INST(dev);
- struct mtc_reg *const inst_mtc = (struct mtc_reg *)(DT_REG_ADDR(
- DT_INST(0, nuvoton_npcx_cros_mtc)));
- struct pmc_reg *const inst_pmc = (struct pmc_reg *)(DT_REG_ADDR_BY_NAME(
- DT_INST(0, nuvoton_npcx_pcc), pmc));
- uint32_t reset_flags;
- volatile uint8_t *saved_reset_flags =
- (volatile uint8_t *)BBRAM_SAVED_RESET_FLAG_ADDR;
-
- /* Turn off all blocks except last one for better power consumption */
- inst_pmc->RAM_PD[0] = (uint8_t)pd_ram_mask;
- inst_pmc->RAM_PD[1] = (uint8_t)(pd_ram_mask >> 8);
-
- /* Set deep idle mode */
- inst_pmc->PMCSR = BIT(NPCX_PMCSR_IDLE) | BIT(NPCX_PMCSR_DHF);
-
- /* Enter system sleep mode */
- __asm__ volatile("wfi");
-
- /*
- * Mark wake-up reason for hibernate. Do not call bbram utilities
- * directly since the other ram blocks are power down.
- */
- if (IS_BIT_SET(inst_mtc->WTC, NPCX_WTC_PTO)) {
- /* Save wake-up reason as RTC alarm. */
- reset_flags = EC_RESET_FLAG_RTC_ALARM;
- } else {
- /* Otherwise, we treat it as GPIOs wake-up */
- reset_flags = EC_RESET_FLAG_WAKE_PIN;
- }
-
- saved_reset_flags[0] |= reset_flags;
- saved_reset_flags[1] |= reset_flags >> 8;
- saved_reset_flags[2] |= reset_flags >> 16;
- saved_reset_flags[3] |= reset_flags >> 24;
-
- /*
- * The trigger of a watchdog event by a "too early service" condition.
- * When the watchdog is written more than once during three watchdog
- * clock cycle.
- */
- inst_twd->WDSDM = 0x5C;
- inst_twd->WDSDM = 0x5C;
-
- /* Spin and wait for reboot; should never return */
- while (1)
- continue;
-}
-
-static inline int system_npcx_get_ram_blk_by_lfw_addr(char *address)
-{
- return NPCX_RAM_BLOCK_COUNT -
- ceiling_fraction((uint32_t)address -
- CONFIG_CROS_EC_PROGRAM_MEMORY_BASE,
- NPCX_RAM_BLOCK_SIZE);
-}
-
-static void system_npcx_hibernate_by_disable_ram(const struct device *dev,
- uint32_t seconds,
- uint32_t microseconds)
-{
- /* Get 32kb ram block order of lfw function */
- extern char __lfw_text_start[], __lfw_text_end[];
- int lfw_block = system_npcx_get_ram_blk_by_lfw_addr(__lfw_text_start);
- uint32_t pd_ram_mask = ~BIT(lfw_block) & NPCX_RAM_BLOCK_PD_MASK;
-
- if (lfw_block != system_npcx_get_ram_blk_by_lfw_addr(__lfw_text_end)) {
- LOG_ERR("LFW cannot cross ram blocks!");
- return;
- }
-
- /*
- * Set status of pins which connect to flash to tri-state in case
- * the leakage current.
- */
- system_npcx_set_flash_pins_tri_state(dev);
-
- /* Initialize watchdog for reset after wake-up from hibernating */
- system_npcx_init_watchdog_reset(dev);
-
- /* Disable ADC and wait for 1000 us to make sure conversion is done */
- if (IS_ENABLED(CONFIG_ADC))
- system_npcx_turn_off_adc();
-
- /* Disable kernel timer */
- system_npcx_turn_off_kernel_timer();
-
- /* Disable instant wake up mode for better power consumption */
- system_npcx_disable_instant_wakeup();
-
- /*
- * Set wake-up input GPIOs and turn off the other sources for better
- * power consumption before entering hibernate mode.
- */
- system_npcx_set_wakeup_gpios_before_hibernate();
-
- /*
- * Give the board a chance to do any late stage hibernation work. This
- * is likely going to configure GPIOs for hibernation. 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) {
- board_hibernate_late();
- }
-
- /* Setup a RTC alarm if needed */
- if (IS_ENABLED(CONFIG_RTC) && (seconds || microseconds)) {
- system_set_rtc_alarm(seconds, microseconds);
- }
-
- /* Clear all pending IRQs in case wake-up immediately after sleeping */
- for (int i = 0; i < CONFIG_NUM_IRQS; i++) {
- NVIC_ClearPendingIRQ(i);
- }
-
- /* Execute hibernate by lfw which locates in last 32K block ram */
- system_npcx_hibernate_by_lfw_in_last_ram(dev, pd_ram_mask);
-}
-
-static const char *cros_system_npcx_get_chip_vendor(const struct device *dev)
-{
- struct mswc_reg *const inst_mswc = HAL_MSWC_INST(dev);
- static char str[11] = "Unknown-XX";
- char *p = str + 8;
- uint8_t fam_id = inst_mswc->SID_CR;
-
-#if DT_NODE_EXISTS(SYSTEM_DT_NODE_SOC_ID_CONFIG)
- if (fam_id == NPCX_FAMILY_ID) {
- return "Nuvoton";
- }
-#endif
-
- hex2char(fam_id >> 4, p++);
- hex2char(fam_id & 0xf, p);
- return str;
-}
-
-static const char *cros_system_npcx_get_chip_name(const struct device *dev)
-{
- struct mswc_reg *const inst_mswc = HAL_MSWC_INST(dev);
- static char str[13] = "Unknown-XXXX";
- char *p = str + 8;
- uint8_t chip_id = inst_mswc->SRID_CR;
- uint8_t device_id = inst_mswc->DEVICE_ID_CR;
-
-#if DT_NODE_EXISTS(SYSTEM_DT_NODE_SOC_ID_CONFIG)
- if (chip_id == NPCX_CHIP_ID && device_id == NPCX_DEVICE_ID) {
- return CONFIG_SOC;
- }
-#endif
-
- hex2char(chip_id >> 4, p++);
- hex2char(chip_id & 0xf, p++);
- hex2char(device_id >> 4, p++);
- hex2char(device_id & 0xf, p);
- return str;
-}
-
-static const char *cros_system_npcx_get_chip_revision(const struct device *dev)
-{
- ARG_UNUSED(dev);
-#if DT_NODE_EXISTS(SYSTEM_DT_NODE_SOC_ID_CONFIG)
- static char rev[NPCX_REVISION_LEN * 2 + 1];
-#else
- static char rev[1];
-#endif
- char *p = rev;
-
-#if DT_NODE_EXISTS(SYSTEM_DT_NODE_SOC_ID_CONFIG)
- /*
- * For NPCX7, the revision number is 1 byte.
- * For NPCX9 and later chips, the revision number is 4 bytes.
- */
- for (int s = NPCX_REVISION_ADDR + NPCX_REVISION_LEN - 1;
- s >= NPCX_REVISION_ADDR; s--) {
- uint8_t r = *((volatile uint8_t *)s);
- hex2char(r >> 4, p++);
- hex2char(r & 0xf, p++);
- }
-#endif
- *p = '\0';
-
- return rev;
-}
-
-static void system_npcx_hibernate_by_psl(const struct device *dev,
- uint32_t seconds,
- uint32_t microseconds)
-{
- ARG_UNUSED(dev);
- /*
- * TODO(b/178230662): RTC wake-up in PSL mode only support in npcx9
- * series. Nuvoton will introduce CLs for it later.
- */
- ARG_UNUSED(seconds);
- ARG_UNUSED(microseconds);
-
- /*
- * Configure PSL input pads from "psl-in-pads" property in device tree
- * file.
- */
- npcx_pinctrl_psl_input_configure();
-
- /*
- * Give the board a chance to do any late stage hibernation work. This
- * is likely going to configure GPIOs for hibernation. 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)
- board_hibernate_late();
-
- /* Turn off VCC1 to enter ultra-low-power mode for hibernating */
- npcx_pinctrl_psl_output_set_inactive();
-}
-
-static int cros_system_npcx_get_reset_cause(const struct device *dev)
-{
- struct cros_system_npcx_data *data = DRV_DATA(dev);
-
- return data->reset;
-}
-
-static int cros_system_npcx_init(const struct device *dev)
-{
- struct scfg_reg *const inst_scfg = HAL_SCFG_INST(dev);
- struct twd_reg *const inst_twd = HAL_TWD_INST(dev);
- struct cros_system_npcx_data *data = DRV_DATA(dev);
-
- /* check reset cause */
- if (IS_BIT_SET(inst_twd->T0CSR, NPCX_T0CSR_WDRST_STS)) {
- data->reset = WATCHDOG_RST;
- inst_twd->T0CSR |= BIT(NPCX_T0CSR_WDRST_STS);
- } else if (IS_BIT_SET(inst_scfg->RSTCTL, NPCX_RSTCTL_DBGRST_STS)) {
- data->reset = DEBUG_RST;
- inst_scfg->RSTCTL |= BIT(NPCX_RSTCTL_DBGRST_STS);
- } else if (IS_BIT_SET(inst_scfg->RSTCTL, NPCX_RSTCTL_VCC1_RST_STS)) {
- data->reset = VCC1_RST_PIN;
- } else {
- data->reset = POWERUP;
- }
-
- return 0;
-}
-
-static int cros_system_npcx_soc_reset(const struct device *dev)
-{
- struct twd_reg *const inst_twd = HAL_TWD_INST(dev);
-
- /* Disable interrupts to avoid task swaps during reboot */
- interrupt_disable_all();
-
- /*
- * NPCX chip doesn't have the specific system reset functionality. Use
- * watchdog reset as a system reset.
- */
-
- /* Stop the watchdog */
- system_npcx_watchdog_stop();
-
- /* Initialize watchdog for reset */
- system_npcx_init_watchdog_reset(dev);
-
- /*
- * The trigger of a watchdog event by a "too early service" condition.
- * When the watchdog is written more than once during three watchdog
- * clock cycle.
- */
- inst_twd->WDSDM = 0x5C;
- inst_twd->WDSDM = 0x5C;
-
- /* Wait for the soc reset. */
- while (1) {
- ;
- }
-
- /* should never return */
- return 0;
-}
-
-static int cros_system_npcx_hibernate(const struct device *dev,
- uint32_t seconds, uint32_t microseconds)
-{
- /* Disable interrupt first */
- interrupt_disable_all();
-
- /* Stop the watchdog */
- system_npcx_watchdog_stop();
-
- /* Enter hibernate mode */
- if (IS_ENABLED(CONFIG_PLATFORM_EC_HIBERNATE_PSL)) {
- system_npcx_hibernate_by_psl(dev, seconds, microseconds);
- } else {
- system_npcx_hibernate_by_disable_ram(dev, seconds,
- microseconds);
- }
-
- return 0;
-}
-
-__maybe_unused static uint64_t
-cros_system_npcx_deep_sleep_ticks(const struct device *dev)
-{
- return npcx_clock_get_sleep_ticks();
-}
-
-static struct cros_system_npcx_data cros_system_npcx_dev_data;
-
-static const struct cros_system_npcx_config cros_system_dev_cfg = {
- .base_scfg = DT_REG_ADDR(DT_INST(0, nuvoton_npcx_scfg)),
- .base_twd = DT_REG_ADDR(DT_INST(0, nuvoton_npcx_watchdog)),
- .base_mswc =
- DT_REG_ADDR_BY_NAME(DT_INST(0, nuvoton_npcx_host_sub), mswc),
-};
-
-static const struct cros_system_driver_api cros_system_driver_npcx_api = {
- .get_reset_cause = cros_system_npcx_get_reset_cause,
- .soc_reset = cros_system_npcx_soc_reset,
- .hibernate = cros_system_npcx_hibernate,
- .chip_vendor = cros_system_npcx_get_chip_vendor,
- .chip_name = cros_system_npcx_get_chip_name,
- .chip_revision = cros_system_npcx_get_chip_revision,
-#ifdef CONFIG_SOC_POWER_MANAGEMENT_TRACE
- .deep_sleep_ticks = cros_system_npcx_deep_sleep_ticks,
-#endif
-};
-
-DEVICE_DEFINE(cros_system_npcx_0, "CROS_SYSTEM", cros_system_npcx_init, NULL,
- &cros_system_npcx_dev_data, &cros_system_dev_cfg, PRE_KERNEL_1,
- CONFIG_CROS_SYSTEM_NPCX_INIT_PRIORITY,
- &cros_system_driver_npcx_api);
-
-#if DT_NODE_EXISTS(DT_NODELABEL(dbg))
-#define HAL_DBG_REG_BASE_ADDR \
- ((struct dbg_reg *)DT_REG_ADDR(DT_INST(0, nuvoton_npcx_cros_dbg)))
-
-#define DBG_NODE DT_NODELABEL(dbg)
-#define DBG_PINCTRL_PH DT_PHANDLE_BY_IDX(DBG_NODE, pinctrl_0, 0)
-#define DBG_ALT_FILED(f) DT_PHA_BY_IDX(DBG_PINCTRL_PH, alts, 0, f)
-
-static int jtag_init(const struct device *dev)
-{
- ARG_UNUSED(dev);
- struct dbg_reg *const dbg_reg_base = HAL_DBG_REG_BASE_ADDR;
- const struct npcx_alt jtag_alts[] = {
- {
- .group = DBG_ALT_FILED(group),
- .bit = DBG_ALT_FILED(bit),
- .inverted = DBG_ALT_FILED(inv)
- }
- };
-
- dbg_reg_base->DBGCTRL = 0x04;
- dbg_reg_base->DBGFRZEN3 &= ~BIT(NPCX_DBGFRZEN3_GLBL_FRZ_DIS);
- if (DT_NODE_HAS_STATUS(DT_NODELABEL(dbg), okay))
- npcx_pinctrl_mux_configure(jtag_alts, 1, 1);
-
- return 0;
-}
-#if CONFIG_KERNEL_INIT_PRIORITY_DEFAULT >= 41
-#error "jtag_init must be called after default kernel init"
-#endif
-SYS_INIT(jtag_init, PRE_KERNEL_1, 41);
-#endif /* DT_NODE_EXISTS(DT_NODELABEL(dbg)) */