diff --git a/boards/ti/am243x_evm/am243x_evm_am2434_r5f0_0.dts b/boards/ti/am243x_evm/am243x_evm_am2434_r5f0_0.dts index b498b214c257b..39a3a0ee9d8fe 100644 --- a/boards/ti/am243x_evm/am243x_evm_am2434_r5f0_0.dts +++ b/boards/ti/am243x_evm/am243x_evm_am2434_r5f0_0.dts @@ -183,6 +183,10 @@ }; }; +&main_rti8 { + status = "okay"; +}; + &main_mbox6 { usr-id = <0>; status = "okay"; diff --git a/drivers/watchdog/wdt_ti_rti.c b/drivers/watchdog/wdt_ti_rti.c index 3644dd2ccbc40..e504df59cc1b4 100644 --- a/drivers/watchdog/wdt_ti_rti.c +++ b/drivers/watchdog/wdt_ti_rti.c @@ -9,6 +9,7 @@ #include #include #include +#include #define WDENABLE_KEY 0xa98559da #define WDDISABLE_KEY 0x5312aced @@ -20,6 +21,9 @@ #define WDT_PRELOAD_MAX 0xfff +/* Only the last 6 bits are used */ +#define CLEAR_WDSTATUS 0x3f + #define RTIWWDRX_NMI 0xa #define RTIWWDRX_RESET 0x5 @@ -59,12 +63,15 @@ struct wdt_ti_rti_regs { struct wdt_ti_rti_data { DEVICE_MMIO_RAM; + + wdt_callback_t callback; }; struct wdt_ti_rti_config { DEVICE_MMIO_ROM; uint64_t freq; + void (*irq_config_func)(void); }; static int wdt_ti_rti_setup(const struct device *dev, uint8_t options) @@ -79,6 +86,8 @@ static int wdt_ti_rti_setup(const struct device *dev, uint8_t options) regs->GCTRL = RTIGCTRL_RUN_BY_DBG; } + /* Clear the Watchdog status register before enabling */ + regs->WDSTATUS = CLEAR_WDSTATUS; regs->DWDCTRL = WDENABLE_KEY; return 0; @@ -119,10 +128,13 @@ static int wdt_ti_rti_window_size(const struct wdt_window window) static int wdt_ti_rti_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) { const struct wdt_ti_rti_config *config = DEV_CFG(dev); + struct wdt_ti_rti_data *data = DEV_DATA(dev); struct wdt_ti_rti_regs *regs = DEV_REGS(dev); uint32_t timer_margin; int window_size; + data->callback = cfg->callback; + window_size = wdt_ti_rti_window_size(cfg->window); if (window_size < 0) { return window_size; @@ -134,6 +146,7 @@ static int wdt_ti_rti_timeout(const struct device *dev, const struct wdt_timeout return -EINVAL; } + /* Only NMI is supported */ if (cfg->flags == WDT_FLAG_RESET_SOC) { regs->WWDRXNCTRL = RTIWWDRX_NMI; } @@ -158,8 +171,23 @@ static int wdt_ti_rti_feed(const struct device *dev, int channel_id) return 0; } +static void wdt_ti_rti_isr(const struct device *dev) +{ + struct wdt_ti_rti_data *data = DEV_DATA(dev); + struct wdt_ti_rti_regs *regs = DEV_REGS(dev); + volatile uint32_t status = regs->WDSTATUS; + /* Clear status register before servicing the watchdog */ + regs->WDSTATUS = CLEAR_WDSTATUS; + if (status & BIT(5) && data->callback) { + data->callback(dev, 0); + } + regs->WDKEY = WDKEY_SEQ0; + regs->WDKEY = WDKEY_SEQ1; +} + static int wdt_ti_rti_init(const struct device *dev) { + const struct wdt_ti_rti_config *config = DEV_CFG(dev); struct wdt_ti_rti_regs *regs; DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); @@ -168,7 +196,8 @@ static int wdt_ti_rti_init(const struct device *dev) if (!regs) { return -EINVAL; } - + + config->irq_config_func(); return 0; } @@ -180,11 +209,18 @@ static DEVICE_API(wdt, wdt_ti_rti_api) = { }; #define WDT_TI_RTI_INIT(i) \ + static void wdt_ti_rti_irq_config_##i(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(i), DT_INST_IRQ(i, priority), wdt_ti_rti_isr, \ + DEVICE_DT_INST_GET(i), 0); \ + irq_enable(DT_INST_IRQN(i)); \ + }; \ static struct wdt_ti_rti_data wdt_ti_rti_data_##i = {}; \ \ static struct wdt_ti_rti_config wdt_ti_rti_config_##i = { \ DEVICE_MMIO_ROM_INIT(DT_DRV_INST(i)), \ .freq = DT_INST_PROP(i, clock_frequency), \ + .irq_config_func = wdt_ti_rti_irq_config_##i, \ }; \ \ DEVICE_DT_INST_DEFINE(i, wdt_ti_rti_init, NULL, &wdt_ti_rti_data_##i, \ diff --git a/dts/arm/ti/am64x_r5.dtsi b/dts/arm/ti/am64x_r5.dtsi index f95a2ef087392..f0e1f7039ac21 100644 --- a/dts/arm/ti/am64x_r5.dtsi +++ b/dts/arm/ti/am64x_r5.dtsi @@ -188,6 +188,11 @@ interrupt-parent = <&vim>; }; +&main_rti8 { + interrupts = <0 0 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; +}; + &main_mbox0 { interrupts = <0 96 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; interrupt-parent = <&vim>; diff --git a/dts/vendor/ti/am64x_main.dtsi b/dts/vendor/ti/am64x_main.dtsi index e735fe69f3ec8..7bf3fad6bbdc8 100644 --- a/dts/vendor/ti/am64x_main.dtsi +++ b/dts/vendor/ti/am64x_main.dtsi @@ -272,6 +272,14 @@ #size-cells = <0>; }; + main_rti8: watchdog@e080000 { + compatible = "ti,j7-rti-wdt"; + reg = <0xe080000 0x100>; + clock-frequency = ; + power-domains = <&rti8_pd>; + status = "disabled"; + }; + /* users: r5f0_0, r5f0_1, r5f1_0, r5f1_1 */ main_mbox0: mailbox@29000000 { compatible = "ti,omap-mailbox"; diff --git a/samples/drivers/watchdog/boards/am243x_evm_am2434_r5f0_0.overlay b/samples/drivers/watchdog/boards/am243x_evm_am2434_r5f0_0.overlay new file mode 100644 index 0000000000000..0ef02735732b8 --- /dev/null +++ b/samples/drivers/watchdog/boards/am243x_evm_am2434_r5f0_0.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2025 Texas Instruments Incorporated + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + watchdog0 = &main_rti8; + }; +};