]>
Commit | Line | Data |
---|---|---|
253531bb YL |
1 | /* |
2 | * Copyright (C) 2016 Freescale Semiconductor, Inc. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/io.h> | |
9 | #include <asm/arch/imx-regs.h> | |
10 | ||
11 | /* | |
12 | * MX7ULP WDOG Register Map | |
13 | */ | |
14 | struct wdog_regs { | |
15 | u8 cs1; | |
16 | u8 cs2; | |
17 | u16 reserve0; | |
18 | u32 cnt; | |
19 | u32 toval; | |
20 | u32 win; | |
21 | }; | |
22 | ||
23 | #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS | |
24 | #define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500 | |
25 | #endif | |
26 | ||
27 | #define REFRESH_WORD0 0xA602 /* 1st refresh word */ | |
28 | #define REFRESH_WORD1 0xB480 /* 2nd refresh word */ | |
29 | ||
30 | #define UNLOCK_WORD0 0xC520 /* 1st unlock word */ | |
31 | #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ | |
32 | ||
33 | #define WDGCS1_WDGE (1<<7) | |
34 | #define WDGCS1_WDGUPDATE (1<<5) | |
35 | ||
36 | #define WDGCS2_FLG (1<<6) | |
37 | ||
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 | ||
43 | DECLARE_GLOBAL_DATA_PTR; | |
44 | ||
45 | void hw_watchdog_set_timeout(u16 val) | |
46 | { | |
47 | /* setting timeout value */ | |
48 | struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; | |
49 | ||
50 | writel(val, &wdog->toval); | |
51 | } | |
52 | ||
53 | void hw_watchdog_reset(void) | |
54 | { | |
55 | struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; | |
56 | ||
57 | writel(REFRESH_WORD0, &wdog->cnt); | |
58 | writel(REFRESH_WORD1, &wdog->cnt); | |
59 | } | |
60 | ||
61 | void hw_watchdog_init(void) | |
62 | { | |
63 | u8 val; | |
64 | struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; | |
65 | ||
66 | writel(UNLOCK_WORD0, &wdog->cnt); | |
67 | writel(UNLOCK_WORD1, &wdog->cnt); | |
68 | ||
69 | val = readb(&wdog->cs2); | |
70 | val |= WDGCS2_FLG; | |
71 | writeb(val, &wdog->cs2); | |
72 | ||
73 | hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); | |
74 | writel(0, &wdog->win); | |
75 | ||
76 | writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ | |
77 | writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */ | |
78 | ||
79 | hw_watchdog_reset(); | |
80 | } | |
81 | ||
82 | void reset_cpu(ulong addr) | |
83 | { | |
84 | struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; | |
85 | ||
86 | writel(UNLOCK_WORD0, &wdog->cnt); | |
87 | writel(UNLOCK_WORD1, &wdog->cnt); | |
88 | ||
89 | hw_watchdog_set_timeout(5); /* 5ms timeout */ | |
90 | writel(0, &wdog->win); | |
91 | ||
92 | writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ | |
93 | writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */ | |
94 | ||
95 | hw_watchdog_reset(); | |
96 | ||
97 | while (1); | |
98 | } |