Skip to content

Commit 70c6bef

Browse files
blauretcarlescufi
authored andcommitted
drivers: watchdog: implement Smartbond watchdog driver
This patch adds watchdog driver for Renesas Smartbond SOCs. Co-authored-by: Jerzy Kasenberg <[email protected]> Signed-off-by: Ben Lauret <[email protected]>
1 parent 36ac1ee commit 70c6bef

File tree

8 files changed

+188
-1
lines changed

8 files changed

+188
-1
lines changed

boards/arm/da1469x_dk_pro/da1469x_dk_pro.dts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
aliases {
6161
led0 = &red_led;
62+
watchdog0 = &wdog;
6263
};
6364

6465
sysclk: system-clock {

boards/arm/da1469x_dk_pro/da1469x_dk_pro.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ toolchain:
1010
supported:
1111
- arduino_gpio
1212
- gpio
13+
- watchdog

drivers/watchdog/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_SIFIVE wdt_sifive.c)
2929
zephyr_library_sources_ifdef(CONFIG_WDT_XEC wdt_mchp_xec.c)
3030
zephyr_library_sources_ifdef(CONFIG_WDT_COUNTER wdt_counter.c)
3131
zephyr_library_sources_ifdef(CONFIG_WDT_NXP_S32 wdt_nxp_s32.c)
32+
zephyr_library_sources_ifdef(CONFIG_WDT_SMARTBOND wdt_smartbond.c)
3233

3334
zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c)
3435

drivers/watchdog/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,6 @@ source "drivers/watchdog/Kconfig.nxp_s32"
9696

9797
source "drivers/watchdog/Kconfig.dw"
9898

99+
source "drivers/watchdog/Kconfig.smartbond"
100+
99101
endif # WATCHDOG

drivers/watchdog/Kconfig.smartbond

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Smartbond watchdog driver config
2+
3+
# Copyright (c) 2022 Renesas Electronics Corporation and/or its affiliates
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config WDT_SMARTBOND
7+
bool "Watchdog Driver for Smartbond family of MCUs"
8+
default y
9+
depends on DT_HAS_RENESAS_SMARTBOND_WATCHDOG_ENABLED
10+
help
11+
Enable watchdog driver for Smartbond line of MCUs
12+
13+
config WDT_SMARTBOND_NMI
14+
bool "NMI pre-reset interrupt enable"
15+
default n
16+
depends on WDT_SMARTBOND
17+
select RUNTIME_NMI
18+
help
19+
Watchdog timer generates NMI at value 0, and WDOG (SYS)
20+
reset at <= -16. Timer can be frozen/resumed using
21+
SET_FREEZE_REG[FRZ_WDOG]/RESET_FREEZE_REG[FRZ_WDOG].
22+
When not set:
23+
Watchdog timer generates a WDOG (SYS)
24+
reset at value 0 and can not be frozen by Software.
25+
Note that this bit can only be set to 1 by SW and
26+
only be reset with a WDOG (SYS) reset or SW reset.

drivers/watchdog/wdt_smartbond.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Copyright (c) 2022 Renesas Electronics Corporation and/or its affiliates
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <soc.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/drivers/watchdog.h>
10+
#include <zephyr/logging/log.h>
11+
12+
LOG_MODULE_REGISTER(wdog_smartbond, CONFIG_WDT_LOG_LEVEL);
13+
14+
#define DT_DRV_COMPAT renesas_smartbond_watchdog
15+
16+
/* driver data */
17+
struct wdog_smartbond_data {
18+
/* Reload value calculated in setup */
19+
uint32_t reload_val;
20+
#ifdef CONFIG_WDT_SMARTBOND_NMI
21+
const struct device *wdog_device;
22+
wdt_callback_t callback;
23+
#endif
24+
};
25+
26+
static struct wdog_smartbond_data wdog_smartbond_dev_data = {};
27+
28+
static int wdg_smartbond_setup(const struct device *dev, uint8_t options)
29+
{
30+
ARG_UNUSED(dev);
31+
32+
if (options & WDT_OPT_PAUSE_IN_SLEEP) {
33+
LOG_ERR("Watchdog pause in sleep is not supported");
34+
return -ENOTSUP;
35+
}
36+
return 0;
37+
}
38+
39+
static int wdg_smartbond_disable(const struct device *dev)
40+
{
41+
ARG_UNUSED(dev);
42+
43+
if (SYS_WDOG->WATCHDOG_CTRL_REG & SYS_WDOG_WATCHDOG_CTRL_REG_NMI_RST_Msk) {
44+
/* watchdog cannot be stopped once started when NMI_RST is 1 */
45+
return -EPERM;
46+
}
47+
48+
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk;
49+
return 0;
50+
}
51+
52+
#ifdef CONFIG_WDT_SMARTBOND_NMI
53+
extern void z_NmiHandlerSet(void (*pHandler)(void));
54+
55+
static void wdog_smartbond_nmi_isr(void)
56+
{
57+
if (wdog_smartbond_dev_data.callback) {
58+
wdog_smartbond_dev_data.callback(wdog_smartbond_dev_data.wdog_device, 0);
59+
}
60+
}
61+
#endif /* CONFIG_RUNTIME_NMI */
62+
63+
static int wdg_smartbond_install_timeout(const struct device *dev,
64+
const struct wdt_timeout_cfg *config)
65+
{
66+
struct wdog_smartbond_data *data = (struct wdog_smartbond_data *)(dev)->data;
67+
uint32_t reload_val;
68+
69+
#ifndef CONFIG_WDT_SMARTBOND_NMI
70+
if (config->callback != NULL) {
71+
return -ENOTSUP;
72+
}
73+
#endif
74+
/* For RC32K timer ticks every ~10ms, for RCX ~21ms */
75+
if (CRG_TOP->CLK_RCX_REG & CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk) {
76+
reload_val = config->window.max / 21;
77+
} else {
78+
reload_val = config->window.max / 10;
79+
}
80+
81+
if (reload_val < 1 || reload_val >= 0x2000 || config->window.min != 0) {
82+
/* Out of range supported by watchdog */
83+
LOG_ERR("Watchdog timeout out of range");
84+
return -EINVAL;
85+
}
86+
#if CONFIG_WDT_SMARTBOND_NMI
87+
data->callback = config->callback;
88+
data->wdog_device = dev;
89+
z_NmiHandlerSet(wdog_smartbond_nmi_isr);
90+
SYS_WDOG->WATCHDOG_CTRL_REG = 2;
91+
#else
92+
SYS_WDOG->WATCHDOG_CTRL_REG = 2 | SYS_WDOG_WATCHDOG_CTRL_REG_NMI_RST_Msk;
93+
#endif
94+
95+
data->reload_val = reload_val;
96+
while (SYS_WDOG->WATCHDOG_CTRL_REG & SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Msk) {
97+
/* wait */
98+
}
99+
SYS_WDOG->WATCHDOG_REG = reload_val;
100+
101+
return 0;
102+
}
103+
104+
static int wdg_smartbond_feed(const struct device *dev, int channel_id)
105+
{
106+
struct wdog_smartbond_data *data = (struct wdog_smartbond_data *)(dev)->data;
107+
108+
ARG_UNUSED(channel_id);
109+
110+
while (SYS_WDOG->WATCHDOG_CTRL_REG & SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Msk) {
111+
/* wait */
112+
}
113+
SYS_WDOG->WATCHDOG_REG = data->reload_val;
114+
115+
return 0;
116+
}
117+
118+
static const struct wdt_driver_api wdg_smartbond_api = {
119+
.setup = wdg_smartbond_setup,
120+
.disable = wdg_smartbond_disable,
121+
.install_timeout = wdg_smartbond_install_timeout,
122+
.feed = wdg_smartbond_feed,
123+
};
124+
125+
static int wdg_smartbond_init(const struct device *dev)
126+
{
127+
ARG_UNUSED(dev);
128+
129+
#ifdef CONFIG_WDT_DISABLE_AT_BOOT
130+
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk;
131+
#endif
132+
133+
return 0;
134+
}
135+
136+
DEVICE_DT_INST_DEFINE(0, wdg_smartbond_init, NULL, &wdog_smartbond_dev_data, NULL, POST_KERNEL,
137+
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdg_smartbond_api);

dts/arm/renesas/smartbond/da1469x.dtsi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Renesas Electronics Corporation
2+
* Copyright (c) 2022 Renesas Electronics Corporation and/or its affiliates
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -23,6 +23,7 @@
2323
};
2424
};
2525

26+
2627
soc {
2728
sram0: memory@20000000 {
2829
compatible = "mmio-sram";
@@ -81,6 +82,12 @@
8182
};
8283
};
8384

85+
wdog: watchdog@50000700 {
86+
compatible = "renesas,smartbond-watchdog";
87+
reg = <0x50000700 0x8>;
88+
status = "okay";
89+
};
90+
8491
uart: uart@50020000 {
8592
compatible = "renesas,smartbond-uart";
8693
reg = <0x50020000 0x100>;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2022 Renesas Electronics Corporation and/or its affiliates
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Smartbond watchdog
5+
6+
compatible: "renesas,smartbond-watchdog"
7+
8+
include: base.yaml
9+
10+
properties:
11+
reg:
12+
required: true

0 commit comments

Comments
 (0)