3535
3636#define RTIWWDRX_NMI 0xa
3737
38- #define RTIWWDSIZE_50P 0x50
38+ #define RTIWWDSIZE_50P 0x50
39+ #define RTIWWDSIZE_25P 0x500
40+ #define RTIWWDSIZE_12P5 0x5000
41+ #define RTIWWDSIZE_6P25 0x50000
42+ #define RTIWWDSIZE_3P125 0x500000
3943
4044#define WDENABLE_KEY 0xa98559da
4145
4852
4953#define DWDST BIT(1)
5054
51- static int heartbeat ;
55+ static int heartbeat = DEFAULT_HEARTBEAT ;
5256
5357/*
5458 * struct to hold data for each WDT device
@@ -79,11 +83,9 @@ static int rti_wdt_start(struct watchdog_device *wdd)
7983 * be petted during the open window; not too early or not too late.
8084 * The HW configuration options only allow for the open window size
8185 * to be 50% or less than that; we obviouly want to configure the open
82- * window as large as possible so we select the 50% option. To avoid
83- * any glitches, we accommodate 5% safety margin also, so we setup
84- * the min_hw_hearbeat at 55% of the timeout period.
86+ * window as large as possible so we select the 50% option.
8587 */
86- wdd -> min_hw_heartbeat_ms = 11 * wdd -> timeout * 1000 / 20 ;
88+ wdd -> min_hw_heartbeat_ms = 500 * wdd -> timeout ;
8789
8890 /* Generate NMI when wdt expires */
8991 writel_relaxed (RTIWWDRX_NMI , wdt -> base + RTIWWDRXCTRL );
@@ -110,7 +112,48 @@ static int rti_wdt_ping(struct watchdog_device *wdd)
110112 return 0 ;
111113}
112114
113- static unsigned int rti_wdt_get_timeleft (struct watchdog_device * wdd )
115+ static int rti_wdt_setup_hw_hb (struct watchdog_device * wdd , u32 wsize )
116+ {
117+ /*
118+ * RTI only supports a windowed mode, where the watchdog can only
119+ * be petted during the open window; not too early or not too late.
120+ * The HW configuration options only allow for the open window size
121+ * to be 50% or less than that.
122+ */
123+ switch (wsize ) {
124+ case RTIWWDSIZE_50P :
125+ /* 50% open window => 50% min heartbeat */
126+ wdd -> min_hw_heartbeat_ms = 500 * heartbeat ;
127+ break ;
128+
129+ case RTIWWDSIZE_25P :
130+ /* 25% open window => 75% min heartbeat */
131+ wdd -> min_hw_heartbeat_ms = 750 * heartbeat ;
132+ break ;
133+
134+ case RTIWWDSIZE_12P5 :
135+ /* 12.5% open window => 87.5% min heartbeat */
136+ wdd -> min_hw_heartbeat_ms = 875 * heartbeat ;
137+ break ;
138+
139+ case RTIWWDSIZE_6P25 :
140+ /* 6.5% open window => 93.5% min heartbeat */
141+ wdd -> min_hw_heartbeat_ms = 935 * heartbeat ;
142+ break ;
143+
144+ case RTIWWDSIZE_3P125 :
145+ /* 3.125% open window => 96.9% min heartbeat */
146+ wdd -> min_hw_heartbeat_ms = 969 * heartbeat ;
147+ break ;
148+
149+ default :
150+ return - EINVAL ;
151+ }
152+
153+ return 0 ;
154+ }
155+
156+ static unsigned int rti_wdt_get_timeleft_ms (struct watchdog_device * wdd )
114157{
115158 u64 timer_counter ;
116159 u32 val ;
@@ -123,11 +166,18 @@ static unsigned int rti_wdt_get_timeleft(struct watchdog_device *wdd)
123166
124167 timer_counter = readl_relaxed (wdt -> base + RTIDWDCNTR );
125168
169+ timer_counter *= 1000 ;
170+
126171 do_div (timer_counter , wdt -> freq );
127172
128173 return timer_counter ;
129174}
130175
176+ static unsigned int rti_wdt_get_timeleft (struct watchdog_device * wdd )
177+ {
178+ return rti_wdt_get_timeleft_ms (wdd ) / 1000 ;
179+ }
180+
131181static const struct watchdog_info rti_wdt_info = {
132182 .options = WDIOF_KEEPALIVEPING ,
133183 .identity = "K3 RTI Watchdog" ,
@@ -148,6 +198,7 @@ static int rti_wdt_probe(struct platform_device *pdev)
148198 struct watchdog_device * wdd ;
149199 struct rti_wdt_device * wdt ;
150200 struct clk * clk ;
201+ u32 last_ping = 0 ;
151202
152203 wdt = devm_kzalloc (dev , sizeof (* wdt ), GFP_KERNEL );
153204 if (!wdt )
@@ -169,6 +220,14 @@ static int rti_wdt_probe(struct platform_device *pdev)
169220 return - EINVAL ;
170221 }
171222
223+ /*
224+ * If watchdog is running at 32k clock, it is not accurate.
225+ * Adjust frequency down in this case so that we don't pet
226+ * the watchdog too often.
227+ */
228+ if (wdt -> freq < 32768 )
229+ wdt -> freq = wdt -> freq * 9 / 10 ;
230+
172231 pm_runtime_enable (dev );
173232 ret = pm_runtime_get_sync (dev );
174233 if (ret ) {
@@ -185,11 +244,8 @@ static int rti_wdt_probe(struct platform_device *pdev)
185244 wdd -> min_timeout = 1 ;
186245 wdd -> max_hw_heartbeat_ms = (WDT_PRELOAD_MAX << WDT_PRELOAD_SHIFT ) /
187246 wdt -> freq * 1000 ;
188- wdd -> timeout = DEFAULT_HEARTBEAT ;
189247 wdd -> parent = dev ;
190248
191- watchdog_init_timeout (wdd , heartbeat , dev );
192-
193249 watchdog_set_drvdata (wdd , wdt );
194250 watchdog_set_nowayout (wdd , 1 );
195251 watchdog_set_restart_priority (wdd , 128 );
@@ -201,12 +257,48 @@ static int rti_wdt_probe(struct platform_device *pdev)
201257 goto err_iomap ;
202258 }
203259
260+ if (readl (wdt -> base + RTIDWDCTRL ) == WDENABLE_KEY ) {
261+ u32 time_left_ms ;
262+ u64 heartbeat_ms ;
263+ u32 wsize ;
264+
265+ set_bit (WDOG_HW_RUNNING , & wdd -> status );
266+ time_left_ms = rti_wdt_get_timeleft_ms (wdd );
267+ heartbeat_ms = readl (wdt -> base + RTIDWDPRLD );
268+ heartbeat_ms <<= WDT_PRELOAD_SHIFT ;
269+ heartbeat_ms *= 1000 ;
270+ do_div (heartbeat_ms , wdt -> freq );
271+ if (heartbeat_ms != heartbeat * 1000 )
272+ dev_warn (dev , "watchdog already running, ignoring heartbeat config!\n" );
273+
274+ heartbeat = heartbeat_ms ;
275+ heartbeat /= 1000 ;
276+
277+ wsize = readl (wdt -> base + RTIWWDSIZECTRL );
278+ ret = rti_wdt_setup_hw_hb (wdd , wsize );
279+ if (ret ) {
280+ dev_err (dev , "bad window size.\n" );
281+ goto err_iomap ;
282+ }
283+
284+ last_ping = heartbeat_ms - time_left_ms ;
285+ if (time_left_ms > heartbeat_ms ) {
286+ dev_warn (dev , "time_left > heartbeat? Assuming last ping just before now.\n" );
287+ last_ping = 0 ;
288+ }
289+ }
290+
291+ watchdog_init_timeout (wdd , heartbeat , dev );
292+
204293 ret = watchdog_register_device (wdd );
205294 if (ret ) {
206295 dev_err (dev , "cannot register watchdog device\n" );
207296 goto err_iomap ;
208297 }
209298
299+ if (last_ping )
300+ watchdog_set_last_hw_keepalive (wdd , last_ping );
301+
210302 return 0 ;
211303
212304err_iomap :
0 commit comments