1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Ralink / Mediatek RT288x/RT3xxx/MT76xx built-in hardware watchdog timer 4 * 5 * Copyright (C) 2018 Stefan Roese <sr@denx.de> 6 * 7 * Based on the Linux driver version which is: 8 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 9 * Copyright (C) 2013 John Crispin <blogic@openwrt.org> 10 */ 11 12 #include <common.h> 13 #include <dm.h> 14 #include <wdt.h> 15 #include <linux/io.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 struct mt762x_wdt { 20 void __iomem *regs; 21 }; 22 23 #define TIMER_REG_TMRSTAT 0x00 24 #define TIMER_REG_TMR1CTL 0x20 25 #define TIMER_REG_TMR1LOAD 0x24 26 27 #define TMR1CTL_ENABLE BIT(7) 28 #define TMR1CTL_RESTART BIT(9) 29 #define TMR1CTL_PRESCALE_SHIFT 16 30 31 static int mt762x_wdt_ping(struct mt762x_wdt *priv) 32 { 33 writel(TMR1CTL_RESTART, priv->regs + TIMER_REG_TMRSTAT); 34 35 return 0; 36 } 37 38 static int mt762x_wdt_start(struct udevice *dev, u64 ms, ulong flags) 39 { 40 struct mt762x_wdt *priv = dev_get_priv(dev); 41 42 /* set the prescaler to 1ms == 1000us */ 43 writel(1000 << TMR1CTL_PRESCALE_SHIFT, priv->regs + TIMER_REG_TMR1CTL); 44 writel(ms, priv->regs + TIMER_REG_TMR1LOAD); 45 46 setbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE); 47 48 return 0; 49 } 50 51 static int mt762x_wdt_stop(struct udevice *dev) 52 { 53 struct mt762x_wdt *priv = dev_get_priv(dev); 54 55 mt762x_wdt_ping(priv); 56 57 clrbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE); 58 59 return 0; 60 } 61 62 static int mt762x_wdt_reset(struct udevice *dev) 63 { 64 struct mt762x_wdt *priv = dev_get_priv(dev); 65 66 mt762x_wdt_ping(priv); 67 68 return 0; 69 } 70 71 static int mt762x_wdt_probe(struct udevice *dev) 72 { 73 struct mt762x_wdt *priv = dev_get_priv(dev); 74 75 priv->regs = dev_remap_addr(dev); 76 if (!priv->regs) 77 return -EINVAL; 78 79 mt762x_wdt_stop(dev); 80 81 return 0; 82 } 83 84 static const struct wdt_ops mt762x_wdt_ops = { 85 .start = mt762x_wdt_start, 86 .reset = mt762x_wdt_reset, 87 .stop = mt762x_wdt_stop, 88 }; 89 90 static const struct udevice_id mt762x_wdt_ids[] = { 91 { .compatible = "mediatek,mt7621-wdt" }, 92 {} 93 }; 94 95 U_BOOT_DRIVER(mt762x_wdt) = { 96 .name = "mt762x_wdt", 97 .id = UCLASS_WDT, 98 .of_match = mt762x_wdt_ids, 99 .probe = mt762x_wdt_probe, 100 .priv_auto_alloc_size = sizeof(struct mt762x_wdt), 101 .ops = &mt762x_wdt_ops, 102 }; 103