blob: ecd35ef22ac5abd53f9757f0238d3963c49f1c29 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Ye Li62862b62017-02-22 16:21:48 +08002/*
3 * Copyright (C) 2016 Freescale Semiconductor, Inc.
Ye Li62862b62017-02-22 16:21:48 +08004 */
5
6#include <common.h>
Simon Glassafb02152019-12-28 10:45:01 -07007#include <cpu_func.h>
Ye Li62862b62017-02-22 16:21:48 +08008#include <asm/io.h>
9#include <asm/arch/imx-regs.h>
10
11/*
12 * MX7ULP WDOG Register Map
13 */
14struct wdog_regs {
Breno Lima4a686892021-06-29 10:32:35 +080015 u32 cs;
Ye Li62862b62017-02-22 16:21:48 +080016 u32 cnt;
17 u32 toval;
18 u32 win;
19};
20
21#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
22#define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500
23#endif
24
25#define REFRESH_WORD0 0xA602 /* 1st refresh word */
26#define REFRESH_WORD1 0xB480 /* 2nd refresh word */
27
28#define UNLOCK_WORD0 0xC520 /* 1st unlock word */
29#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
30
Breno Lima4a686892021-06-29 10:32:35 +080031#define WDGCS_WDGE BIT(7)
32#define WDGCS_WDGUPDATE BIT(5)
Ye Li62862b62017-02-22 16:21:48 +080033
Breno Lima4a686892021-06-29 10:32:35 +080034#define WDGCS_RCS BIT(10)
35#define WDGCS_ULK BIT(11)
36#define WDGCS_FLG BIT(14)
Ye Li62862b62017-02-22 16:21:48 +080037
38#define WDG_BUS_CLK (0x0)
39#define WDG_LPO_CLK (0x1)
40#define WDG_32KHZ_CLK (0x2)
41#define WDG_EXT_CLK (0x3)
42
Ye Li62862b62017-02-22 16:21:48 +080043void hw_watchdog_set_timeout(u16 val)
44{
45 /* setting timeout value */
46 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
47
48 writel(val, &wdog->toval);
49}
50
51void hw_watchdog_reset(void)
52{
53 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
54
Breno Lima3c5e9632021-06-29 10:32:34 +080055 dmb();
56 __raw_writel(REFRESH_WORD0, &wdog->cnt);
57 __raw_writel(REFRESH_WORD1, &wdog->cnt);
58 dmb();
Ye Li62862b62017-02-22 16:21:48 +080059}
60
61void hw_watchdog_init(void)
62{
Ye Li62862b62017-02-22 16:21:48 +080063 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
64
Breno Lima3c5e9632021-06-29 10:32:34 +080065 dmb();
66 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
67 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
68 dmb();
Ye Li62862b62017-02-22 16:21:48 +080069
Breno Lima4a686892021-06-29 10:32:35 +080070 /* Wait WDOG Unlock */
71 while (!(readl(&wdog->cs) & WDGCS_ULK))
72 ;
Ye Li62862b62017-02-22 16:21:48 +080073
74 hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
75 writel(0, &wdog->win);
76
Breno Lima4a686892021-06-29 10:32:35 +080077 /* setting 1-kHz clock source, enable counter running, and clear interrupt */
78 writel((WDGCS_WDGE | WDGCS_WDGUPDATE |(WDG_LPO_CLK << 8) | WDGCS_FLG), &wdog->cs);
79
80 /* Wait WDOG reconfiguration */
81 while (!(readl(&wdog->cs) & WDGCS_RCS))
82 ;
Ye Li62862b62017-02-22 16:21:48 +080083
84 hw_watchdog_reset();
85}
86
Harald Seiler6f14d5f2020-12-15 16:47:52 +010087void reset_cpu(void)
Ye Li62862b62017-02-22 16:21:48 +080088{
89 struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
90
Breno Lima3c5e9632021-06-29 10:32:34 +080091 dmb();
92 __raw_writel(UNLOCK_WORD0, &wdog->cnt);
93 __raw_writel(UNLOCK_WORD1, &wdog->cnt);
94 dmb();
Ye Li62862b62017-02-22 16:21:48 +080095
Breno Lima4a686892021-06-29 10:32:35 +080096 /* Wait WDOG Unlock */
97 while (!(readl(&wdog->cs) & WDGCS_ULK))
98 ;
99
Ye Li62862b62017-02-22 16:21:48 +0800100 hw_watchdog_set_timeout(5); /* 5ms timeout */
101 writel(0, &wdog->win);
102
Breno Lima4a686892021-06-29 10:32:35 +0800103 /* enable counter running */
104 writel((WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);
105
106 /* Wait WDOG reconfiguration */
107 while (!(readl(&wdog->cs) & WDGCS_RCS))
108 ;
Ye Li62862b62017-02-22 16:21:48 +0800109
110 hw_watchdog_reset();
111
112 while (1);
113}