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