drivers: watchdog: add watchdog driver for sf32lb platform

Add initial watchdog driver for SF32LB platform

Signed-off-by: Qingsong Gou <gouqs@hotmail.com>
This commit is contained in:
Qingsong Gou
2025-10-14 11:43:14 +08:00
committed by Chris Friedt
parent 7bd0604631
commit bcc4689cd0
4 changed files with 138 additions and 1 deletions

View File

@@ -65,7 +65,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_SHELL wdt_shell.c)
zephyr_library_sources_ifdef(CONFIG_WDT_RENESAS_RA wdt_renesas_ra.c)
zephyr_library_sources_ifdef(CONFIG_WDT_RENESAS_RX_IWDT wdt_renesas_rx_iwdt.c)
zephyr_library_sources_ifdef(CONFIG_WDT_NXP_EWM wdt_nxp_ewm.c)
zephyr_library_sources_ifdef(CONFIG_WDT_SF32LB wdt_sf32lb.c)
zephyr_library_sources_ifdef(CONFIG_WDT_TI_RTI wdt_ti_rti.c)
zephyr_library_sources_ifdef(CONFIG_USERSPACE wdt_handlers.c)

View File

@@ -159,6 +159,8 @@ source "drivers/watchdog/Kconfig.wch"
source "drivers/watchdog/Kconfig.nxp_ewm"
source "drivers/watchdog/Kconfig.sf32lb"
source "drivers/watchdog/Kconfig.xilinx_wwdt"
source "drivers/watchdog/Kconfig.ti_rti"

View File

@@ -0,0 +1,11 @@
# Copyright (c) 2025 Qingsong Gou <gouqs@hotmail.com>
# SPDX-License-Identifier: Apache-2.0
config WDT_SF32LB
bool "SF32LB Watchdog (WDT) Driver"
default y
depends on DT_HAS_SIFLI_SF32LB_WDT_ENABLED
select HAS_WDT_DISABLE_AT_BOOT
select HAS_WDT_NO_CALLBACKS
help
Enable WDT driver for SF32LB series MCUs.

View File

@@ -0,0 +1,124 @@
/*
* Copyright (c) 2025, Qingsong Gou <gouqs@hotmail.com>
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT sifli_sf32lb_wdt
#include <zephyr/arch/cpu.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/logging/log.h>
#include <register.h>
LOG_MODULE_REGISTER(wdt_sf32lb, CONFIG_WDT_LOG_LEVEL);
#define WDT_CVR0 offsetof(WDT_TypeDef, WDT_CVR0)
#define WDT_CR offsetof(WDT_TypeDef, WDT_CR)
#define WDT_CCR offsetof(WDT_TypeDef, WDT_CCR)
#define WDT_CMD_START 0x00000076U
#define WDT_CMD_STOP 0x00000034U
#define WDT_CVR0_MAX 0xFFFFFF
#define WDT_WDT_CR_RESPONSE_MODE1 0U
/* Assume LRC10 clocks WDT (LRC32 support to be added in the future) */
#define WDT_CLK_KHZ 10
#define WDT_WINDOW_MS_MAX (WDT_CVR0_MAX / WDT_CLK_KHZ)
struct wdt_sf32lb_config {
uintptr_t base;
};
static int wdt_sf32lb_setup(const struct device *dev, uint8_t options)
{
const struct wdt_sf32lb_config *config = dev->config;
if (options != 0U) {
LOG_ERR("Options not supported");
return -ENOTSUP;
}
sys_write32(WDT_CMD_START, config->base + WDT_CCR);
return 0;
}
static int wdt_sf32lb_disable(const struct device *dev)
{
const struct wdt_sf32lb_config *config = dev->config;
sys_write32(WDT_CMD_STOP, config->base + WDT_CCR);
return 0;
}
static int wdt_sf32lb_install_timeout(const struct device *dev,
const struct wdt_timeout_cfg *wdt_cfg)
{
const struct wdt_sf32lb_config *config = dev->config;
if (wdt_cfg->flags != WDT_FLAG_RESET_SOC) {
LOG_ERR("Only SoC reset supported");
return -ENOTSUP;
}
if (wdt_cfg->callback != NULL) {
LOG_ERR("Callback not supported");
return -ENOTSUP;
}
if (wdt_cfg->window.min != 0U) {
LOG_ERR("Window mode not supported!");
return -ENOTSUP;
};
if (wdt_cfg->window.max > WDT_WINDOW_MS_MAX) {
return -EINVAL;
}
sys_write32(wdt_cfg->window.max * WDT_CLK_KHZ, config->base + WDT_CVR0);
return 0;
}
static int wdt_sf32lb_feed(const struct device *dev, int channel_id)
{
const struct wdt_sf32lb_config *config = dev->config;
sys_write32(WDT_CMD_START, config->base + WDT_CCR);
return 0;
}
static DEVICE_API(wdt, wdt_sf32lb_api) = {
.setup = wdt_sf32lb_setup,
.disable = wdt_sf32lb_disable,
.install_timeout = wdt_sf32lb_install_timeout,
.feed = wdt_sf32lb_feed,
};
static int wdt_sf32lb_init(const struct device *dev)
{
const struct wdt_sf32lb_config *config = dev->config;
uint32_t cr;
cr = sys_read32(config->base + WDT_CR);
cr &= ~WDT_WDT_CR_RESPONSE_MODE_Msk;
cr |= WDT_WDT_CR_RESPONSE_MODE1;
sys_write32(cr, config->base + WDT_CR);
return 0;
}
#define WDT_SF32LB_INIT(index) \
static const struct wdt_sf32lb_config wdt_sf32lb_config_##index = { \
.base = DT_INST_REG_ADDR(index), \
}; \
DEVICE_DT_INST_DEFINE(index, wdt_sf32lb_init, NULL, NULL, \
&wdt_sf32lb_config_##index, POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_sf32lb_api);
DT_INST_FOREACH_STATUS_OKAY(WDT_SF32LB_INIT)