> > According to Server Base System Architecture (SBSA) specification, the > > SBSA Generic Watchdog has two stage timeouts: the first signal > > (WS0) is for alerting the system by interrupt, the second one (WS1) is > > a real hardware reset. > > More details about the hardware specification of this device: > > ARM DEN0029B - Server Base System Architecture (SBSA) > > > > This driver can operate ARM SBSA Generic Watchdog as a single stage In > > the single stage mode, when the timeout is reached, your system will > > be reset by WS1. The first signal (WS0) is ignored. > > > > Signed-off-by: Zhao Qiang <qiang.z...@nxp.com> > > Signed-off-by: Biwen Li <biwen...@nxp.com> > > --- > > Change in v2: > > - fix copyright > > > > MAINTAINERS | 1 + > > drivers/watchdog/Kconfig | 6 ++ > > drivers/watchdog/Makefile | 1 + > > drivers/watchdog/sbsa_gwdt.c | 131 > +++++++++++++++++++++++++++++++++++++++++++ > > 4 files changed, 139 insertions(+) > > create mode 100644 drivers/watchdog/sbsa_gwdt.c > > > > diff --git a/MAINTAINERS b/MAINTAINERS index 1fd975c..09554c0 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -685,6 +685,7 @@ M: Priyanka Jain <priyanka.j...@nxp.com> > > S: Maintained > > T: git > > https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq.git > > F: drivers/watchdog/sp805_wdt.c > > +F: drivers/watchdog/sbsa_gwdt.c > > > > I2C > > M: Heiko Schocher <h...@denx.de> > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index > > bf06180..191891c 100644 > > --- a/drivers/watchdog/Kconfig > > +++ b/drivers/watchdog/Kconfig > > @@ -163,6 +163,12 @@ config WDT_SANDBOX > > can be probed and supports all of the methods of WDT, but does not > > really do anything. > > > > +config WDT_SBSA > > + bool "SBSA watchdog timer support" > > + depends on WDT > > + help > > + Select this to enable SBSA watchdog timer. > > Please extend this help text a bit (add something from the commit text) to > make it more descriptive. Okay, it will be updated in v3. > > > + > > config WDT_SP805 > > bool "SP805 watchdog timer support" > > depends on WDT > > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > > index 519bbd3..0f0b2eb 100644 > > --- a/drivers/watchdog/Makefile > > +++ b/drivers/watchdog/Makefile > > @@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o > > obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o > > obj-$(CONFIG_WDT_MTK) += mtk_wdt.o > > obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o > > +obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o > > obj-$(CONFIG_WDT_SP805) += sp805_wdt.o > > obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o > > obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o diff --git > > a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c new file > > mode 100644 index 0000000..ddac668 > > --- /dev/null > > +++ b/drivers/watchdog/sbsa_gwdt.c > > @@ -0,0 +1,131 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Watchdog driver for SBSA > > + * > > + * Copyright 2020 NXP > > + */ > > + > > +#include <asm/io.h> > > +#include <common.h> > > +#include <dm/device.h> > > +#include <dm/fdtaddr.h> > > +#include <dm/read.h> > > +#include <linux/bitops.h> > > +#include <watchdog.h> > > +#include <wdt.h> > > + > > +DECLARE_GLOBAL_DATA_PTR; > > + > > +/* SBSA Generic Watchdog register definitions */ > > +/* refresh frame */ > > +#define SBSA_GWDT_WRR 0x000 > > + > > +/* control frame */ > > +#define SBSA_GWDT_WCS 0x000 > > +#define SBSA_GWDT_WOR 0x008 > > +#define SBSA_GWDT_WCV 0x010 > > + > > +/* refresh/control frame */ > > +#define SBSA_GWDT_W_IIDR 0xfcc > > +#define SBSA_GWDT_IDR 0xfd0 > > + > > +/* Watchdog Control and Status Register */ > > +#define SBSA_GWDT_WCS_EN BIT(0) > > +#define SBSA_GWDT_WCS_WS0 BIT(1) > > +#define SBSA_GWDT_WCS_WS1 BIT(2) > > + > > +struct sbsa_gwdt_priv { > > + void __iomem *reg_refresh; > > + void __iomem *reg_control; > > +}; > > + > > +static int sbsa_gwdt_reset(struct udevice *dev) { > > + struct sbsa_gwdt_priv *priv = dev_get_priv(dev); > > + > > + writel(0, priv->reg_refresh + SBSA_GWDT_WRR); > > + > > + return 0; > > +} > > + > > +static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong > > +flags) { > > + u32 clk; > > + u32 load_value; > > + > > + struct sbsa_gwdt_priv *priv = dev_get_priv(dev); > > Nitpicking: > > Remove empty line above and add sone below the variable declarations > (reverse x-max tree is preferred): > > struct sbsa_gwdt_priv *priv = dev_get_priv(dev); > u32 load_value; > u32 clk; Okay, it will be updated in v3. > > Other than that: > > Reviewed-by: Stefan Roese <s...@denx.de> > Okay, got it.
> Thanks, > Stefan > > > + /* > > + * it work in the single stage mode in u-boot, > > + * The first signal (WS0) is ignored, > > + * the timeout is (WOR * 2), so the WOR should be configured > > + * to half value of timeout. > > + */ > > + clk = get_tbclk(); > > + writel(clk / 2 * timeout, > > + priv->reg_control + SBSA_GWDT_WOR); > > + > > + /* writing WCS will cause an explicit watchdog refresh */ > > + writel(SBSA_GWDT_WCS_EN, priv->reg_control + SBSA_GWDT_WCS); > > + > > + return 0; > > +} > > + > > +static int sbsa_gwdt_stop(struct udevice *dev) { > > + struct sbsa_gwdt_priv *priv = dev_get_priv(dev); > > + > > + writel(0, priv->reg_control + SBSA_GWDT_WCS); > > + > > + return 0; > > +} > > + > > +static int sbsa_gwdt_expire_now(struct udevice *dev, ulong flags) { > > + sbsa_gwdt_start(dev, 0, flags); > > + > > + return 0; > > +} > > + > > +static int sbsa_gwdt_probe(struct udevice *dev) { > > + debug("%s: Probing wdt%u (sbsa-gwdt)\n", __func__, dev->seq); > > + > > + return 0; > > +} > > + > > +static int sbsa_gwdt_ofdata_to_platdata(struct udevice *dev) { > > + struct sbsa_gwdt_priv *priv = dev_get_priv(dev); > > + > > + priv->reg_control = (void __iomem *)dev_read_addr_index(dev, 0); > > + if (IS_ERR(priv->reg_control)) > > + return PTR_ERR(priv->reg_control); > > + > > + priv->reg_refresh = (void __iomem *)dev_read_addr_index(dev, 1); > > + if (IS_ERR(priv->reg_refresh)) > > + return PTR_ERR(priv->reg_refresh); > > + > > + return 0; > > +} > > + > > +static const struct wdt_ops sbsa_gwdt_ops = { > > + .start = sbsa_gwdt_start, > > + .reset = sbsa_gwdt_reset, > > + .stop = sbsa_gwdt_stop, > > + .expire_now = sbsa_gwdt_expire_now, > > +}; > > + > > +static const struct udevice_id sbsa_gwdt_ids[] = { > > + { .compatible = "arm,sbsa-gwdt" }, > > + {} > > +}; > > + > > +U_BOOT_DRIVER(sbsa_gwdt) = { > > + .name = "sbsa_gwdt", > > + .id = UCLASS_WDT, > > + .of_match = sbsa_gwdt_ids, > > + .probe = sbsa_gwdt_probe, > > + .priv_auto_alloc_size = sizeof(struct sbsa_gwdt_priv), > > + .ofdata_to_platdata = sbsa_gwdt_ofdata_to_platdata, > > + .ops = &sbsa_gwdt_ops, > > +}; > > > > > Viele Grüße, > Stefan > > -- > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: s...@denx.de