treewide: convert devfdt_get_addr() to dev_read_addr()
[platform/kernel/u-boot.git] / drivers / watchdog / mt7621_wdt.c
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/bitops.h>
16 #include <linux/io.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 struct mt762x_wdt {
21         void __iomem *regs;
22 };
23
24 #define TIMER_REG_TMRSTAT               0x00
25 #define TIMER_REG_TMR1CTL               0x20
26 #define TIMER_REG_TMR1LOAD              0x24
27
28 #define TMR1CTL_ENABLE                  BIT(7)
29 #define TMR1CTL_RESTART                 BIT(9)
30 #define TMR1CTL_PRESCALE_SHIFT          16
31
32 static int mt762x_wdt_ping(struct mt762x_wdt *priv)
33 {
34         writel(TMR1CTL_RESTART, priv->regs + TIMER_REG_TMRSTAT);
35
36         return 0;
37 }
38
39 static int mt762x_wdt_start(struct udevice *dev, u64 ms, ulong flags)
40 {
41         struct mt762x_wdt *priv = dev_get_priv(dev);
42
43         /* set the prescaler to 1ms == 1000us */
44         writel(1000 << TMR1CTL_PRESCALE_SHIFT, priv->regs + TIMER_REG_TMR1CTL);
45         writel(ms, priv->regs + TIMER_REG_TMR1LOAD);
46
47         setbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE);
48
49         return 0;
50 }
51
52 static int mt762x_wdt_stop(struct udevice *dev)
53 {
54         struct mt762x_wdt *priv = dev_get_priv(dev);
55
56         mt762x_wdt_ping(priv);
57
58         clrbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE);
59
60         return 0;
61 }
62
63 static int mt762x_wdt_reset(struct udevice *dev)
64 {
65         struct mt762x_wdt *priv = dev_get_priv(dev);
66
67         mt762x_wdt_ping(priv);
68
69         return 0;
70 }
71
72 static int mt762x_wdt_probe(struct udevice *dev)
73 {
74         struct mt762x_wdt *priv = dev_get_priv(dev);
75
76         priv->regs = dev_remap_addr(dev);
77         if (!priv->regs)
78                 return -EINVAL;
79
80         mt762x_wdt_stop(dev);
81
82         return 0;
83 }
84
85 static const struct wdt_ops mt762x_wdt_ops = {
86         .start = mt762x_wdt_start,
87         .reset = mt762x_wdt_reset,
88         .stop = mt762x_wdt_stop,
89 };
90
91 static const struct udevice_id mt762x_wdt_ids[] = {
92         { .compatible = "mediatek,mt7621-wdt" },
93         {}
94 };
95
96 U_BOOT_DRIVER(mt762x_wdt) = {
97         .name = "mt762x_wdt",
98         .id = UCLASS_WDT,
99         .of_match = mt762x_wdt_ids,
100         .probe = mt762x_wdt_probe,
101         .priv_auto_alloc_size = sizeof(struct mt762x_wdt),
102         .ops = &mt762x_wdt_ops,
103 };