From 2cf3caa11c433c28b11273752a5764c3c8c90e9e Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Fri, 30 Jun 2023 00:49:40 -0700 Subject: [PATCH] driver: wdt: npcx: add WDT_OPT_PAUSE_HALTED_BY_DBG support. This CL adds WDT_OPT_PAUSE_HALTED_BY_DBG support by enabling freeze mode. Signed-off-by: Mulin Chao --- drivers/watchdog/wdt_npcx.c | 7 ++-- dts/arm/nuvoton/npcx/npcx.dtsi | 6 ++-- soc/arm/nuvoton_npcx/common/reg/reg_def.h | 42 +++++++++++++++++++++++ soc/arm/nuvoton_npcx/common/scfg.c | 13 +++++++ soc/arm/nuvoton_npcx/common/soc_dbg.h | 26 ++++++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 soc/arm/nuvoton_npcx/common/soc_dbg.h diff --git a/drivers/watchdog/wdt_npcx.c b/drivers/watchdog/wdt_npcx.c index 4af2659e5a4..482bbd1c733 100644 --- a/drivers/watchdog/wdt_npcx.c +++ b/drivers/watchdog/wdt_npcx.c @@ -39,6 +39,7 @@ #include #include +#include "soc_dbg.h" LOG_MODULE_REGISTER(wdt_npcx, CONFIG_WDT_LOG_LEVEL); /* Watchdog operating frequency is fixed to LFCLK (32.768) kHz */ @@ -227,9 +228,11 @@ static int wdt_npcx_setup(const struct device *dev, uint8_t options) return -ENOTSUP; } + /* Stall the WDT counter when halted by debugger */ if ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) != 0) { - LOG_ERR("WDT_OPT_PAUSE_HALTED_BY_DBG is not supported"); - return -ENOTSUP; + npcx_dbg_freeze_enable(true); + } else { + npcx_dbg_freeze_enable(false); } /* diff --git a/dts/arm/nuvoton/npcx/npcx.dtsi b/dts/arm/nuvoton/npcx/npcx.dtsi index 3034afec328..78f0b84ba5b 100644 --- a/dts/arm/nuvoton/npcx/npcx.dtsi +++ b/dts/arm/nuvoton/npcx/npcx.dtsi @@ -83,10 +83,12 @@ scfg: scfg@400c3000 { compatible = "nuvoton,npcx-scfg"; /* First reg region is System Configuration Device */ - /* Second reg region is System Glue Device */ + /* Second reg region is Debugger Interface Device */ + /* Third reg region is System Glue Device */ reg = <0x400c3000 0x70 + 0x400c3070 0x30 0x400a5000 0x2000>; - reg-names = "scfg", "glue"; + reg-names = "scfg", "dbg", "glue"; #alt-cells = <3>; #lvol-cells = <2>; }; diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index 0bb92a99532..31517a0189c 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -158,6 +158,48 @@ static inline uint32_t npcx_pwdwn_ctl_offset(uint32_t ctl_no) #define NPCX_ENIDL_CTL_PECI_ENI 2 #define NPCX_ENIDL_CTL_ADC_ACC_DIS 1 +/* Macro functions for Development and Debugger Interface (DDI) registers */ +#define NPCX_DBGCTRL(base) (*(volatile uint8_t *)(base + 0x004)) +#define NPCX_DBGFRZEN1(base) (*(volatile uint8_t *)(base + 0x006)) +#define NPCX_DBGFRZEN2(base) (*(volatile uint8_t *)(base + 0x007)) +#define NPCX_DBGFRZEN3(base) (*(volatile uint8_t *)(base + 0x008)) +#define NPCX_DBGFRZEN4(base) (*(volatile uint8_t *)(base + 0x009)) + +/* DDI register fields */ +#define NPCX_DBGCTRL_CCDEV_SEL FIELD(6, 2) +#define NPCX_DBGCTRL_CCDEV_DIR 5 +#define NPCX_DBGCTRL_SEQ_WK_EN 4 +#define NPCX_DBGCTRL_FRCLK_SEL_DIS 3 +#define NPCX_DBGFRZEN1_SPIFEN 7 +#define NPCX_DBGFRZEN1_HIFEN 6 +#define NPCX_DBGFRZEN1_ESPISEN 5 +#define NPCX_DBGFRZEN1_UART1FEN 4 +#define NPCX_DBGFRZEN1_SMB3FEN 3 +#define NPCX_DBGFRZEN1_SMB2FEN 2 +#define NPCX_DBGFRZEN1_MFT2FEN 1 +#define NPCX_DBGFRZEN1_MFT1FEN 0 +#define NPCX_DBGFRZEN2_ITIM6FEN 7 +#define NPCX_DBGFRZEN2_ITIM5FEN 6 +#define NPCX_DBGFRZEN2_ITIM4FEN 5 +#define NPCX_DBGFRZEN2_ITIM64FEN 3 +#define NPCX_DBGFRZEN2_SMB1FEN 2 +#define NPCX_DBGFRZEN2_SMB0FEN 1 +#define NPCX_DBGFRZEN2_MFT3FEN 0 +#define NPCX_DBGFRZEN3_GLBL_FRZ_DIS 7 +#define NPCX_DBGFRZEN3_ITIM3FEN 6 +#define NPCX_DBGFRZEN3_ITIM2FEN 5 +#define NPCX_DBGFRZEN3_ITIM1FEN 4 +#define NPCX_DBGFRZEN3_I3CFEN 2 +#define NPCX_DBGFRZEN3_SMB4FEN 1 +#define NPCX_DBGFRZEN3_SHMFEN 0 +#define NPCX_DBGFRZEN4_UART2FEN 6 +#define NPCX_DBGFRZEN4_UART3FEN 5 +#define NPCX_DBGFRZEN4_UART4FEN 4 +#define NPCX_DBGFRZEN4_LCTFEN 3 +#define NPCX_DBGFRZEN4_SMB7FEN 2 +#define NPCX_DBGFRZEN4_SMB6FEN 1 +#define NPCX_DBGFRZEN4_SMB5FEN 0 + /* * System Configuration (SCFG) device registers */ diff --git a/soc/arm/nuvoton_npcx/common/scfg.c b/soc/arm/nuvoton_npcx/common/scfg.c index 18d7f228d2d..42add909aa7 100644 --- a/soc/arm/nuvoton_npcx/common/scfg.c +++ b/soc/arm/nuvoton_npcx/common/scfg.c @@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(pimux_npcx, LOG_LEVEL_ERR); struct npcx_scfg_config { /* scfg device base address */ uintptr_t base_scfg; + uintptr_t base_dbg; uintptr_t base_glue; }; @@ -45,6 +46,7 @@ static const struct npcx_alt def_alts[] = { static const struct npcx_scfg_config npcx_scfg_cfg = { .base_scfg = DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), scfg), + .base_dbg = DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), dbg), .base_glue = DT_REG_ADDR_BY_NAME(DT_NODELABEL(scfg), glue), }; @@ -129,6 +131,17 @@ void npcx_host_interface_sel(enum npcx_hif_type hif_type) SET_FIELD(inst_scfg->DEVCNT, NPCX_DEVCNT_HIF_TYP_SEL_FIELD, hif_type); } +void npcx_dbg_freeze_enable(bool enable) +{ + const uintptr_t dbg_base = npcx_scfg_cfg.base_dbg; + + if (enable) { + NPCX_DBGFRZEN3(dbg_base) &= ~BIT(NPCX_DBGFRZEN3_GLBL_FRZ_DIS); + } else { + NPCX_DBGFRZEN3(dbg_base) |= BIT(NPCX_DBGFRZEN3_GLBL_FRZ_DIS); + } +} + /* Pin-control driver registration */ static int npcx_scfg_init(void) { diff --git a/soc/arm/nuvoton_npcx/common/soc_dbg.h b/soc/arm/nuvoton_npcx/common/soc_dbg.h new file mode 100644 index 00000000000..dc8f2ce1202 --- /dev/null +++ b/soc/arm/nuvoton_npcx/common/soc_dbg.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NUVOTON_NPCX_SOC_DBG_H_ +#define _NUVOTON_NPCX_SOC_DBG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configure the Automatic Freeze mode. If this mode is enabled, whenever + * the Core is halted, various modules’ clocks, counters are stopped and + * destructive reads are disabled, pending the respective module enable bit for + * debugging. + */ +void npcx_dbg_freeze_enable(bool enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _NUVOTON_NPCX_SOC_DBG_H_ */