Merge git://git.denx.de/u-boot-socfpga
[platform/kernel/u-boot.git] / drivers / watchdog / designware_wdt.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2013 Altera Corporation <www.altera.com>
4  */
5
6 #include <common.h>
7 #include <watchdog.h>
8 #include <asm/io.h>
9 #include <asm/utils.h>
10
11 #define DW_WDT_CR       0x00
12 #define DW_WDT_TORR     0x04
13 #define DW_WDT_CRR      0x0C
14
15 #define DW_WDT_CR_EN_OFFSET     0x00
16 #define DW_WDT_CR_RMOD_OFFSET   0x01
17 #define DW_WDT_CR_RMOD_VAL      0x00
18 #define DW_WDT_CRR_RESTART_VAL  0x76
19
20 /*
21  * Set the watchdog time interval.
22  * Counter is 32 bit.
23  */
24 static int designware_wdt_settimeout(unsigned int timeout)
25 {
26         signed int i;
27
28         /* calculate the timeout range value */
29         i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16;
30         if (i > 15)
31                 i = 15;
32         if (i < 0)
33                 i = 0;
34
35         writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
36         return 0;
37 }
38
39 static void designware_wdt_enable(void)
40 {
41         writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
42               (0x1 << DW_WDT_CR_EN_OFFSET)),
43               (CONFIG_DW_WDT_BASE + DW_WDT_CR));
44 }
45
46 static unsigned int designware_wdt_is_enabled(void)
47 {
48         unsigned long val;
49         val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
50         return val & 0x1;
51 }
52
53 #if defined(CONFIG_HW_WATCHDOG)
54 void hw_watchdog_reset(void)
55 {
56         if (designware_wdt_is_enabled())
57                 /* restart the watchdog counter */
58                 writel(DW_WDT_CRR_RESTART_VAL,
59                        (CONFIG_DW_WDT_BASE + DW_WDT_CRR));
60 }
61
62 void hw_watchdog_init(void)
63 {
64         /* reset to disable the watchdog */
65         hw_watchdog_reset();
66         /* set timer in miliseconds */
67         designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
68         /* enable the watchdog */
69         designware_wdt_enable();
70         /* reset the watchdog */
71         hw_watchdog_reset();
72 }
73 #endif