diff options
author | Wealian Liao <whliao@nuvoton.corp-partner.google.com> | 2021-02-17 16:00:41 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-22 23:41:45 +0000 |
commit | a384e42b985225aaa20e60ce2574dc8b6d782fc8 (patch) | |
tree | 2bf0ddffc06fc8677613ec0c67481283a9e749ac | |
parent | 400929c7d00bde06c1cc5668c5bececd045b3d1f (diff) | |
download | chrome-ec-a384e42b985225aaa20e60ce2574dc8b6d782fc8.tar.gz |
zephyr: npcx: add system reset driver
This CL include the following:
1. Add cros_system_soc_reset() API for system reset.
2. Add NPCX soc reset driver. NPCX chip doesn't have the specific
system reset functionality. Use watchdog reset as the system reset.
BUG=b:176523207
BRANCH=None.
TEST=reset EC by 'reboot' console command
Signed-off-by: Wealian Liao <whliao@nuvoton.corp-partner.google.com>
Change-Id: Ia86bfac548ef48e18e501a29f3cbb632f33a3e8a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2698739
Reviewed-by: Simon Glass <sjg@chromium.org>
Commit-Queue: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | zephyr/drivers/cros_system/cros_system_npcx.c | 58 | ||||
-rw-r--r-- | zephyr/include/drivers/cros_system.h | 52 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/system.c | 20 |
3 files changed, 125 insertions, 5 deletions
diff --git a/zephyr/drivers/cros_system/cros_system_npcx.c b/zephyr/drivers/cros_system/cros_system_npcx.c index 87db955e4a..b63743a13d 100644 --- a/zephyr/drivers/cros_system/cros_system_npcx.c +++ b/zephyr/drivers/cros_system/cros_system_npcx.c @@ -4,6 +4,7 @@ */ #include <drivers/cros_system.h> +#include <drivers/watchdog.h> #include <logging/log.h> #include <soc.h> @@ -29,6 +30,16 @@ struct cros_system_npcx_data { #define DRV_DATA(dev) ((struct cros_system_npcx_data *)(dev)->data) +/* + * For cortex-m we cannot use irq_lock() for disabling all the interrupts + * because it leaves some (NMI and faults) still enabled. Use "cpsid i" to + * replace it. + */ +static inline void interrupt_disable_all(void) +{ + __asm__("cpsid i"); +} + static int cros_system_npcx_get_reset_cause(const struct device *dev) { struct cros_system_npcx_data *data = DRV_DATA(dev); @@ -58,6 +69,52 @@ static int cros_system_npcx_init(const struct device *dev) 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 */ + if (IS_ENABLED(CONFIG_WATCHDOG)) { + const struct device *wdt_dev = device_get_binding( + DT_LABEL(DT_INST(0, nuvoton_npcx_watchdog))); + + if (!wdt_dev) { + LOG_ERR("wdt_dev get binding failed"); + return -ENODEV; + } + + wdt_disable(wdt_dev); + } + + /* Enable early touch */ + inst_twd->T0CSR &= ~BIT(NPCX_T0CSR_TESDIS); + inst_twd->TWCFG |= BIT(NPCX_TWCFG_WDSDME); + + /* + * 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 struct cros_system_npcx_data cros_system_npcx_dev_data; static const struct cros_system_npcx_config cros_system_dev_cfg = { @@ -67,6 +124,7 @@ static const struct cros_system_npcx_config cros_system_dev_cfg = { 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, }; /* diff --git a/zephyr/include/drivers/cros_system.h b/zephyr/include/drivers/cros_system.h index 489c86a6f7..8c5b24ef2f 100644 --- a/zephyr/include/drivers/cros_system.h +++ b/zephyr/include/drivers/cros_system.h @@ -3,16 +3,28 @@ * found in the LICENSE file. */ +/** + * @file + * @brief Public API for cros system drivers + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_CROS_SYSTEM_H_ #define ZEPHYR_INCLUDE_DRIVERS_CROS_SYSTEM_H_ +/** + * @brief cros system Interface + * @defgroup cros_system_interface cros system Interface + * @ingroup io_interfaces + * @{ + */ + #include <kernel.h> #include <device.h> /** - * @brief CROS system driver APIs + * @brief system_reset_cause enum + * Identify the reset cause. */ - enum system_reset_cause { /* the reset is triggered by VCC power-up */ POWERUP = 0, @@ -26,10 +38,24 @@ enum system_reset_cause { UNKNOWN_RST, }; +/** + * @typedef cros_system_get_reset_cause_api + * @brief Callback API for getting reset cause instance. + * See cros_system_get_reset_cause() for argument descriptions + */ typedef int (*cros_system_get_reset_cause_api)(const struct device *dev); +/** + * @typedef cros_system_soc_reset_api + * @brief Callback API for soc-reset instance. + * See cros_system_soc_reset() for argument descriptions + */ +typedef int (*cros_system_soc_reset_api)(const struct device *dev); + +/** @brief Driver API structure. */ __subsystem struct cros_system_driver_api { cros_system_get_reset_cause_api get_reset_cause; + cros_system_soc_reset_api soc_reset; }; /** @@ -55,6 +81,28 @@ static inline int z_impl_cros_system_get_reset_cause(const struct device *dev) } /** + * @brief reset the soc + * + * @param dev Pointer to the device structure for the driver instance. + * + * @retval no return if successful. + * @retval Negative errno code if failure. + */ +__syscall int cros_system_soc_reset(const struct device *dev); + +static inline int z_impl_cros_system_soc_reset(const struct device *dev) +{ + const struct cros_system_driver_api *api = + (const struct cros_system_driver_api *)dev->api; + + if (!api->soc_reset) { + return -ENOTSUP; + } + + return api->soc_reset(dev); +} + +/** * @} */ #include <syscalls/cros_system.h> diff --git a/zephyr/shim/chip/npcx/system.c b/zephyr/shim/chip/npcx/system.c index e86d77a7fd..4e25363415 100644 --- a/zephyr/shim/chip/npcx/system.c +++ b/zephyr/shim/chip/npcx/system.c @@ -3,16 +3,30 @@ * found in the LICENSE file. */ +#include <drivers/cros_system.h> +#include <logging/log.h> + #include "system.h" +LOG_MODULE_REGISTER(shim_npcx_system, LOG_LEVEL_ERR); + void system_reset(int flags) { + const struct device *sys_dev = device_get_binding("CROS_SYSTEM"); + int err; + + if (!sys_dev) + LOG_ERR("sys_dev get binding failed"); + /* - * TODO(b/176523207): Reset the system. NPCX uses Watchdog & BBRAM for - * system reset & reset flag saving. The function could be implemented - * after Watchdog & BBRAM land the zephyr repository. + * TODO(b/176523207): reset flag & SYSTEM_RESET_WAIT_EXT */ + err = cros_system_soc_reset(sys_dev); + + if (err < 0) + LOG_ERR("soc reset failed"); + while (1) ; } |