summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWealian Liao <whliao@nuvoton.corp-partner.google.com>2021-02-17 16:00:41 +0800
committerCommit Bot <commit-bot@chromium.org>2021-02-22 23:41:45 +0000
commita384e42b985225aaa20e60ce2574dc8b6d782fc8 (patch)
tree2bf0ddffc06fc8677613ec0c67481283a9e749ac
parent400929c7d00bde06c1cc5668c5bececd045b3d1f (diff)
downloadchrome-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.c58
-rw-r--r--zephyr/include/drivers/cros_system.h52
-rw-r--r--zephyr/shim/chip/npcx/system.c20
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)
;
}