blob: c01936680b070b45829f4138b1ae5bedd0684782 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Mediatek watchdog common driver.
4 *
5 *
6 * Copyright (C) 2020 MediaTek Inc.
7 *
8 * Author: Anan Sun <anan.sun@mediatek.com>
9 */
10
11#define pr_fmt(fmt) "mtk-wdt: " fmt
12
13#include <linux/bitops.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/platform_device.h>
23#include <linux/types.h>
24#include <linux/watchdog.h>
25#include <linux/delay.h>
26#include <asm/system_misc.h>
27#include <linux/of_address.h>
28#include <dbgtop.h>
29
30#define WDT_MODE (0x0000)
31#define WDT_EN BIT(0)
32#define EXTPOL BIT(1)
33#define EXTEN BIT(2)
34#define WDT_IRQ BIT(3)
35#define WDT_2STAGE_TMO_EN BIT(4) /* 6885: HW setting */
36#define WDT_MODE_AUTO_START BIT(4) /* 6589: reserved */
37#define IRQ_LVL_EN BIT(5)
38#define DUAL_MODE BIT(6)
39#define WDT_CNT_RESET_SEL BIT(8)
40#define WDT_MODE_UNLOCK_KEY (0x22000000)
41/* 6885: clear WDT_STA by WDT_MODE */
42#define WDT_STA_CLR_MASK (0x01FF)
43#define WDT_STA_CLEAR_UNLOCK_KEY (0x23000000)
44
45#define WDT_LENGTH (0x0004)
46#define WDT_LENGTH_UNLOCK_KEY (0x0008)
47/* ((sec * 32768) / 512 - 1) = 1 length unit */
48#define WDT_LENGTH_SEC2LENGTH(sec) (((sec) << 6) - 1)
49#define WDT_TIMEOUT_MAX_SEC (31)
50#define WDT_TIMEOUT_DEFAULT_SEC (20)
51#define WDT_TIMEOUT_MIN_SEC (1)
52#define WDT_LENGTH_SHIFT (5)
53#define WDT_LENGTH_MASK GENMASK(15, 5)
54
55#define WDT_RESTART (0x0008)
56#define WDT_RESTART_KEY (0x1971)
57
58#define WDT_SWRST (0x0014)
59#define WDT_SWRST_KEY (0x1209)
60
61#define WDT_NONRST_REG2 (0x0024)
62#define WDT_REBOOT_RPMBPK BIT(0)
63#define WDT_REBOOT_RECOVERY BIT(1)
64#define WDT_REBOOT_BOOTLOADER BIT(2)
65#define WDT_REBOOT_META BIT(3)
66#define WDT_REBOOT_DDR_RESERVE BIT(4)
67#define WDT_REBOOT_MODE_MSK (0x1F)
68#define WDT_REBOOT_STAGE_CUR_SHIFT (28)
69#define WDT_REBOOT_STAGE_MASK (0xfUL)
70#define WDT_REBOOT_STAGE_KERNEL (0x3UL)
71
72#define WDT_REQ_MODE (0x0030)
73#define WDT_REQ_MODE_UNLOCK_KEY (0x33000000)
74#define WDT_REQ_IRQ_EN (0x0034)
75#define WDT_REQ_IRQ_EN_UNLOCK_KEY (0x44000000)
76#define SPM_THERMAL_RST BIT(0)
77#define SPM_RST BIT(1)
78#define EINT_RST BIT(2)
79#define SYSRST_RST BIT(3)
80#define DVFSP_RST BIT(4)
81#define MCUPM_RST BIT(5)
82#define DEBUG_TOP_RST BIT(6)
83#define PCIE_PERST_B_RST BIT(7)
84#define PMCU_RSTREQ BIT(16) /* 2731: IOC_RST */
85#define MDDBG_RST BIT(17)
86#define THERMAL_CTL_RST BIT(18)
87#define DEBUG_RST BIT(19)
88
89#define WDT_EXT_REQ_CON (0x0038)
90#define EINT_DGRST_EN BIT(0)
91#define EINT_SEL_MASK (0xf)
92#define EINT_SEL_SHIFT (4)
93#define EINT_SEL GENMASK(7, 4)
94
95#define WDT_LATCH_CTL2 (0x0048)
96#define DFD_TIMEOUT_MASK GENMASK(16, 0)
97#define DFD_EN BIT(17)
98#define DFD_THERM1_DIS BIT(18)
99#define DFD_THERM2_DIS BIT(19)
100#define WDT_LATCH_CTL2_UNLOCK_KEY (0x95000000)
101
102#define WDT_SYSDBG_EN1 (0x0088)
103#define SYSDBG_EN_KEY1 (0x1B2A)
104#define WDT_SYSDBG_EN2 (0x008C)
105#define SYSDBG_EN_KEY2 (0x4F59)
106
107#define DRV_NAME "mtk-wdt"
108#define DRV_VERSION "1.0"
109#define DEV_VERSION_MSK (0xffUL)
110#define DEV_VERSION(chip, base) \
111 ((((chip) & DEV_VERSION_MSK) << 8) | ((base) & DEV_VERSION_MSK))
112#define DEV_VERSION_BASE(vers) ((vers) & DEV_VERSION_MSK)
113#define DEV_VERSION_CHIP(vers) (((vers) >> 8) & DEV_VERSION_MSK)
114
115enum wdt_version_id {
116 WDT_MT6589 = 1UL,
117 WDT_MT6885,
118 WDT_MT2731,
119 WDT_MT2735,
120};
121
122enum wdt_req_mode {
123 WDT_REQ_DIS = 0UL,
124 WDT_REQ_EN_IRQ_MODE,
125 WDT_REQ_EN_RST_MODE,
126};
127
128struct mtk_wdt_dev;
129
130struct mtk_wdt_plat {
131 unsigned int version;
132 void (*request_default)(struct mtk_wdt_dev *mtk_wdt);
133};
134
135struct mtk_wdt_dev {
136 struct watchdog_device wdt_dev;
137 void __iomem *wdt_base;
138 u32 eint;
139 u32 dfd_timeout;
140 const struct mtk_wdt_plat *wdt_plat;
141};
142
143static bool nowayout = WATCHDOG_NOWAYOUT;
144static unsigned int timeout = WDT_TIMEOUT_MAX_SEC;
145static void __iomem *toprgu_base;
146
147static void mtk_wdt_update_current_stage(struct mtk_wdt_dev *mtk_wdt,
148 uint32_t stage)
149{
150 void __iomem *wdt_base = mtk_wdt->wdt_base;
151 uint32_t reg_val = readl(wdt_base + WDT_NONRST_REG2);
152
153 reg_val &= (~(WDT_REBOOT_STAGE_MASK << WDT_REBOOT_STAGE_CUR_SHIFT));
154 reg_val |= (stage << WDT_REBOOT_STAGE_CUR_SHIFT);
155
156 writel(reg_val, wdt_base + WDT_NONRST_REG2);
157}
158
159static void mtk_wdt_request_config(struct mtk_wdt_dev *mtk_wdt,
160 unsigned int mark_bit,
161 enum wdt_req_mode mode)
162{
163 void __iomem *wdt_base = mtk_wdt->wdt_base;
164 u32 reg_val_en, reg_val_mode;
165
166 if ((mark_bit == EINT_RST) && (mode != WDT_REQ_DIS)) {
167 if (mtk_wdt->eint > EINT_SEL_MASK) {
168 pr_err("invalid eint id\n");
169 return;
170 }
171 writel((((mtk_wdt->eint) << EINT_SEL_SHIFT) | EINT_DGRST_EN),
172 wdt_base + WDT_EXT_REQ_CON);
173
174 } else if (mark_bit == SYSRST_RST) {
175 if (mode == WDT_REQ_DIS) {
176 writel(0, wdt_base + WDT_SYSDBG_EN1);
177 writel(0, wdt_base + WDT_SYSDBG_EN2);
178 } else {
179 writel(SYSDBG_EN_KEY1, wdt_base + WDT_SYSDBG_EN1);
180 writel(SYSDBG_EN_KEY2, wdt_base + WDT_SYSDBG_EN2);
181 }
182 }
183
184 reg_val_en = readl(wdt_base + WDT_REQ_MODE);
185 if (mode == WDT_REQ_DIS) {
186 reg_val_en &= ~mark_bit;
187 } else {
188 reg_val_en |= mark_bit;
189 }
190 writel((WDT_REQ_MODE_UNLOCK_KEY | reg_val_en), wdt_base + WDT_REQ_MODE);
191
192 reg_val_mode = readl(wdt_base + WDT_REQ_IRQ_EN);
193 if (mode != WDT_REQ_EN_IRQ_MODE) {
194 reg_val_mode &= ~mark_bit;
195 } else {
196 reg_val_mode |= mark_bit;
197 }
198 writel((WDT_REQ_IRQ_EN_UNLOCK_KEY | reg_val_mode),
199 wdt_base + WDT_REQ_IRQ_EN);
200}
201
202static void mtk_wdt_parse_dt(struct device_node *np,
203 struct mtk_wdt_dev *mtk_wdt)
204{
205 int err;
206 void __iomem *wdt_base = mtk_wdt->wdt_base;
207 unsigned int reg_val;
208
209 err = of_property_read_u32(np, "mediatek,rg_dfd_timeout",
210 &mtk_wdt->dfd_timeout);
211
212 if (!err && mtk_wdt->dfd_timeout) {
213 /* enable dfd_en and setup timeout */
214 reg_val = readl(wdt_base + WDT_LATCH_CTL2);
215 reg_val &= ~(DFD_THERM2_DIS | DFD_TIMEOUT_MASK);
216 reg_val |= (DFD_EN | DFD_THERM1_DIS |
217 (mtk_wdt->dfd_timeout & DFD_TIMEOUT_MASK));
218
219 writel((WDT_LATCH_CTL2_UNLOCK_KEY | reg_val),
220 wdt_base + WDT_LATCH_CTL2);
221 }
222}
223
224static void mtk_wdt_parse_eint(struct device_node *np,
225 struct mtk_wdt_dev *mtk_wdt)
226{
227 int err = of_property_read_u32(np, "eint", &mtk_wdt->eint);
228
229 if (err)
230 mtk_wdt->eint = (EINT_SEL_MASK + 1);
231}
232
233static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
234 unsigned long action, void *cmd)
235{
236 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
237 void __iomem *wdt_base = mtk_wdt->wdt_base;
238 u32 reg_val = readl(wdt_base + WDT_NONRST_REG2);
239
240 pr_info("[WDT]mtk_wdt_restart\n");
241 reg_val &= ~WDT_REBOOT_MODE_MSK;
242 if (cmd && (strcmp(cmd, "rpmbpk") == 0)) {
243 reg_val |= WDT_REBOOT_RPMBPK;
244
245 } else if (cmd && (strcmp(cmd, "recovery") == 0)) {
246 reg_val |= WDT_REBOOT_RECOVERY;
247
248 } else if (cmd && (strcmp(cmd, "bootloader") == 0)) {
249 reg_val |= WDT_REBOOT_BOOTLOADER;
250
251 } else if (cmd && !strcmp(cmd, "meta")) {
252 reg_val |= WDT_REBOOT_META;
253 pr_info("arch_reset, reboot meta mode\n");
254
255 } else if (cmd && !strcmp(cmd, "ddr-reserve")) {
256 reg_val |= WDT_REBOOT_DDR_RESERVE;
257 pr_info("arch_reset, reboot ddr-reserve mode\n");
258 }
259 writel(reg_val, wdt_base + WDT_NONRST_REG2);
260
261 reg_val = (WDT_LENGTH_SEC2LENGTH(WDT_TIMEOUT_DEFAULT_SEC) <<
262 WDT_LENGTH_SHIFT);
263 reg_val &= WDT_LENGTH_MASK;
264 writel((WDT_LENGTH_UNLOCK_KEY | reg_val), wdt_base + WDT_LENGTH);
265
266 writel(WDT_RESTART_KEY, wdt_base + WDT_RESTART);
267
268 if (!(readl(wdt_base + WDT_NONRST_REG2) & WDT_REBOOT_DDR_RESERVE))
269 mtk_dbgtop_dram_reserved(0);
270
271 reg_val = readl(wdt_base + WDT_MODE);
272 // reg_val |= (WDT_EN | EXTEN);
273 reg_val |= EXTEN;
274 reg_val &= ~(WDT_IRQ | DUAL_MODE);
275 writel((WDT_MODE_UNLOCK_KEY | reg_val), wdt_base + WDT_MODE);
276
277 if (!arm_pm_restart) {
278 while (1) {
279 writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
280 mdelay(5);
281 }
282 }
283
284 return NOTIFY_DONE;
285}
286
287static int mtk_wdt_ping(struct watchdog_device *wdt_dev)
288{
289 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
290 void __iomem *wdt_base = mtk_wdt->wdt_base;
291
292 writel(WDT_RESTART_KEY, wdt_base + WDT_RESTART);
293 return 0;
294}
295
296static int mtk_wdt_set_timeout(struct watchdog_device *wdt_dev,
297 unsigned int timeout)
298{
299 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
300 void __iomem *wdt_base = mtk_wdt->wdt_base;
301 u32 reg_val;
302
303 wdt_dev->timeout = timeout;
304 reg_val = (WDT_LENGTH_SEC2LENGTH(timeout) << WDT_LENGTH_SHIFT);
305 reg_val &= WDT_LENGTH_MASK;
306 writel((WDT_LENGTH_UNLOCK_KEY | reg_val), wdt_base + WDT_LENGTH);
307
308 mtk_wdt_ping(wdt_dev);
309
310 return 0;
311}
312
313static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
314{
315 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
316 void __iomem *wdt_base = mtk_wdt->wdt_base;
317 u32 reg_val;
318
319 reg_val = readl(wdt_base + WDT_MODE);
320 reg_val &= (~WDT_EN);
321 writel((WDT_MODE_UNLOCK_KEY | reg_val), wdt_base + WDT_MODE);
322
323 clear_bit(WDOG_HW_RUNNING, &mtk_wdt->wdt_dev.status);
324 return 0;
325}
326
327static int mtk_wdt_start(struct watchdog_device *wdt_dev)
328{
329 u32 reg_val;
330 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
331 void __iomem *wdt_base = mtk_wdt->wdt_base;
332 int ret;
333 ret = mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
334 if (ret < 0)
335 return ret;
336
337 reg_val = readl(wdt_base + WDT_MODE);
338 reg_val |= (WDT_EN | EXTEN | WDT_IRQ | DUAL_MODE);
339 writel((WDT_MODE_UNLOCK_KEY | reg_val), wdt_base + WDT_MODE);
340
341 set_bit(WDOG_HW_RUNNING, &mtk_wdt->wdt_dev.status);
342
343 return 0;
344}
345
346static const struct watchdog_info mtk_wdt_info = {
347 .identity = DRV_NAME,
348 .options = WDIOF_SETTIMEOUT |
349 WDIOF_KEEPALIVEPING |
350 WDIOF_MAGICCLOSE,
351};
352
353static const struct watchdog_ops mtk_wdt_ops = {
354 .owner = THIS_MODULE,
355 .start = mtk_wdt_start,
356 .stop = mtk_wdt_stop,
357 .ping = mtk_wdt_ping,
358 .set_timeout = mtk_wdt_set_timeout,
359 .restart = mtk_wdt_restart,
360};
361
362static int mtk_wdt_probe(struct platform_device *pdev)
363{
364 struct mtk_wdt_dev *mtk_wdt;
365 struct device *dev = &pdev->dev;
366 struct resource *res;
367 int err;
368 u32 mode;
369
370 mtk_wdt = devm_kzalloc(dev, sizeof(*mtk_wdt), GFP_KERNEL);
371 if (!mtk_wdt)
372 return -ENOMEM;
373
374 platform_set_drvdata(pdev, mtk_wdt);
375
376 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
377 mtk_wdt->wdt_base = devm_ioremap_resource(dev, res);
378 if (IS_ERR(mtk_wdt->wdt_base))
379 return PTR_ERR(mtk_wdt->wdt_base);
380 toprgu_base = mtk_wdt->wdt_base;
381
382 arm_pm_restart = NULL;
383 mtk_wdt->wdt_dev.info = &mtk_wdt_info;
384 mtk_wdt->wdt_dev.ops = &mtk_wdt_ops;
385 mtk_wdt->wdt_dev.timeout = WDT_TIMEOUT_MAX_SEC;
386 mtk_wdt->wdt_dev.max_timeout = WDT_TIMEOUT_MAX_SEC;
387 mtk_wdt->wdt_dev.min_timeout = WDT_TIMEOUT_MIN_SEC;
388 mtk_wdt->wdt_dev.parent = dev;
389
390 mtk_wdt->wdt_plat = of_device_get_match_data(dev);
391 mtk_wdt_update_current_stage(mtk_wdt, WDT_REBOOT_STAGE_KERNEL);
392
393 mtk_wdt_parse_dt(dev->of_node, mtk_wdt);
394 mtk_wdt_parse_eint(dev->of_node, mtk_wdt);
395 if (mtk_wdt->wdt_plat && mtk_wdt->wdt_plat->request_default)
396 mtk_wdt->wdt_plat->request_default(mtk_wdt);
397
398 watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, dev);
399 watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
400 watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
401
402 watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
403 writel((WDT_MODE_UNLOCK_KEY | WDT_EN), mtk_wdt->wdt_base + WDT_MODE);
404 if (readl(mtk_wdt->wdt_base + WDT_MODE) & WDT_EN) {
405 set_bit(WDOG_HW_RUNNING, &mtk_wdt->wdt_dev.status);
406 mtk_wdt_start(&mtk_wdt->wdt_dev);
407 }
408 else
409 mtk_wdt_stop(&mtk_wdt->wdt_dev);
410 err = watchdog_register_device(&mtk_wdt->wdt_dev);
411 if (unlikely(err))
412 return err;
413 mode = readl(mtk_wdt->wdt_base + WDT_MODE);
414 pr_info("[mode]0x%x\n", mode);
415 dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
416 mtk_wdt->wdt_dev.timeout, nowayout);
417 return 0;
418}
419
420static void mtk_wdt_shutdown(struct platform_device *pdev)
421{
422 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
423
424 if (watchdog_active(&mtk_wdt->wdt_dev))
425 mtk_wdt_stop(&mtk_wdt->wdt_dev);
426}
427
428static int mtk_wdt_remove(struct platform_device *pdev)
429{
430 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
431
432 mtk_wdt_stop(&mtk_wdt->wdt_dev);
433 watchdog_unregister_device(&mtk_wdt->wdt_dev);
434
435 return 0;
436}
437
438#ifdef CONFIG_PM_SLEEP
439static int mtk_wdt_suspend(struct device *dev)
440{
441 struct mtk_wdt_dev *mtk_wdt = dev_get_drvdata(dev);
442
443 if (watchdog_active(&mtk_wdt->wdt_dev))
444 mtk_wdt_stop(&mtk_wdt->wdt_dev);
445
446 return 0;
447}
448
449static int mtk_wdt_resume(struct device *dev)
450{
451 struct mtk_wdt_dev *mtk_wdt = dev_get_drvdata(dev);
452
453 if (watchdog_active(&mtk_wdt->wdt_dev))
454 mtk_wdt_start(&mtk_wdt->wdt_dev);
455
456 return 0;
457}
458
459static const struct dev_pm_ops mtk_wdt_pm_ops = {
460 SET_SYSTEM_SLEEP_PM_OPS(mtk_wdt_suspend, mtk_wdt_resume)
461};
462#endif
463
464static void mtk_wdt_request_default_mt2731(struct mtk_wdt_dev *mtk_wdt)
465{
466 mtk_wdt_request_config(mtk_wdt, THERMAL_CTL_RST, WDT_REQ_EN_RST_MODE);
467 /* spm: scpsys */
468 mtk_wdt_request_config(mtk_wdt, SPM_RST, WDT_REQ_EN_RST_MODE);
469}
470
471static struct mtk_wdt_plat mt2731_wdt = {
472 .version = DEV_VERSION(WDT_MT2731, WDT_MT6589),
473 .request_default = mtk_wdt_request_default_mt2731,
474};
475
476static struct mtk_wdt_plat mt2735_wdt = {
477 .version = DEV_VERSION(WDT_MT2735, WDT_MT6885),
478 .request_default = NULL,
479};
480
481static const struct of_device_id mtk_wdt_dt_ids[] = {
482 { .compatible = "mediatek,mt2731-wdt", .data = &mt2731_wdt },
483 { .compatible = "mediatek,mt2735-wdt", .data = &mt2735_wdt },
484 { /* sentinel */ }
485};
486MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
487
488static struct platform_driver mtk_wdt_driver = {
489 .probe = mtk_wdt_probe,
490 .remove = mtk_wdt_remove,
491 .shutdown = mtk_wdt_shutdown,
492 .driver = {
493 .name = DRV_NAME,
494#ifdef CONFIG_PM_SLEEP
495 .pm = &mtk_wdt_pm_ops,
496#endif
497 .of_match_table = mtk_wdt_dt_ids,
498 },
499};
500module_platform_driver(mtk_wdt_driver);
501
502void __iomem *mtk_wd_Gettoprgu(void)
503{
504 struct device_node *np_rgu;
505 unsigned int i, cnt = ARRAY_SIZE(mtk_wdt_dt_ids) - 1;
506
507 if (!toprgu_base) {
508 for (i = 0; i < cnt; i++) {
509 np_rgu = of_find_compatible_node(NULL, NULL,
510 mtk_wdt_dt_ids[i].compatible);
511 if (!np_rgu)
512 continue;
513
514 toprgu_base = of_iomap(np_rgu, 0);
515 if (!toprgu_base)
516 pr_debug("RGU iomap failed\n");
517
518 break;
519 }
520 }
521
522 pr_info("get toprgu is %p\n", toprgu_base);
523
524 return toprgu_base;
525}
526EXPORT_SYMBOL_GPL(mtk_wd_Gettoprgu);
527
528module_param(timeout, uint, 0);
529MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds");
530
531module_param(nowayout, bool, 0);
532MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
533 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
534
535MODULE_LICENSE("GPL");
536MODULE_AUTHOR("Matthias Brugger <matthias.bgg@gmail.com>");
537MODULE_DESCRIPTION("Mediatek WatchDog Timer Driver");
538MODULE_VERSION(DRV_VERSION);