[U-Boot] [PATCH 0/4] Add watchdog support for STM32MP1

This series: - sorts Kconfig entries in alphabetical order - enable watchdog support in SPL for STM32MP1 - adds watchdog support to STM32MP1 boards
Patrice Chotard (4): watchdog: Kconfig: Sort entry alphabetically ARM: dts: stm32mp: Add iwdg2 support for stm32mp157c watchdog: stm32mp: Add watchdog driver configs: stm32mp15: Enable WDT flags
MAINTAINERS | 1 + arch/arm/dts/stm32mp157-u-boot.dtsi | 4 ++ arch/arm/mach-stm32mp/Kconfig | 1 + configs/stm32mp15_basic_defconfig | 2 + configs/stm32mp15_trusted_defconfig | 2 + drivers/watchdog/Kconfig | 91 +++++++++++++----------- drivers/watchdog/Makefile | 1 + drivers/watchdog/stm32mp_wdt.c | 135 ++++++++++++++++++++++++++++++++++++ 8 files changed, 196 insertions(+), 41 deletions(-) create mode 100644 drivers/watchdog/stm32mp_wdt.c

To make adding new entry easier, sort Kconfig entries in alphabetical order.
Signed-off-by: Patrice Chotard patrice.chotard@st.com ---
drivers/watchdog/Kconfig | 87 ++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3bce0aa..4a3ff7a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -26,6 +26,13 @@ config BCM2835_WDT This provides basic infrastructure to support BCM2835/2836 watchdog hardware, with a max timeout of ~15secs.
+config IMX_WATCHDOG + bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP" + select HW_WATCHDOG + help + Select this to enable the IMX and LSCH2 of Layerscape watchdog + driver. + config OMAP_WATCHDOG bool "TI OMAP watchdog driver" depends on ARCH_OMAP2PLUS @@ -59,14 +66,6 @@ config WDT What exactly happens when the timer expires is up to a particular device/driver.
-config WDT_SANDBOX - bool "Enable Watchdog Timer support for Sandbox" - depends on SANDBOX && WDT - help - Enable Watchdog Timer support in Sandbox. This is a dummy device that - can be probed and supports all of the methods of WDT, but does not - really do anything. - config WDT_ARMADA_37XX bool "Marvell Armada 37xx watchdog timer support" depends on WDT && ARMADA_3700 @@ -87,6 +86,13 @@ config WDT_ASPEED It currently does not support Boot Flash Addressing Mode Detection or Second Boot.
+config WDT_AT91 + bool "AT91 watchdog timer support" + depends on WDT + help + Select this to enable Microchip watchdog timer, which can be found on + some AT91 devices. + config WDT_BCM6345 bool "BCM6345 watchdog timer support" depends on WDT && (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158) @@ -95,14 +101,6 @@ config WDT_BCM6345 The watchdog timer is stopped when initialized. It performs full SoC reset.
-config WDT_ORION - bool "Orion watchdog timer support" - depends on WDT - select CLK - help - Select this to enable Orion watchdog timer, which can be found on some - Marvell Armada chips. - config WDT_CDNS bool "Cadence watchdog timer support" depends on WDT @@ -111,6 +109,20 @@ config WDT_CDNS Select this to enable Cadence watchdog timer, which can be found on some Xilinx Microzed Platform.
+config WDT_MPC8xx + bool "MPC8xx watchdog timer support" + depends on WDT && MPC8xx + select CONFIG_MPC8xx_WATCHDOG + help + Select this to enable mpc8xx watchdog timer + +config WDT_MT7621 + bool "MediaTek MT7621 watchdog timer support" + depends on WDT && ARCH_MT7620 + help + Select this to enable Ralink / Mediatek watchdog timer, + which can be found on some MediaTek chips. + config WDT_MTK bool "MediaTek watchdog timer support" depends on WDT && ARCH_MEDIATEK @@ -119,39 +131,28 @@ config WDT_MTK The watchdog timer is stopped when initialized. It performs full SoC reset.
-config XILINX_TB_WATCHDOG - bool "Xilinx Axi watchdog timer support" +config WDT_ORION + bool "Orion watchdog timer support" depends on WDT - imply WATCHDOG + select CLK help - Select this to enable Xilinx Axi watchdog timer, which can be found on some - Xilinx Microblaze Platforms. + Select this to enable Orion watchdog timer, which can be found on some + Marvell Armada chips.
-config IMX_WATCHDOG - bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP" - select HW_WATCHDOG +config WDT_SANDBOX + bool "Enable Watchdog Timer support for Sandbox" + depends on SANDBOX && WDT help - Select this to enable the IMX and LSCH2 of Layerscape watchdog - driver. + Enable Watchdog Timer support in Sandbox. This is a dummy device that + can be probed and supports all of the methods of WDT, but does not + really do anything.
-config WDT_AT91 - bool "AT91 watchdog timer support" +config XILINX_TB_WATCHDOG + bool "Xilinx Axi watchdog timer support" depends on WDT + imply WATCHDOG help - Select this to enable Microchip watchdog timer, which can be found on - some AT91 devices. - -config WDT_MT7621 - bool "MediaTek MT7621 watchdog timer support" - depends on WDT && ARCH_MT7620 - help - Select this to enable Ralink / Mediatek watchdog timer, - which can be found on some MediaTek chips. - -config WDT_MPC8xx - bool "MPC8xx watchdog timer support" - depends on WDT && MPC8xx - help - Select this to enable mpc8xx watchdog timer + Select this to enable Xilinx Axi watchdog timer, which can be found on some + Xilinx Microblaze Platforms.
endmenu

On 29.04.19 11:23, Patrice Chotard wrote:
To make adding new entry easier, sort Kconfig entries in alphabetical order.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/watchdog/Kconfig | 87 ++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3bce0aa..4a3ff7a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -26,6 +26,13 @@ config BCM2835_WDT This provides basic infrastructure to support BCM2835/2836 watchdog hardware, with a max timeout of ~15secs.
+config IMX_WATCHDOG
- bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP"
- select HW_WATCHDOG
- help
Select this to enable the IMX and LSCH2 of Layerscape watchdog
driver.
- config OMAP_WATCHDOG bool "TI OMAP watchdog driver" depends on ARCH_OMAP2PLUS
@@ -59,14 +66,6 @@ config WDT What exactly happens when the timer expires is up to a particular device/driver.
-config WDT_SANDBOX
- bool "Enable Watchdog Timer support for Sandbox"
- depends on SANDBOX && WDT
- help
Enable Watchdog Timer support in Sandbox. This is a dummy device that
can be probed and supports all of the methods of WDT, but does not
really do anything.
- config WDT_ARMADA_37XX bool "Marvell Armada 37xx watchdog timer support" depends on WDT && ARMADA_3700
@@ -87,6 +86,13 @@ config WDT_ASPEED It currently does not support Boot Flash Addressing Mode Detection or Second Boot.
+config WDT_AT91
- bool "AT91 watchdog timer support"
- depends on WDT
- help
Select this to enable Microchip watchdog timer, which can be found on
some AT91 devices.
- config WDT_BCM6345 bool "BCM6345 watchdog timer support" depends on WDT && (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158)
@@ -95,14 +101,6 @@ config WDT_BCM6345 The watchdog timer is stopped when initialized. It performs full SoC reset.
-config WDT_ORION
- bool "Orion watchdog timer support"
- depends on WDT
- select CLK
- help
Select this to enable Orion watchdog timer, which can be found on some
Marvell Armada chips.
- config WDT_CDNS bool "Cadence watchdog timer support" depends on WDT
@@ -111,6 +109,20 @@ config WDT_CDNS Select this to enable Cadence watchdog timer, which can be found on some Xilinx Microzed Platform.
+config WDT_MPC8xx
- bool "MPC8xx watchdog timer support"
- depends on WDT && MPC8xx
- select CONFIG_MPC8xx_WATCHDOG
- help
Select this to enable mpc8xx watchdog timer
+config WDT_MT7621
- bool "MediaTek MT7621 watchdog timer support"
- depends on WDT && ARCH_MT7620
- help
Select this to enable Ralink / Mediatek watchdog timer,
which can be found on some MediaTek chips.
- config WDT_MTK bool "MediaTek watchdog timer support" depends on WDT && ARCH_MEDIATEK
@@ -119,39 +131,28 @@ config WDT_MTK The watchdog timer is stopped when initialized. It performs full SoC reset.
-config XILINX_TB_WATCHDOG
- bool "Xilinx Axi watchdog timer support"
+config WDT_ORION
- bool "Orion watchdog timer support" depends on WDT
- imply WATCHDOG
- select CLK help
Select this to enable Xilinx Axi watchdog timer, which can be found on some
Xilinx Microblaze Platforms.
Select this to enable Orion watchdog timer, which can be found on some
Marvell Armada chips.
-config IMX_WATCHDOG
- bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP"
- select HW_WATCHDOG
+config WDT_SANDBOX
- bool "Enable Watchdog Timer support for Sandbox"
- depends on SANDBOX && WDT help
Select this to enable the IMX and LSCH2 of Layerscape watchdog
driver.
Enable Watchdog Timer support in Sandbox. This is a dummy device that
can be probed and supports all of the methods of WDT, but does not
really do anything.
-config WDT_AT91
- bool "AT91 watchdog timer support"
+config XILINX_TB_WATCHDOG
- bool "Xilinx Axi watchdog timer support" depends on WDT
- imply WATCHDOG help
Select this to enable Microchip watchdog timer, which can be found on
some AT91 devices.
-config WDT_MT7621
- bool "MediaTek MT7621 watchdog timer support"
- depends on WDT && ARCH_MT7620
- help
Select this to enable Ralink / Mediatek watchdog timer,
which can be found on some MediaTek chips.
-config WDT_MPC8xx
- bool "MPC8xx watchdog timer support"
- depends on WDT && MPC8xx
- help
Select this to enable mpc8xx watchdog timer
Select this to enable Xilinx Axi watchdog timer, which can be found on some
Xilinx Microblaze Platforms.
endmenu
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

This patch adds independent watchdog support for stm32mp157c in SPL.
Signed-off-by: Patrice Chotard patrice.chotard@st.com ---
arch/arm/dts/stm32mp157-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi index ab6f673..09560e2 100644 --- a/arch/arm/dts/stm32mp157-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157-u-boot.dtsi @@ -140,3 +140,7 @@ compatible = "st,stm32-gpio"; u-boot,dm-pre-reloc; }; + +&iwdg2 { + u-boot,dm-pre-reloc; +};

On Mon, 29 Apr 2019 at 03:23, Patrice Chotard patrice.chotard@st.com wrote:
This patch adds independent watchdog support for stm32mp157c in SPL.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/dts/stm32mp157-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

This patch adds IWDG (Independent WatchDoG) support for STM32MP platform.
Signed-off-by: Christophe Kerello christophe.kerello@st.com Signed-off-by: Patrice Chotard patrice.chotard@st.com ---
MAINTAINERS | 1 + arch/arm/mach-stm32mp/Kconfig | 1 + drivers/watchdog/Kconfig | 8 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/stm32mp_wdt.c | 135 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+) create mode 100644 drivers/watchdog/stm32mp_wdt.c
diff --git a/MAINTAINERS b/MAINTAINERS index 09f31cd..eec2603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -311,6 +311,7 @@ F: drivers/ram/stm32mp1/ F: drivers/misc/stm32_rcc.c F: drivers/reset/stm32-reset.c F: drivers/spi/stm32_qspi.c +F: drivers/watchdog/stm32mp_wdt.c
ARM STM STV0991 M: Vikas Manocha vikas.manocha@st.com diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 73aa382..4e7cc2e 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -17,6 +17,7 @@ config SPL select SPL_DM_RESET select SPL_SERIAL_SUPPORT select SPL_SYSCON + select SPL_WATCHDOG_SUPPORT imply SPL_DISPLAY_PRINT imply SPL_LIBDISK_SUPPORT
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4a3ff7a..d582abe 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -147,6 +147,14 @@ config WDT_SANDBOX can be probed and supports all of the methods of WDT, but does not really do anything.
+config WDT_STM32MP + bool "IWDG watchdog driver for STM32 MP's family" + depends on WDT + imply WATCHDOG + help + Enable the STM32 watchdog (IWDG) driver. Enable support to + configure STM32's on-SoC watchdog. + config XILINX_TB_WATCHDOG bool "Xilinx Axi watchdog timer support" depends on WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 40b2f4b..a3ebff8 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o obj-$(CONFIG_WDT_MTK) += mtk_wdt.o +obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c new file mode 100644 index 0000000..82db2c6 --- /dev/null +++ b/drivers/watchdog/stm32mp_wdt.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <syscon.h> +#include <wdt.h> +#include <asm/io.h> +#include <linux/iopoll.h> + +/* IWDG registers */ +#define IWDG_KR 0x00 /* Key register */ +#define IWDG_PR 0x04 /* Prescaler Register */ +#define IWDG_RLR 0x08 /* ReLoad Register */ +#define IWDG_SR 0x0C /* Status Register */ + +/* IWDG_KR register bit mask */ +#define KR_KEY_RELOAD 0xAAAA /* Reload counter enable */ +#define KR_KEY_ENABLE 0xCCCC /* Peripheral enable */ +#define KR_KEY_EWA 0x5555 /* Write access enable */ + +/* IWDG_PR register bit values */ +#define PR_256 0x06 /* Prescaler set to 256 */ + +/* IWDG_RLR register values */ +#define RLR_MAX 0xFFF /* Max value supported by reload register */ + +/* IWDG_SR register bit values */ +#define SR_PVU BIT(0) /* Watchdog prescaler value update */ +#define SR_RVU BIT(1) /* Watchdog counter reload value update */ + +struct stm32mp_wdt_priv { + fdt_addr_t base; /* registers addr in physical memory */ + unsigned long wdt_clk_rate; /* Watchdog dedicated clock rate */ +}; + +static int stm32mp_wdt_reset(struct udevice *dev) +{ + struct stm32mp_wdt_priv *priv = dev_get_priv(dev); + + writel(KR_KEY_RELOAD, priv->base + IWDG_KR); + + return 0; +} + +static int stm32mp_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct stm32mp_wdt_priv *priv = dev_get_priv(dev); + int reload; + u32 val; + int ret; + + /* Prescaler fixed to 256 */ + reload = timeout * priv->wdt_clk_rate / 256; + if (reload > RLR_MAX + 1) + /* Force to max watchdog counter reload value */ + reload = RLR_MAX + 1; + else if (!reload) + /* Force to min watchdog counter reload value */ + reload = priv->wdt_clk_rate / 256; + + /* Set prescaler & reload registers */ + writel(KR_KEY_EWA, priv->base + IWDG_KR); + writel(PR_256, priv->base + IWDG_PR); + writel(reload - 1, priv->base + IWDG_RLR); + + /* Enable watchdog */ + writel(KR_KEY_ENABLE, priv->base + IWDG_KR); + + /* Wait for the registers to be updated */ + ret = readl_poll_timeout(priv->base + IWDG_SR, val, + val & (SR_PVU | SR_RVU), CONFIG_SYS_HZ); + + if (ret < 0) { + pr_err("Updating IWDG registers timeout"); + return -ETIMEDOUT; + } + + return 0; +} + +static int stm32mp_wdt_probe(struct udevice *dev) +{ + struct stm32mp_wdt_priv *priv = dev_get_priv(dev); + struct clk clk; + int ret; + + debug("IWDG init\n"); + + priv->base = devfdt_get_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Enable clock */ + ret = clk_get_by_name(dev, "pclk", &clk); + if (ret) + return ret; + + ret = clk_enable(&clk); + if (ret) + return ret; + + /* Get LSI clock */ + ret = clk_get_by_name(dev, "lsi", &clk); + if (ret) + return ret; + + priv->wdt_clk_rate = clk_get_rate(&clk); + + debug("IWDG init done\n"); + + return 0; +} + +static const struct wdt_ops stm32mp_wdt_ops = { + .start = stm32mp_wdt_start, + .reset = stm32mp_wdt_reset, +}; + +static const struct udevice_id stm32mp_wdt_match[] = { + { .compatible = "st,stm32mp1-iwdg" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(stm32mp_wdt) = { + .name = "stm32mp-wdt", + .id = UCLASS_WDT, + .of_match = stm32mp_wdt_match, + .priv_auto_alloc_size = sizeof(struct stm32mp_wdt_priv), + .probe = stm32mp_wdt_probe, + .ops = &stm32mp_wdt_ops, +};

On 29.04.19 11:23, Patrice Chotard wrote:
This patch adds IWDG (Independent WatchDoG) support for STM32MP platform.
Signed-off-by: Christophe Kerello christophe.kerello@st.com Signed-off-by: Patrice Chotard patrice.chotard@st.com
MAINTAINERS | 1 + arch/arm/mach-stm32mp/Kconfig | 1 + drivers/watchdog/Kconfig | 8 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/stm32mp_wdt.c | 135 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+) create mode 100644 drivers/watchdog/stm32mp_wdt.c
diff --git a/MAINTAINERS b/MAINTAINERS index 09f31cd..eec2603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -311,6 +311,7 @@ F: drivers/ram/stm32mp1/ F: drivers/misc/stm32_rcc.c F: drivers/reset/stm32-reset.c F: drivers/spi/stm32_qspi.c +F: drivers/watchdog/stm32mp_wdt.c
ARM STM STV0991 M: Vikas Manocha vikas.manocha@st.com diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 73aa382..4e7cc2e 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -17,6 +17,7 @@ config SPL select SPL_DM_RESET select SPL_SERIAL_SUPPORT select SPL_SYSCON
- select SPL_WATCHDOG_SUPPORT imply SPL_DISPLAY_PRINT imply SPL_LIBDISK_SUPPORT
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4a3ff7a..d582abe 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -147,6 +147,14 @@ config WDT_SANDBOX can be probed and supports all of the methods of WDT, but does not really do anything.
+config WDT_STM32MP
- bool "IWDG watchdog driver for STM32 MP's family"
- depends on WDT
- imply WATCHDOG
- help
Enable the STM32 watchdog (IWDG) driver. Enable support to
configure STM32's on-SoC watchdog.
- config XILINX_TB_WATCHDOG bool "Xilinx Axi watchdog timer support" depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 40b2f4b..a3ebff8 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o obj-$(CONFIG_WDT_MTK) += mtk_wdt.o +obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c new file mode 100644 index 0000000..82db2c6 --- /dev/null +++ b/drivers/watchdog/stm32mp_wdt.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/*
- Copyright (C) 2019, STMicroelectronics - All Rights Reserved
- */
+#include <common.h> +#include <clk.h> +#include <dm.h> +#include <syscon.h> +#include <wdt.h> +#include <asm/io.h> +#include <linux/iopoll.h>
+/* IWDG registers */ +#define IWDG_KR 0x00 /* Key register */ +#define IWDG_PR 0x04 /* Prescaler Register */ +#define IWDG_RLR 0x08 /* ReLoad Register */ +#define IWDG_SR 0x0C /* Status Register */
+/* IWDG_KR register bit mask */ +#define KR_KEY_RELOAD 0xAAAA /* Reload counter enable */ +#define KR_KEY_ENABLE 0xCCCC /* Peripheral enable */ +#define KR_KEY_EWA 0x5555 /* Write access enable */
+/* IWDG_PR register bit values */ +#define PR_256 0x06 /* Prescaler set to 256 */
+/* IWDG_RLR register values */ +#define RLR_MAX 0xFFF /* Max value supported by reload register */
+/* IWDG_SR register bit values */ +#define SR_PVU BIT(0) /* Watchdog prescaler value update */ +#define SR_RVU BIT(1) /* Watchdog counter reload value update */
+struct stm32mp_wdt_priv {
- fdt_addr_t base; /* registers addr in physical memory */
- unsigned long wdt_clk_rate; /* Watchdog dedicated clock rate */
+};
+static int stm32mp_wdt_reset(struct udevice *dev) +{
- struct stm32mp_wdt_priv *priv = dev_get_priv(dev);
- writel(KR_KEY_RELOAD, priv->base + IWDG_KR);
- return 0;
+}
+static int stm32mp_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
s/timeout/timeout_ms (see below).
+{
- struct stm32mp_wdt_priv *priv = dev_get_priv(dev);
- int reload;
- u32 val;
- int ret;
- /* Prescaler fixed to 256 */
- reload = timeout * priv->wdt_clk_rate / 256;
Just checking, if this takes into account that timeout is passed in ms (milli-seconds) to the DM wdt_start() function. That's why I prefer to see timeout explicitly named to "timeout_ms" instead.
Thanks, Stefan
- if (reload > RLR_MAX + 1)
/* Force to max watchdog counter reload value */
reload = RLR_MAX + 1;
- else if (!reload)
/* Force to min watchdog counter reload value */
reload = priv->wdt_clk_rate / 256;
- /* Set prescaler & reload registers */
- writel(KR_KEY_EWA, priv->base + IWDG_KR);
- writel(PR_256, priv->base + IWDG_PR);
- writel(reload - 1, priv->base + IWDG_RLR);
- /* Enable watchdog */
- writel(KR_KEY_ENABLE, priv->base + IWDG_KR);
- /* Wait for the registers to be updated */
- ret = readl_poll_timeout(priv->base + IWDG_SR, val,
val & (SR_PVU | SR_RVU), CONFIG_SYS_HZ);
- if (ret < 0) {
pr_err("Updating IWDG registers timeout");
return -ETIMEDOUT;
- }
- return 0;
+}
+static int stm32mp_wdt_probe(struct udevice *dev) +{
- struct stm32mp_wdt_priv *priv = dev_get_priv(dev);
- struct clk clk;
- int ret;
- debug("IWDG init\n");
- priv->base = devfdt_get_addr(dev);
- if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
- /* Enable clock */
- ret = clk_get_by_name(dev, "pclk", &clk);
- if (ret)
return ret;
- ret = clk_enable(&clk);
- if (ret)
return ret;
- /* Get LSI clock */
- ret = clk_get_by_name(dev, "lsi", &clk);
- if (ret)
return ret;
- priv->wdt_clk_rate = clk_get_rate(&clk);
- debug("IWDG init done\n");
- return 0;
+}
+static const struct wdt_ops stm32mp_wdt_ops = {
- .start = stm32mp_wdt_start,
- .reset = stm32mp_wdt_reset,
+};
+static const struct udevice_id stm32mp_wdt_match[] = {
- { .compatible = "st,stm32mp1-iwdg" },
- { /* sentinel */ }
+};
+U_BOOT_DRIVER(stm32mp_wdt) = {
- .name = "stm32mp-wdt",
- .id = UCLASS_WDT,
- .of_match = stm32mp_wdt_match,
- .priv_auto_alloc_size = sizeof(struct stm32mp_wdt_priv),
- .probe = stm32mp_wdt_probe,
- .ops = &stm32mp_wdt_ops,
+};
Viele Grüße, Stefan

Hi Stefan
On 4/29/19 11:43 AM, Stefan Roese wrote:
On 29.04.19 11:23, Patrice Chotard wrote:
This patch adds IWDG (Independent WatchDoG) support for STM32MP platform.
Signed-off-by: Christophe Kerello christophe.kerello@st.com Signed-off-by: Patrice Chotard patrice.chotard@st.com
MAINTAINERS | 1 + arch/arm/mach-stm32mp/Kconfig | 1 + drivers/watchdog/Kconfig | 8 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/stm32mp_wdt.c | 135 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+) create mode 100644 drivers/watchdog/stm32mp_wdt.c
diff --git a/MAINTAINERS b/MAINTAINERS index 09f31cd..eec2603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -311,6 +311,7 @@ F: drivers/ram/stm32mp1/ F: drivers/misc/stm32_rcc.c F: drivers/reset/stm32-reset.c F: drivers/spi/stm32_qspi.c +F: drivers/watchdog/stm32mp_wdt.c ARM STM STV0991 M: Vikas Manocha vikas.manocha@st.com diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 73aa382..4e7cc2e 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -17,6 +17,7 @@ config SPL select SPL_DM_RESET select SPL_SERIAL_SUPPORT select SPL_SYSCON + select SPL_WATCHDOG_SUPPORT imply SPL_DISPLAY_PRINT imply SPL_LIBDISK_SUPPORT diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4a3ff7a..d582abe 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -147,6 +147,14 @@ config WDT_SANDBOX can be probed and supports all of the methods of WDT, but does not really do anything. +config WDT_STM32MP + bool "IWDG watchdog driver for STM32 MP's family" + depends on WDT + imply WATCHDOG + help + Enable the STM32 watchdog (IWDG) driver. Enable support to + configure STM32's on-SoC watchdog.
config XILINX_TB_WATCHDOG bool "Xilinx Axi watchdog timer support" depends on WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 40b2f4b..a3ebff8 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o obj-$(CONFIG_WDT_MTK) += mtk_wdt.o +obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c new file mode 100644 index 0000000..82db2c6 --- /dev/null +++ b/drivers/watchdog/stm32mp_wdt.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/*
- Copyright (C) 2019, STMicroelectronics - All Rights Reserved
- */
+#include <common.h> +#include <clk.h> +#include <dm.h> +#include <syscon.h> +#include <wdt.h> +#include <asm/io.h> +#include <linux/iopoll.h>
+/* IWDG registers */ +#define IWDG_KR 0x00 /* Key register */ +#define IWDG_PR 0x04 /* Prescaler Register */ +#define IWDG_RLR 0x08 /* ReLoad Register */ +#define IWDG_SR 0x0C /* Status Register */
+/* IWDG_KR register bit mask */ +#define KR_KEY_RELOAD 0xAAAA /* Reload counter enable */ +#define KR_KEY_ENABLE 0xCCCC /* Peripheral enable */ +#define KR_KEY_EWA 0x5555 /* Write access enable */
+/* IWDG_PR register bit values */ +#define PR_256 0x06 /* Prescaler set to 256 */
+/* IWDG_RLR register values */ +#define RLR_MAX 0xFFF /* Max value supported by reload register */
+/* IWDG_SR register bit values */ +#define SR_PVU BIT(0) /* Watchdog prescaler value update */ +#define SR_RVU BIT(1) /* Watchdog counter reload value update */
+struct stm32mp_wdt_priv { + fdt_addr_t base; /* registers addr in physical memory */ + unsigned long wdt_clk_rate; /* Watchdog dedicated clock rate */ +};
+static int stm32mp_wdt_reset(struct udevice *dev) +{ + struct stm32mp_wdt_priv *priv = dev_get_priv(dev);
+ writel(KR_KEY_RELOAD, priv->base + IWDG_KR);
+ return 0; +}
+static int stm32mp_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
s/timeout/timeout_ms (see below).
+{ + struct stm32mp_wdt_priv *priv = dev_get_priv(dev); + int reload; + u32 val; + int ret;
+ /* Prescaler fixed to 256 */ + reload = timeout * priv->wdt_clk_rate / 256;
Just checking, if this takes into account that timeout is passed in ms (milli-seconds) to the DM wdt_start() function. That's why I prefer to see timeout explicitly named to "timeout_ms" instead.
Ok, no problem, i will update and re-spin this series.
Thanks
Thanks, Stefan
+ if (reload > RLR_MAX + 1) + /* Force to max watchdog counter reload value */ + reload = RLR_MAX + 1; + else if (!reload) + /* Force to min watchdog counter reload value */ + reload = priv->wdt_clk_rate / 256;
+ /* Set prescaler & reload registers */ + writel(KR_KEY_EWA, priv->base + IWDG_KR); + writel(PR_256, priv->base + IWDG_PR); + writel(reload - 1, priv->base + IWDG_RLR);
+ /* Enable watchdog */ + writel(KR_KEY_ENABLE, priv->base + IWDG_KR);
+ /* Wait for the registers to be updated */ + ret = readl_poll_timeout(priv->base + IWDG_SR, val, + val & (SR_PVU | SR_RVU), CONFIG_SYS_HZ);
+ if (ret < 0) { + pr_err("Updating IWDG registers timeout"); + return -ETIMEDOUT; + }
+ return 0; +}
+static int stm32mp_wdt_probe(struct udevice *dev) +{ + struct stm32mp_wdt_priv *priv = dev_get_priv(dev); + struct clk clk; + int ret;
+ debug("IWDG init\n");
+ priv->base = devfdt_get_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL;
+ /* Enable clock */ + ret = clk_get_by_name(dev, "pclk", &clk); + if (ret) + return ret;
+ ret = clk_enable(&clk); + if (ret) + return ret;
+ /* Get LSI clock */ + ret = clk_get_by_name(dev, "lsi", &clk); + if (ret) + return ret;
+ priv->wdt_clk_rate = clk_get_rate(&clk);
+ debug("IWDG init done\n");
+ return 0; +}
+static const struct wdt_ops stm32mp_wdt_ops = { + .start = stm32mp_wdt_start, + .reset = stm32mp_wdt_reset, +};
+static const struct udevice_id stm32mp_wdt_match[] = { + { .compatible = "st,stm32mp1-iwdg" }, + { /* sentinel */ } +};
+U_BOOT_DRIVER(stm32mp_wdt) = { + .name = "stm32mp-wdt", + .id = UCLASS_WDT, + .of_match = stm32mp_wdt_match, + .priv_auto_alloc_size = sizeof(struct stm32mp_wdt_priv), + .probe = stm32mp_wdt_probe, + .ops = &stm32mp_wdt_ops, +};
Viele Grüße, Stefan

This allows to enable WATCHDOG and WDT flags to be able to reset the watchdog and to support watchdog driver model.
Signed-off-by: Patrice Chotard patrice.chotard@st.com ---
configs/stm32mp15_basic_defconfig | 2 ++ configs/stm32mp15_trusted_defconfig | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index fd164fa..7252c14 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -77,3 +77,5 @@ CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" CONFIG_USB_GADGET_VENDOR_NUM=0x0483 CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_WDT=y +CONFIG_WDT_STM32MP=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index f82b770..52ee280 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -68,3 +68,5 @@ CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" CONFIG_USB_GADGET_VENDOR_NUM=0x0483 CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_WDT=y +CONFIG_WDT_STM32MP=y
participants (4)
-
Patrice CHOTARD
-
Patrice Chotard
-
Simon Glass
-
Stefan Roese