]> git.sur5r.net Git - u-boot/blob - drivers/watchdog/tangier_wdt.c
efi_loader: efi_get_time_init should return status code
[u-boot] / drivers / watchdog / tangier_wdt.c
1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 #include <common.h>
7 #include <watchdog.h>
8 #include <asm/scu.h>
9
10 /* Hardware timeout in seconds */
11 #define WDT_PRETIMEOUT          15
12 #define WDT_TIMEOUT_MIN         (1 + WDT_PRETIMEOUT)
13 #define WDT_TIMEOUT_MAX         170
14 #define WDT_DEFAULT_TIMEOUT     90
15
16 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
17 #define WATCHDOG_HEARTBEAT 60000
18 #else
19 #define WATCHDOG_HEARTBEAT CONFIG_WATCHDOG_TIMEOUT_MSECS
20 #endif
21
22 enum {
23         SCU_WATCHDOG_START                      = 0,
24         SCU_WATCHDOG_STOP                       = 1,
25         SCU_WATCHDOG_KEEPALIVE                  = 2,
26         SCU_WATCHDOG_SET_ACTION_ON_TIMEOUT      = 3,
27 };
28
29 void hw_watchdog_reset(void)
30 {
31         static unsigned long last;
32         unsigned long now;
33
34         if (gd->timer)
35                 now = timer_get_us();
36         else
37                 now = rdtsc() / 1000;
38
39         /* Do not flood SCU */
40         if (last > now)
41                 last = 0;
42
43         if (unlikely((now - last) > (WDT_PRETIMEOUT / 2) * 1000000)) {
44                 last = now;
45                 scu_ipc_simple_command(IPCMSG_WATCHDOG_TIMER, SCU_WATCHDOG_KEEPALIVE);
46         }
47 }
48
49 int hw_watchdog_disable(void)
50 {
51         return scu_ipc_simple_command(IPCMSG_WATCHDOG_TIMER, SCU_WATCHDOG_STOP);
52 }
53
54 void hw_watchdog_init(void)
55 {
56         u32 timeout = WATCHDOG_HEARTBEAT / 1000;
57         int in_size;
58         struct ipc_wd_start {
59                 u32 pretimeout;
60                 u32 timeout;
61         } ipc_wd_start = { timeout - WDT_PRETIMEOUT, timeout };
62
63         /*
64          * SCU expects the input size for watchdog IPC
65          * to be based on 4 bytes
66          */
67         in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4);
68
69         scu_ipc_command(IPCMSG_WATCHDOG_TIMER, SCU_WATCHDOG_START,
70                         (u32 *)&ipc_wd_start, in_size, NULL, 0);
71 }