blob: da31104a15d6816f717158317f8848dabe43cebb [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * drivers\watchdog\zx29_wdt.h
3 *
4 * Copyright (C) 2015 ZTE-TSP
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef __ZX29_WDT_H
18#define __ZX29_WDT_H
19
20#include <mach/board.h>
21#include <mach/iomap.h>
22
23#define WDT_SOURCE_CLOCK_RATE (32768)
24
25#define WDT_TIME_1S (WDT_SOURCE_CLOCK_RATE/32)
26#define WDT_TIME_1M (WDT_TIME_1S*60)
27#define WDT_TIME_1MS (WDT_TIME_1S/1000)
28
29typedef struct
30{
31 /* 0x00 */ volatile unsigned wdt_version;
32 /* 0x04 */ volatile unsigned wdt_config;
33 /* 0x08 */ volatile unsigned wdt_load;
34 /* 0x0c */ volatile unsigned wdt_counter;
35 /* 0x10 */ volatile unsigned wdt_status;
36 /* 0x14 */ volatile unsigned wdt_int_value;
37 /* 0x18 */ volatile unsigned wdt_set_en;
38 /* 0x1c */ volatile unsigned wdt_start;
39} zx29_wdt_registers;
40
41typedef struct
42{
43 unsigned wdt_config;
44 unsigned wdt_load;
45 unsigned wdt_int_value;
46 unsigned wdt_start;
47} zx29_wdt_context;
48
49/* we can enable/disable wdt reset function */
50#define WDT_RESET_ENABLE_REG (ZX_TOP_CRM_BASE + 0x2c)
51#define CPU_AP_WDT_RSTALL_EN (1U << 7)
52#define CPU_AP_WDT_RSTEN (1U << 6)
53
54#define __wdt_enable_reset() \
55 zx_set_reg(WDT_RESET_ENABLE_REG, CPU_AP_WDT_RSTALL_EN|CPU_AP_WDT_RSTEN)
56
57#define __wdt_disable_reset() \
58 zx_clr_reg(WDT_RESET_ENABLE_REG, CPU_AP_WDT_RSTALL_EN|CPU_AP_WDT_RSTEN)
59
60/******************************************************************************/
61#define WDT_WRITE_KEY (0x1234 << 16)
62#define WDT_PRESCALE(ptv) (ptv << 8)
63
64static inline void __wdt_start(void __iomem *base)
65{
66 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
67
68 wdt_reg->wdt_start = WDT_WRITE_KEY|1;
69}
70
71static inline void __wdt_stop(void __iomem *base)
72{
73 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
74
75 wdt_reg->wdt_start = WDT_WRITE_KEY|0;
76}
77
78static inline void __wdt_refresh_config_reg(void __iomem *base)
79{
80 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
81 unsigned int tmp=0;
82
83 tmp = wdt_reg->wdt_set_en;
84 tmp ^= 0x30;
85 wdt_reg->wdt_set_en = WDT_WRITE_KEY|tmp;
86}
87
88static inline void __wdt_refresh_load_reg(void __iomem *base)
89{
90 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
91 unsigned int tmp=0;
92
93 tmp = wdt_reg->wdt_set_en;
94 tmp ^= 0xC;
95 wdt_reg->wdt_set_en = WDT_WRITE_KEY|tmp;
96}
97
98static inline void __wdt_refresh_int_value_reg(void __iomem *base)
99{
100 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
101 unsigned int tmp=0;
102
103 tmp = wdt_reg->wdt_set_en;
104 tmp ^= 0x3;
105 wdt_reg->wdt_set_en = WDT_WRITE_KEY|tmp;
106}
107
108static inline void __wdt_refresh_config_load_int_reg(void __iomem *base)
109{
110 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
111 unsigned int tmp=0;
112
113 tmp = wdt_reg->wdt_set_en;
114 tmp ^= 0x3f;
115 wdt_reg->wdt_set_en = WDT_WRITE_KEY|tmp;
116}
117
118static inline void __wdt_wait_value_loaded(void __iomem *base)
119{
120 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
121
122 while( (wdt_reg->wdt_status & 0x2)==0x0 );
123}
124
125/*
126 * set prescale, default is 0
127 * 1--div 2 2--div 3 ...
128 */
129static inline void __wdt_set_prescale(void __iomem *base, u32 prescale)
130{
131 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
132 unsigned int tmp = wdt_reg->wdt_config;
133
134 tmp &= WDT_PRESCALE(0xFF);
135 tmp |= WDT_PRESCALE(prescale);
136
137 wdt_reg->wdt_config = WDT_WRITE_KEY|tmp;
138
139 __wdt_refresh_config_reg(base);
140}
141
142static inline void __wdt_set_load(void __iomem *base, u32 load)
143{
144 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
145
146 wdt_reg->wdt_load = WDT_WRITE_KEY|load;
147
148 __wdt_refresh_load_reg(base);
149}
150
151static inline void __wdt_set_int_value(void __iomem *base, u32 int_value)
152{
153 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
154
155 wdt_reg->wdt_int_value = WDT_WRITE_KEY|int_value;
156
157 __wdt_refresh_int_value_reg(base);
158}
159
160static inline void __wdt_save_context(void __iomem *base, u32 *pointer)
161{
162 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
163 zx29_wdt_context *wdt_context = (zx29_wdt_context *)pointer;
164
165 wdt_context->wdt_config = wdt_reg->wdt_config;
166 wdt_context->wdt_load = wdt_reg->wdt_load;
167 wdt_context->wdt_int_value = wdt_reg->wdt_int_value;
168 wdt_context->wdt_start = wdt_reg->wdt_start;
169
170 if(wdt_context->wdt_start)
171 __wdt_stop(base);
172}
173
174static inline void __wdt_restore_context(void __iomem *base, u32 *pointer)
175{
176 zx29_wdt_registers *wdt_reg = (zx29_wdt_registers *)base;
177 zx29_wdt_context *wdt_context = (zx29_wdt_context *)pointer;
178
179 wdt_reg->wdt_config = wdt_context->wdt_config;
180 wdt_reg->wdt_load = wdt_context->wdt_load;
181 wdt_reg->wdt_int_value = wdt_context->wdt_int_value;
182
183 __wdt_refresh_config_load_int_reg(base);
184
185 if(wdt_context->wdt_start)
186 __wdt_start(base);
187}
188
189#endif
190
191