From patchwork Sun Feb 2 17:10:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 235774 List-Id: U-Boot discussion From: seanga2 at gmail.com (Sean Anderson) Date: Sun, 2 Feb 2020 12:10:54 -0500 Subject: [PATCH 1/4] wdt: Add CONFIG_DESIGNWARE_WATCHDOG to Kconfig Message-ID: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> Currently this is set from headers. No board has this set by default, so we don't need to modify any configs. Signed-off-by: Sean Anderson --- drivers/watchdog/Kconfig | 7 +++++++ include/configs/socfpga_common.h | 1 - include/configs/socfpga_soc64_common.h | 1 - 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 8c16d69d33..b717eebe3c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -176,6 +176,13 @@ config WDT_TANGIER Intel Tangier SoC. If you're using a board with Intel Tangier SoC, say Y here. +config DESIGNWARE_WATCHDOG + bool "Synopsys Designware watchdog timer support" + select HW_WATCHDOG if !WDT + help + Enable support for the Synopsys Designware watchdog timer, which can + be found on Altera socfpgas, and on Kendryte CPUs. + config SPL_WDT bool "Enable driver model for watchdog timer drivers in SPL" depends on SPL_DM diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 05bfef75c0..5329b19af2 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -105,7 +105,6 @@ * L4 Watchdog */ #ifdef CONFIG_HW_WATCHDOG -#define CONFIG_DESIGNWARE_WATCHDOG #define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS #define CONFIG_DW_WDT_CLOCK_KHZ 25000 #endif diff --git a/include/configs/socfpga_soc64_common.h b/include/configs/socfpga_soc64_common.h index 4afadafd35..159e60ec6e 100644 --- a/include/configs/socfpga_soc64_common.h +++ b/include/configs/socfpga_soc64_common.h @@ -152,7 +152,6 @@ unsigned int cm_get_qspi_controller_clk_hz(void); */ #ifdef CONFIG_SPL_BUILD #define CONFIG_HW_WATCHDOG -#define CONFIG_DESIGNWARE_WATCHDOG #define CONFIG_DW_WDT_BASE SOCFPGA_L4WD0_ADDRESS #ifdef CONFIG_TARGET_SOCFPGA_STRATIX10 #ifndef __ASSEMBLY__ From patchwork Sun Feb 2 17:12:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 235775 List-Id: U-Boot discussion From: seanga2 at gmail.com (Sean Anderson) Date: Sun, 2 Feb 2020 12:12:12 -0500 Subject: [PATCH 2/4] arm: Move asm/utils.h to log2.h In-Reply-To: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> References: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> Message-ID: This header is needed outside of the arm architecture by the designware wdt driver. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- arch/arm/cpu/armv7/cache_v7.c | 2 +- arch/arm/mach-davinci/spl.c | 2 +- arch/arm/mach-omap2/clocks-common.c | 2 +- arch/arm/mach-omap2/emif-common.c | 2 +- arch/arm/mach-omap2/omap4/emif.c | 2 +- arch/arm/mach-omap2/omap5/dra7xx_iodelay.c | 2 +- arch/arm/mach-omap2/omap5/emif.c | 2 +- arch/arm/mach-omap2/omap5/hwinit.c | 2 +- arch/arm/mach-socfpga/spl_a10.c | 2 +- arch/arm/mach-socfpga/spl_agilex.c | 2 +- arch/arm/mach-socfpga/spl_gen5.c | 2 +- arch/arm/mach-socfpga/spl_s10.c | 2 +- drivers/watchdog/designware_wdt.c | 4 ++-- arch/arm/include/asm/utils.h => include/log2.h | 4 ++-- 14 files changed, 16 insertions(+), 16 deletions(-) rename arch/arm/include/asm/utils.h => include/log2.h (93%) diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 99eb7db342..049a27cc92 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #define ARMV7_DCACHE_INVAL_RANGE 1 #define ARMV7_DCACHE_CLEAN_INVAL_RANGE 2 diff --git a/arch/arm/mach-davinci/spl.c b/arch/arm/mach-davinci/spl.c index be3daa9bc0..821324074c 100644 --- a/arch/arm/mach-davinci/spl.c +++ b/arch/arm/mach-davinci/spl.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c index 5932d694d3..7b91a39cdb 100644 --- a/arch/arm/mach-omap2/clocks-common.c +++ b/arch/arm/mach-omap2/clocks-common.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/emif-common.c b/arch/arm/mach-omap2/emif-common.c index 290f9dcdb0..758c2b3d11 100644 --- a/arch/arm/mach-omap2/emif-common.c +++ b/arch/arm/mach-omap2/emif-common.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap2/omap4/emif.c b/arch/arm/mach-omap2/omap4/emif.c index 35a51645be..d2b530535e 100644 --- a/arch/arm/mach-omap2/omap4/emif.c +++ b/arch/arm/mach-omap2/omap4/emif.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS u32 *const T_num = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_NUM; diff --git a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c index 9eda57c450..e541e729ef 100644 --- a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c +++ b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c @@ -7,7 +7,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/omap5/emif.c b/arch/arm/mach-omap2/omap5/emif.c index f3661a0e74..a5c74261c0 100644 --- a/arch/arm/mach-omap2/omap5/emif.c +++ b/arch/arm/mach-omap2/omap5/emif.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS #define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) diff --git a/arch/arm/mach-omap2/omap5/hwinit.c b/arch/arm/mach-omap2/omap5/hwinit.c index 56458ce495..ebd3b4903f 100644 --- a/arch/arm/mach-omap2/omap5/hwinit.c +++ b/arch/arm/mach-omap2/omap5/hwinit.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index 7c38c50981..a2b19e0f47 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-socfpga/spl_agilex.c b/arch/arm/mach-socfpga/spl_agilex.c index c745d64114..4e46d2bf5c 100644 --- a/arch/arm/mach-socfpga/spl_agilex.c +++ b/arch/arm/mach-socfpga/spl_agilex.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c index e19f55aa9b..48de2aceee 100644 --- a/arch/arm/mach-socfpga/spl_gen5.c +++ b/arch/arm/mach-socfpga/spl_gen5.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c index 8d96918cb4..44063b332a 100644 --- a/arch/arm/mach-socfpga/spl_s10.c +++ b/arch/arm/mach-socfpga/spl_s10.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index c668567c66..3b97db1256 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -4,9 +4,9 @@ */ #include -#include #include -#include +#include +#include #define DW_WDT_CR 0x00 #define DW_WDT_TORR 0x04 diff --git a/arch/arm/include/asm/utils.h b/include/log2.h similarity index 93% rename from arch/arm/include/asm/utils.h rename to include/log2.h index eee60c50e9..4f89d3dd76 100644 --- a/arch/arm/include/asm/utils.h +++ b/include/log2.h @@ -4,8 +4,8 @@ * Texas Instruments, * Aneesh V */ -#ifndef _UTILS_H_ -#define _UTILS_H_ +#ifndef _LOG2_H_ +#define _LOG2_H_ static inline s32 log_2_n_round_up(u32 n) { From patchwork Sun Feb 2 17:12:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 235776 List-Id: U-Boot discussion From: seanga2 at gmail.com (Sean Anderson) Date: Sun, 2 Feb 2020 12:12:57 -0500 Subject: [PATCH 3/4] wdt: Remove dependencies on CONFIG_DW_WDT_* from Designware WDT In-Reply-To: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> References: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> Message-ID: <36ff56bf-2cfa-2a1e-74c7-9c7111115780@gmail.com> Currently, the designware watchdog driver depends in several places on the values of CONFIG_DW_WDT_ defines. This patch moves these uses to just the functions hw_watchdog_*. Signed-off-by: Sean Anderson --- drivers/watchdog/designware_wdt.c | 65 ++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 3b97db1256..61c4046f50 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -17,57 +17,76 @@ #define DW_WDT_CR_RMOD_VAL 0x00 #define DW_WDT_CRR_RESTART_VAL 0x76 +struct designware_wdt_priv { + void __iomem *base; + ulong clock_khz; +}; + /* * Set the watchdog time interval. * Counter is 32 bit. */ -static int designware_wdt_settimeout(unsigned int timeout) +static int designware_wdt_settimeout(struct designware_wdt_priv *priv, + u64 timeout) { signed int i; /* calculate the timeout range value */ - i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16; + i = log_2_n_round_up(timeout * priv->clock_khz) - 16; if (i > 15) i = 15; if (i < 0) i = 0; - writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR)); + writel(i | (i << 4), priv->base + DW_WDT_TORR); return 0; } -static void designware_wdt_enable(void) +static void designware_wdt_enable(struct designware_wdt_priv *priv) { - writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) | - (0x1 << DW_WDT_CR_EN_OFFSET)), - (CONFIG_DW_WDT_BASE + DW_WDT_CR)); + writel((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) | + (0x1 << DW_WDT_CR_EN_OFFSET), priv->base + DW_WDT_CR); } -static unsigned int designware_wdt_is_enabled(void) +static unsigned int designware_wdt_is_enabled(struct designware_wdt_priv *priv) { unsigned long val; - val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR)); - return val & 0x1; + val = readl(priv->base + DW_WDT_CR); + return val & 1; } -#if defined(CONFIG_HW_WATCHDOG) +static void designware_wdt_reset(struct designware_wdt_priv *priv) +{ + if (designware_wdt_is_enabled(priv)) + writel(DW_WDT_CRR_RESTART_VAL, priv->base + DW_WDT_CRR); +} + +static void designware_wdt_init(struct designware_wdt_priv *priv, u64 timeout) +{ + /* reset to disable the watchdog */ + designware_wdt_reset(priv); + /* set timer in miliseconds */ + designware_wdt_settimeout(priv, timeout); + designware_wdt_enable(priv); + designware_wdt_reset(priv); +} + +#ifdef CONFIG_HW_WATCHDOG +static struct designware_wdt_priv wdt_priv = { + .base = CONFIG_DW_WDT_BASE, +}; + void hw_watchdog_reset(void) { - if (designware_wdt_is_enabled()) - /* restart the watchdog counter */ - writel(DW_WDT_CRR_RESTART_VAL, - (CONFIG_DW_WDT_BASE + DW_WDT_CRR)); + /* XXX: may contain a function call; must be done at runtime */ + wdt_priv.clock_khz = CONFIG_DW_WDT_CLOCK_KHZ; + designware_wdt_reset(&wdt_priv); } void hw_watchdog_init(void) { - /* reset to disable the watchdog */ - hw_watchdog_reset(); - /* set timer in miliseconds */ - designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); - /* enable the watchdog */ - designware_wdt_enable(); - /* reset the watchdog */ - hw_watchdog_reset(); + /* XXX: see above */ + wdt_priv.clock_khz = CONFIG_DW_WDT_CLOCK_KHZ; + designware_wdt_init(&wdt_priv, CONFIG_WATCHDOG_TIMEOUT_MSECS); } #endif From patchwork Sun Feb 2 17:13:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 235777 List-Id: U-Boot discussion From: seanga2 at gmail.com (Sean Anderson) Date: Sun, 2 Feb 2020 12:13:35 -0500 Subject: [PATCH 4/4] wdt: Add DM support for Designware WDT In-Reply-To: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> References: <9b2bb704-e7ea-74ea-c854-60a44472b8ec@gmail.com> Message-ID: <07f8931f-b143-e536-5e37-2096e8e88eba@gmail.com> The binding used is the same as Linux's. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- doc/device-tree-bindings/watchdog/dw_wdt.txt | 24 +++++++ drivers/watchdog/designware_wdt.c | 67 ++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 doc/device-tree-bindings/watchdog/dw_wdt.txt diff --git a/doc/device-tree-bindings/watchdog/dw_wdt.txt b/doc/device-tree-bindings/watchdog/dw_wdt.txt new file mode 100644 index 0000000000..eb0914420c --- /dev/null +++ b/doc/device-tree-bindings/watchdog/dw_wdt.txt @@ -0,0 +1,24 @@ +Synopsys Designware Watchdog Timer + +Required Properties: + +- compatible : Should contain "snps,dw-wdt" +- reg : Base address and size of the watchdog timer registers. +- clocks : phandle + clock-specifier for the clock that drives the + watchdog timer. + +Optional Properties: + +- interrupts : The interrupt used for the watchdog timeout warning. +- resets : phandle pointing to the system reset controller with + line index for the watchdog. + +Example: + + watchdog0: wd at ffd02000 { + compatible = "snps,dw-wdt"; + reg = <0xffd02000 0x1000>; + interrupts = <0 171 4>; + clocks = <&per_base_clk>; + resets = <&rst WDT0_RESET>; + }; diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 61c4046f50..1f7f4f0103 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -5,8 +5,10 @@ #include #include +#include #include #include +#include #define DW_WDT_CR 0x00 #define DW_WDT_TORR 0x04 @@ -90,3 +92,68 @@ void hw_watchdog_init(void) designware_wdt_init(&wdt_priv, CONFIG_WATCHDOG_TIMEOUT_MSECS); } #endif + +#ifdef CONFIG_WDT +static int dw_wdt_reset(struct udevice *dev) +{ + struct designware_wdt_priv *priv = dev_get_priv(dev); + + designware_wdt_reset(priv); + + return 0; +} + +static int dw_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct designware_wdt_priv *priv = dev_get_priv(dev); + + designware_wdt_init(priv, timeout); + + return 0; +} + +static int dw_wdt_probe(struct udevice *dev) +{ + int ret; + ulong rate; + struct clk clk; + struct designware_wdt_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -ENOENT; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + rate = clk_get_rate(&clk); + if (IS_ERR_VALUE(rate)) { + clk_free(&clk); + return rate; + } + priv->clock_khz = rate / 1000; + + return 0; +} + +static const struct wdt_ops dw_wdt_ops = { + .start = dw_wdt_start, + .reset = dw_wdt_reset, +}; + +static const struct udevice_id dw_wdt_ids[] = { + { .compatible = "snps,dw-wdt" }, + { }, +}; + +U_BOOT_DRIVER(designware_wdt) = { + .name = "designware_wdt", + .id = UCLASS_WDT, + .of_match = dw_wdt_ids, + .probe = dw_wdt_probe, + .ops = &dw_wdt_ops, + .priv_auto_alloc_size = sizeof(struct designware_wdt_priv), + .flags = DM_FLAG_PRE_RELOC, +}; +#endif /* WDT */