From: Stefan Roese Date: Thu, 4 Oct 2018 11:39:07 +0000 (+0200) Subject: wdt: Add MT7621 watchdog driver X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=053fce84c1505b1dac1ab75e2c4666bb36437514;p=u-boot.git wdt: Add MT7621 watchdog driver This patch adds watchdog support for the Mediatek MT7621 SoC. The driver is loosly based on the Linux kernel version. Signed-off-by: Stefan Roese Cc: Daniel Schwierzeck Reviewed-by: Daniel Schwierzeck [fixed merge conflict in drivers/watchdog/Kconfig] Signed-off-by: Daniel Schwierzeck --- diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index a911dba73a..4796da0823 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -128,4 +128,12 @@ config WDT_AT91 config AT91_HW_WDT_TIMEOUT bool "AT91 watchdog timeout specified" depends on WDT_AT91 + +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. + endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index a5c27b0f4c..b8f2842f7e 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o +obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c new file mode 100644 index 0000000000..38866141e4 --- /dev/null +++ b/drivers/watchdog/mt7621_wdt.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Ralink / Mediatek RT288x/RT3xxx/MT76xx built-in hardware watchdog timer + * + * Copyright (C) 2018 Stefan Roese + * + * Based on the Linux driver version which is: + * Copyright (C) 2011 Gabor Juhos + * Copyright (C) 2013 John Crispin + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct mt762x_wdt { + void __iomem *regs; +}; + +#define TIMER_REG_TMRSTAT 0x00 +#define TIMER_REG_TMR1CTL 0x20 +#define TIMER_REG_TMR1LOAD 0x24 + +#define TMR1CTL_ENABLE BIT(7) +#define TMR1CTL_RESTART BIT(9) +#define TMR1CTL_PRESCALE_SHIFT 16 + +static int mt762x_wdt_ping(struct mt762x_wdt *priv) +{ + writel(TMR1CTL_RESTART, priv->regs + TIMER_REG_TMRSTAT); + + return 0; +} + +static int mt762x_wdt_start(struct udevice *dev, u64 ms, ulong flags) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + /* set the prescaler to 1ms == 1000us */ + writel(1000 << TMR1CTL_PRESCALE_SHIFT, priv->regs + TIMER_REG_TMR1CTL); + writel(ms, priv->regs + TIMER_REG_TMR1LOAD); + + setbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE); + + return 0; +} + +static int mt762x_wdt_stop(struct udevice *dev) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + mt762x_wdt_ping(priv); + + clrbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE); + + return 0; +} + +static int mt762x_wdt_reset(struct udevice *dev) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + mt762x_wdt_ping(priv); + + return 0; +} + +static int mt762x_wdt_probe(struct udevice *dev) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + priv->regs = dev_remap_addr(dev); + if (!priv->regs) + return -EINVAL; + + mt762x_wdt_stop(dev); + + return 0; +} + +static const struct wdt_ops mt762x_wdt_ops = { + .start = mt762x_wdt_start, + .reset = mt762x_wdt_reset, + .stop = mt762x_wdt_stop, +}; + +static const struct udevice_id mt762x_wdt_ids[] = { + { .compatible = "mediatek,mt7621-wdt" }, + {} +}; + +U_BOOT_DRIVER(mt762x_wdt) = { + .name = "mt762x_wdt", + .id = UCLASS_WDT, + .of_match = mt762x_wdt_ids, + .probe = mt762x_wdt_probe, + .priv_auto_alloc_size = sizeof(struct mt762x_wdt), + .ops = &mt762x_wdt_ops, +};