From: Alice Guo <[email protected]> Replace hardcoded WDOG_BASE_ADDR with driver model based dynamic address lookup from device tree, allowing reset_cpu() to dynamically locate watchdog devices from device tree.
This change also enables CONFIG_WDT for relevant boards and ensures the watchdog nodes are available for driver model usage. - Remove hardcoded WDOG_BASE_ADDR from hw_watchdog_* functions - Reimplement reset_cpu() using UCLASS_WDT device iteration - Add ulp_wdt_expire_now() callback for standard WDT interface - Pass wdog register pointer to hw_watchdog_set_timeout() - Enable CONFIG_WDT for boards using ULP watchdog - Remove wdog3 status = "disabled" overrides from U-Boot device tree overlays, as the watchdog device needs to be accessible for driver model based reset functionality. Signed-off-by: Alice Guo <[email protected]> Acked-by: Francesco Dolcini <[email protected]> # Toradex boards --- arch/arm/dts/imx8ulp-evk-u-boot.dtsi | 4 -- arch/arm/dts/imx943-evk-u-boot.dtsi | 4 -- arch/arm/dts/imx95-15x15-evk-u-boot.dtsi | 4 -- arch/arm/dts/imx95-19x19-evk-u-boot.dtsi | 4 -- arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi | 4 -- arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi | 4 -- configs/imx8ulp_evk_defconfig | 1 + configs/imx93-phycore_defconfig | 1 + configs/imx943_evk_defconfig | 1 + configs/imx95_15x15_evk_defconfig | 1 + configs/imx95_evk.config | 1 + configs/mx7ulp_com_defconfig | 1 + configs/toradex-smarc-imx95_defconfig | 1 + configs/verdin-imx95_defconfig | 1 + drivers/watchdog/ulp_wdog.c | 79 +++++++++--------------- 15 files changed, 36 insertions(+), 75 deletions(-) diff --git a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi index 860994129ae..ac130b54738 100644 --- a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi @@ -26,10 +26,6 @@ status = "disabled"; }; -&wdog3 { - status = "disabled"; -}; - &per_bridge4 { bootph-pre-ram; }; diff --git a/arch/arm/dts/imx943-evk-u-boot.dtsi b/arch/arm/dts/imx943-evk-u-boot.dtsi index 247a7ed6838..3b3619d2232 100644 --- a/arch/arm/dts/imx943-evk-u-boot.dtsi +++ b/arch/arm/dts/imx943-evk-u-boot.dtsi @@ -153,10 +153,6 @@ bootph-pre-ram; }; -&wdog3 { - status = "disabled"; -}; - &xspi1 { bootph-pre-ram; pinctrl-names = "default"; diff --git a/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi b/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi index 514dd729be9..34b4073ff35 100644 --- a/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi +++ b/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi @@ -44,10 +44,6 @@ bootph-pre-ram; }; -&wdog3 { - status = "disabled"; -}; - &pinctrl_uart1 { bootph-pre-ram; }; diff --git a/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi b/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi index 8b59831b7ca..1083d863c4d 100644 --- a/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi +++ b/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi @@ -28,10 +28,6 @@ bootph-pre-ram; }; -&wdog3 { - status = "disabled"; -}; - &pinctrl_uart1 { bootph-pre-ram; }; diff --git a/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi b/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi index 97ce7402e50..c30e2d6aaee 100644 --- a/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi +++ b/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi @@ -104,7 +104,3 @@ &usdhc2 { bootph-pre-ram; }; - -&wdog3 { - status = "disabled"; -}; diff --git a/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi b/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi index 83802156d52..7d16001baa5 100644 --- a/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi +++ b/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi @@ -106,7 +106,3 @@ &usdhc1 { bootph-pre-ram; }; - -&wdog3 { - status = "disabled"; -}; diff --git a/configs/imx8ulp_evk_defconfig b/configs/imx8ulp_evk_defconfig index baa8c1e4695..2101532833e 100644 --- a/configs/imx8ulp_evk_defconfig +++ b/configs/imx8ulp_evk_defconfig @@ -92,3 +92,4 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_NXP_FSPI=y CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y diff --git a/configs/imx93-phycore_defconfig b/configs/imx93-phycore_defconfig index 0634378149d..f87581d4ddc 100644 --- a/configs/imx93-phycore_defconfig +++ b/configs/imx93-phycore_defconfig @@ -156,6 +156,7 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1fc9 CONFIG_USB_GADGET_PRODUCT_NUM=0x0152 CONFIG_CI_UDC=y CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y # CONFIG_RSA is not set # CONFIG_SPL_SHA256 is not set CONFIG_LZO=y diff --git a/configs/imx943_evk_defconfig b/configs/imx943_evk_defconfig index 70265f13bba..b60d39a1fa2 100644 --- a/configs/imx943_evk_defconfig +++ b/configs/imx943_evk_defconfig @@ -151,3 +151,4 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_SDP_LOADADDR=0x90400000 CONFIG_SPL_USB_SDP_SUPPORT=y CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y diff --git a/configs/imx95_15x15_evk_defconfig b/configs/imx95_15x15_evk_defconfig index e9cd289d31f..3c18956ffe9 100644 --- a/configs/imx95_15x15_evk_defconfig +++ b/configs/imx95_15x15_evk_defconfig @@ -147,5 +147,6 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_NXP_FSPI=y CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y CONFIG_LZO=y CONFIG_BZIP2=y diff --git a/configs/imx95_evk.config b/configs/imx95_evk.config index 30ad2e60313..743778d9554 100644 --- a/configs/imx95_evk.config +++ b/configs/imx95_evk.config @@ -151,3 +151,4 @@ CONFIG_NXP_FSPI=y CONFIG_ULP_WATCHDOG=y CONFIG_LZO=y CONFIG_BZIP2=y +CONFIG_WDT=y diff --git a/configs/mx7ulp_com_defconfig b/configs/mx7ulp_com_defconfig index d63168fe886..c9c3f6b5f26 100644 --- a/configs/mx7ulp_com_defconfig +++ b/configs/mx7ulp_com_defconfig @@ -63,3 +63,4 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y diff --git a/configs/toradex-smarc-imx95_defconfig b/configs/toradex-smarc-imx95_defconfig index caf0718fc13..9363eb5cbb6 100644 --- a/configs/toradex-smarc-imx95_defconfig +++ b/configs/toradex-smarc-imx95_defconfig @@ -175,5 +175,6 @@ CONFIG_USB_GADGET_OS_DESCRIPTORS=y CONFIG_CI_UDC=y CONFIG_SDP_LOADADDR=0x90400000 CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y # CONFIG_SPL_SHA1 is not set CONFIG_LZO=y diff --git a/configs/verdin-imx95_defconfig b/configs/verdin-imx95_defconfig index 50515250d17..ea1ebb0c492 100644 --- a/configs/verdin-imx95_defconfig +++ b/configs/verdin-imx95_defconfig @@ -180,5 +180,6 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x4000 CONFIG_USB_GADGET_OS_DESCRIPTORS=y CONFIG_SDP_LOADADDR=0x90400000 CONFIG_ULP_WATCHDOG=y +CONFIG_WDT=y # CONFIG_SPL_SHA1 is not set CONFIG_LZO=y diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c index 83f19dc0e86..e3a89031c44 100644 --- a/drivers/watchdog/ulp_wdog.c +++ b/drivers/watchdog/ulp_wdog.c @@ -7,6 +7,7 @@ #include <asm/io.h> #include <asm/arch/imx-regs.h> #include <dm.h> +#include <linux/delay.h> #include <wdt.h> /* @@ -51,11 +52,9 @@ struct ulp_wdt_priv { #define CLK_RATE_1KHZ 1000 #define CLK_RATE_32KHZ 125 -void hw_watchdog_set_timeout(u16 val) +void hw_watchdog_set_timeout(struct wdog_regs *wdog, u16 val) { /* setting timeout value */ - struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - writel(val, &wdog->toval); } @@ -89,7 +88,7 @@ void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout) while (!(readl(&wdog->cs) & WDGCS_ULK)) ; - hw_watchdog_set_timeout(timeout); + hw_watchdog_set_timeout(wdog, timeout); writel(0, &wdog->win); /* setting 1-kHz clock source, enable counter running, and clear interrupt */ @@ -107,57 +106,20 @@ void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout) ulp_watchdog_reset(wdog); } -void hw_watchdog_reset(void) -{ - struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - - ulp_watchdog_reset(wdog); -} - -void hw_watchdog_init(void) -{ - struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - - ulp_watchdog_init(wdog, CONFIG_WATCHDOG_TIMEOUT_MSECS); -} - -#if !CONFIG_IS_ENABLED(SYSRESET) +#if !CONFIG_IS_ENABLED(SYSRESET) && CONFIG_IS_ENABLED(WDT) void reset_cpu(void) { - struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - u32 cmd32 = 0; - - if (readl(&wdog->cs) & WDGCS_CMD32EN) { - writel(UNLOCK_WORD, &wdog->cnt); - cmd32 = WDGCS_CMD32EN; - } else { - dmb(); - __raw_writel(UNLOCK_WORD0, &wdog->cnt); - __raw_writel(UNLOCK_WORD1, &wdog->cnt); - dmb(); - } + struct udevice *wdt; - /* Wait WDOG Unlock */ - while (!(readl(&wdog->cs) & WDGCS_ULK)) - ; + for (uclass_first_device(UCLASS_WDT, &wdt); + wdt; + uclass_next_device(&wdt)) { + if (!dev_read_enabled(wdt)) + continue; - hw_watchdog_set_timeout(5); /* 5ms timeout for general; 40ms timeout for imx93 */ - writel(0, &wdog->win); - - /* enable counter running */ - if (IS_ENABLED(CONFIG_ARCH_IMX9)) - writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8) | WDOG_CS_PRES | - WDGCS_INT), &wdog->cs); - else - writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs); - - /* Wait WDOG reconfiguration */ - while (!(readl(&wdog->cs) & WDGCS_RCS)) - ; - - hw_watchdog_reset(); - - while (1); + wdt_expire_now(wdt, 0); + break; + } } #endif @@ -184,6 +146,20 @@ static int ulp_wdt_reset(struct udevice *dev) return 0; } +static int ulp_wdt_expire_now(struct udevice *dev, ulong flags) +{ + int ret; + + /* 5ms timeout for all others; 40ms timeout for "fsl,imx93-wdt" */ + ret = ulp_wdt_start(dev, 5, flags); + if (ret) + return ret; + + mdelay(50); + + return 0; +} + static int ulp_wdt_probe(struct udevice *dev) { struct ulp_wdt_priv *priv = dev_get_priv(dev); @@ -202,6 +178,7 @@ static int ulp_wdt_probe(struct udevice *dev) static const struct wdt_ops ulp_wdt_ops = { .start = ulp_wdt_start, .reset = ulp_wdt_reset, + .expire_now = ulp_wdt_expire_now, }; static const struct udevice_id ulp_wdt_ids[] = { -- 2.34.1

