1 // SPDX-License-Identifier: GPL-2.0-only
4 * Realtek Otto MIPS platform watchdog
6 * Watchdog timer that will reset the system after timeout, using the selected
9 * Counter scaling and timeouts:
10 * - Base prescale of (2 << 25), providing tick duration T_0: 168ms @ 200MHz
11 * - PRESCALE: logarithmic prescaler adding a factor of {1, 2, 4, 8}
12 * - Phase 1: Times out after (PHASE1 + 1) × PRESCALE × T_0
13 * Generates an interrupt, WDT cannot be stopped after phase 1
14 * - Phase 2: starts after phase 1, times out after (PHASE2 + 1) × PRESCALE × T_0
15 * Resets the system according to RST_MODE
18 #include <linux/bits.h>
19 #include <linux/bitfield.h>
20 #include <linux/clk.h>
21 #include <linux/delay.h>
22 #include <linux/interrupt.h>
24 #include <linux/math.h>
25 #include <linux/minmax.h>
26 #include <linux/module.h>
27 #include <linux/mod_devicetable.h>
28 #include <linux/platform_device.h>
29 #include <linux/property.h>
30 #include <linux/reboot.h>
31 #include <linux/watchdog.h>
33 #define OTTO_WDT_REG_CNTR 0x0
34 #define OTTO_WDT_CNTR_PING BIT(31)
36 #define OTTO_WDT_REG_INTR 0x4
37 #define OTTO_WDT_INTR_PHASE_1 BIT(31)
38 #define OTTO_WDT_INTR_PHASE_2 BIT(30)
40 #define OTTO_WDT_REG_CTRL 0x8
41 #define OTTO_WDT_CTRL_ENABLE BIT(31)
42 #define OTTO_WDT_CTRL_PRESCALE GENMASK(30, 29)
43 #define OTTO_WDT_CTRL_PHASE1 GENMASK(26, 22)
44 #define OTTO_WDT_CTRL_PHASE2 GENMASK(19, 15)
45 #define OTTO_WDT_CTRL_RST_MODE GENMASK(1, 0)
46 #define OTTO_WDT_MODE_SOC 0
47 #define OTTO_WDT_MODE_CPU 1
48 #define OTTO_WDT_MODE_SOFTWARE 2
49 #define OTTO_WDT_CTRL_DEFAULT OTTO_WDT_MODE_CPU
51 #define OTTO_WDT_PRESCALE_MAX 3
54 * One higher than the max values contained in PHASE{1,2}, since a value of 0
55 * corresponds to one tick.
57 #define OTTO_WDT_PHASE_TICKS_MAX 32
60 * The maximum reset delay is actually 2×32 ticks, but that would require large
61 * pretimeout values for timeouts longer than 32 ticks. Limit the maximum timeout
62 * to 32 + 1 to ensure small pretimeout values can be configured as expected.
64 #define OTTO_WDT_TIMEOUT_TICKS_MAX (OTTO_WDT_PHASE_TICKS_MAX + 1)
66 struct otto_wdt_ctrl
{
67 struct watchdog_device wdev
;
70 unsigned int clk_rate_khz
;
74 static int otto_wdt_start(struct watchdog_device
*wdev
)
76 struct otto_wdt_ctrl
*ctrl
= watchdog_get_drvdata(wdev
);
79 v
= ioread32(ctrl
->base
+ OTTO_WDT_REG_CTRL
);
80 v
|= OTTO_WDT_CTRL_ENABLE
;
81 iowrite32(v
, ctrl
->base
+ OTTO_WDT_REG_CTRL
);
86 static int otto_wdt_stop(struct watchdog_device
*wdev
)
88 struct otto_wdt_ctrl
*ctrl
= watchdog_get_drvdata(wdev
);
91 v
= ioread32(ctrl
->base
+ OTTO_WDT_REG_CTRL
);
92 v
&= ~OTTO_WDT_CTRL_ENABLE
;
93 iowrite32(v
, ctrl
->base
+ OTTO_WDT_REG_CTRL
);
98 static int otto_wdt_ping(struct watchdog_device
*wdev
)
100 struct otto_wdt_ctrl
*ctrl
= watchdog_get_drvdata(wdev
);
102 iowrite32(OTTO_WDT_CNTR_PING
, ctrl
->base
+ OTTO_WDT_REG_CNTR
);
107 static int otto_wdt_tick_ms(struct otto_wdt_ctrl
*ctrl
, int prescale
)
109 return DIV_ROUND_CLOSEST(1 << (25 + prescale
), ctrl
->clk_rate_khz
);
113 * The timer asserts the PHASE1/PHASE2 IRQs when the number of ticks exceeds
114 * the value stored in those fields. This means each phase will run for at least
115 * one tick, so small values need to be clamped to correctly reflect the timeout.
117 static inline unsigned int div_round_ticks(unsigned int val
, unsigned int tick_duration
,
118 unsigned int min_ticks
)
120 return max(min_ticks
, DIV_ROUND_UP(val
, tick_duration
));
123 static int otto_wdt_determine_timeouts(struct watchdog_device
*wdev
, unsigned int timeout
,
124 unsigned int pretimeout
)
126 struct otto_wdt_ctrl
*ctrl
= watchdog_get_drvdata(wdev
);
127 unsigned int pretimeout_ms
= pretimeout
* 1000;
128 unsigned int timeout_ms
= timeout
* 1000;
129 unsigned int prescale_next
= 0;
130 unsigned int phase1_ticks
;
131 unsigned int phase2_ticks
;
132 unsigned int total_ticks
;
133 unsigned int prescale
;
134 unsigned int tick_ms
;
138 prescale
= prescale_next
;
139 if (prescale
> OTTO_WDT_PRESCALE_MAX
)
142 tick_ms
= otto_wdt_tick_ms(ctrl
, prescale
);
143 total_ticks
= div_round_ticks(timeout_ms
, tick_ms
, 2);
144 phase1_ticks
= div_round_ticks(timeout_ms
- pretimeout_ms
, tick_ms
, 1);
145 phase2_ticks
= total_ticks
- phase1_ticks
;
148 } while (phase1_ticks
> OTTO_WDT_PHASE_TICKS_MAX
149 || phase2_ticks
> OTTO_WDT_PHASE_TICKS_MAX
);
151 v
= ioread32(ctrl
->base
+ OTTO_WDT_REG_CTRL
);
153 v
&= ~(OTTO_WDT_CTRL_PRESCALE
| OTTO_WDT_CTRL_PHASE1
| OTTO_WDT_CTRL_PHASE2
);
154 v
|= FIELD_PREP(OTTO_WDT_CTRL_PHASE1
, phase1_ticks
- 1);
155 v
|= FIELD_PREP(OTTO_WDT_CTRL_PHASE2
, phase2_ticks
- 1);
156 v
|= FIELD_PREP(OTTO_WDT_CTRL_PRESCALE
, prescale
);
158 iowrite32(v
, ctrl
->base
+ OTTO_WDT_REG_CTRL
);
160 timeout_ms
= total_ticks
* tick_ms
;
161 ctrl
->wdev
.timeout
= timeout_ms
/ 1000;
163 pretimeout_ms
= phase2_ticks
* tick_ms
;
164 ctrl
->wdev
.pretimeout
= pretimeout_ms
/ 1000;
169 static int otto_wdt_set_timeout(struct watchdog_device
*wdev
, unsigned int val
)
171 return otto_wdt_determine_timeouts(wdev
, val
, min(wdev
->pretimeout
, val
- 1));
174 static int otto_wdt_set_pretimeout(struct watchdog_device
*wdev
, unsigned int val
)
176 return otto_wdt_determine_timeouts(wdev
, wdev
->timeout
, val
);
179 static int otto_wdt_restart(struct watchdog_device
*wdev
, unsigned long reboot_mode
,
182 struct otto_wdt_ctrl
*ctrl
= watchdog_get_drvdata(wdev
);
186 disable_irq(ctrl
->irq_phase1
);
188 switch (reboot_mode
) {
190 reset_mode
= OTTO_WDT_MODE_SOFTWARE
;
193 reset_mode
= OTTO_WDT_MODE_CPU
;
196 reset_mode
= OTTO_WDT_MODE_SOC
;
200 /* Configure for shortest timeout and wait for reset to occur */
201 v
= FIELD_PREP(OTTO_WDT_CTRL_RST_MODE
, reset_mode
) | OTTO_WDT_CTRL_ENABLE
;
202 iowrite32(v
, ctrl
->base
+ OTTO_WDT_REG_CTRL
);
204 mdelay(3 * otto_wdt_tick_ms(ctrl
, 0));
209 static irqreturn_t
otto_wdt_phase1_isr(int irq
, void *dev_id
)
211 struct otto_wdt_ctrl
*ctrl
= dev_id
;
213 iowrite32(OTTO_WDT_INTR_PHASE_1
, ctrl
->base
+ OTTO_WDT_REG_INTR
);
214 dev_crit(ctrl
->dev
, "phase 1 timeout\n");
215 watchdog_notify_pretimeout(&ctrl
->wdev
);
220 static const struct watchdog_ops otto_wdt_ops
= {
221 .owner
= THIS_MODULE
,
222 .start
= otto_wdt_start
,
223 .stop
= otto_wdt_stop
,
224 .ping
= otto_wdt_ping
,
225 .set_timeout
= otto_wdt_set_timeout
,
226 .set_pretimeout
= otto_wdt_set_pretimeout
,
227 .restart
= otto_wdt_restart
,
230 static const struct watchdog_info otto_wdt_info
= {
231 .identity
= "Realtek Otto watchdog timer",
232 .options
= WDIOF_KEEPALIVEPING
|
238 static int otto_wdt_probe_clk(struct otto_wdt_ctrl
*ctrl
)
242 clk
= devm_clk_get_enabled(ctrl
->dev
, NULL
);
244 return dev_err_probe(ctrl
->dev
, PTR_ERR(clk
), "Failed to get clock\n");
246 ctrl
->clk_rate_khz
= clk_get_rate(clk
) / 1000;
247 if (ctrl
->clk_rate_khz
== 0)
248 return dev_err_probe(ctrl
->dev
, -ENXIO
, "Failed to get clock rate\n");
253 static int otto_wdt_probe_reset_mode(struct otto_wdt_ctrl
*ctrl
)
255 static const char *mode_property
= "realtek,reset-mode";
256 const struct fwnode_handle
*node
= ctrl
->dev
->fwnode
;
264 mode_count
= fwnode_property_string_array_count(node
, mode_property
);
267 else if (mode_count
== 0)
269 else if (mode_count
!= 1)
272 if (fwnode_property_match_string(node
, mode_property
, "soc") == 0)
273 mode
= OTTO_WDT_MODE_SOC
;
274 else if (fwnode_property_match_string(node
, mode_property
, "cpu") == 0)
275 mode
= OTTO_WDT_MODE_CPU
;
276 else if (fwnode_property_match_string(node
, mode_property
, "software") == 0)
277 mode
= OTTO_WDT_MODE_SOFTWARE
;
281 v
= ioread32(ctrl
->base
+ OTTO_WDT_REG_CTRL
);
282 v
&= ~OTTO_WDT_CTRL_RST_MODE
;
283 v
|= FIELD_PREP(OTTO_WDT_CTRL_RST_MODE
, mode
);
284 iowrite32(v
, ctrl
->base
+ OTTO_WDT_REG_CTRL
);
289 static int otto_wdt_probe(struct platform_device
*pdev
)
291 struct device
*dev
= &pdev
->dev
;
292 struct otto_wdt_ctrl
*ctrl
;
293 unsigned int max_tick_ms
;
296 ctrl
= devm_kzalloc(dev
, sizeof(*ctrl
), GFP_KERNEL
);
301 ctrl
->base
= devm_platform_ioremap_resource(pdev
, 0);
302 if (IS_ERR(ctrl
->base
))
303 return PTR_ERR(ctrl
->base
);
305 /* Clear any old interrupts and reset initial state */
306 iowrite32(OTTO_WDT_INTR_PHASE_1
| OTTO_WDT_INTR_PHASE_2
,
307 ctrl
->base
+ OTTO_WDT_REG_INTR
);
308 iowrite32(OTTO_WDT_CTRL_DEFAULT
, ctrl
->base
+ OTTO_WDT_REG_CTRL
);
310 ret
= otto_wdt_probe_clk(ctrl
);
314 ctrl
->irq_phase1
= platform_get_irq_byname(pdev
, "phase1");
315 if (ctrl
->irq_phase1
< 0)
316 return ctrl
->irq_phase1
;
318 ret
= devm_request_irq(dev
, ctrl
->irq_phase1
, otto_wdt_phase1_isr
, 0,
319 "realtek-otto-wdt", ctrl
);
321 return dev_err_probe(dev
, ret
, "Failed to get IRQ for phase1\n");
323 ret
= otto_wdt_probe_reset_mode(ctrl
);
325 return dev_err_probe(dev
, ret
, "Invalid reset mode specified\n");
327 ctrl
->wdev
.parent
= dev
;
328 ctrl
->wdev
.info
= &otto_wdt_info
;
329 ctrl
->wdev
.ops
= &otto_wdt_ops
;
332 * Since pretimeout cannot be disabled, min. timeout is twice the
333 * subsystem resolution. Max. timeout is ca. 43s at a bus clock of 200MHz.
335 ctrl
->wdev
.min_timeout
= 2;
336 max_tick_ms
= otto_wdt_tick_ms(ctrl
, OTTO_WDT_PRESCALE_MAX
);
337 ctrl
->wdev
.max_hw_heartbeat_ms
= max_tick_ms
* OTTO_WDT_TIMEOUT_TICKS_MAX
;
338 ctrl
->wdev
.timeout
= min(30U, ctrl
->wdev
.max_hw_heartbeat_ms
/ 1000);
340 watchdog_set_drvdata(&ctrl
->wdev
, ctrl
);
341 watchdog_init_timeout(&ctrl
->wdev
, 0, dev
);
342 watchdog_stop_on_reboot(&ctrl
->wdev
);
343 watchdog_set_restart_priority(&ctrl
->wdev
, 128);
345 ret
= otto_wdt_determine_timeouts(&ctrl
->wdev
, ctrl
->wdev
.timeout
, 1);
347 return dev_err_probe(dev
, ret
, "Failed to set timeout\n");
349 return devm_watchdog_register_device(dev
, &ctrl
->wdev
);
352 static const struct of_device_id otto_wdt_ids
[] = {
353 { .compatible
= "realtek,rtl8380-wdt" },
354 { .compatible
= "realtek,rtl8390-wdt" },
355 { .compatible
= "realtek,rtl9300-wdt" },
356 { .compatible
= "realtek,rtl9310-wdt" },
359 MODULE_DEVICE_TABLE(of
, otto_wdt_ids
);
361 static struct platform_driver otto_wdt_driver
= {
362 .probe
= otto_wdt_probe
,
364 .name
= "realtek-otto-watchdog",
365 .of_match_table
= otto_wdt_ids
,
368 module_platform_driver(otto_wdt_driver
);
370 MODULE_LICENSE("GPL v2");
371 MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
372 MODULE_DESCRIPTION("Realtek Otto watchdog timer driver");