summaryrefslogtreecommitdiff
path: root/drivers/watchdog/designware_wdt.c
diff options
context:
space:
mode:
authorChin Liang See <clsee@altera.com>2014-06-10 01:10:21 -0500
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-07-05 00:24:16 +0200
commitd8c67dc6e1f861bcf6e61c0b67782fbac2e0a010 (patch)
tree78fe2e1133108456374c7e6b4fbd492188827a70 /drivers/watchdog/designware_wdt.c
parent7237d22baac9ebeffc946dfd30b9f61aaf0bfdbc (diff)
downloadu-boot-imx-d8c67dc6e1f861bcf6e61c0b67782fbac2e0a010.zip
u-boot-imx-d8c67dc6e1f861bcf6e61c0b67782fbac2e0a010.tar.gz
u-boot-imx-d8c67dc6e1f861bcf6e61c0b67782fbac2e0a010.tar.bz2
watchdog/denali: Adding DesignWare watchdog driver support
To add the DesignWare watchdog driver support. It required information such as register base address and clock info from configuration header file within include/configs folder. Signed-off-by: Chin Liang See <clsee@altera.com> Cc: Anatolij Gustschin <agust@denx.de> Cc: Albert Aribaud <albert.u.boot@aribaud.net> Cc: Heiko Schocher <hs@denx.de> Cc: Tom Rini <trini@ti.com>
Diffstat (limited to 'drivers/watchdog/designware_wdt.c')
-rw-r--r--drivers/watchdog/designware_wdt.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
new file mode 100644
index 0000000..e788e1b
--- /dev/null
+++ b/drivers/watchdog/designware_wdt.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/utils.h>
+
+#define DW_WDT_CR 0x00
+#define DW_WDT_TORR 0x04
+#define DW_WDT_CRR 0x0C
+
+#define DW_WDT_CR_EN_OFFSET 0x00
+#define DW_WDT_CR_RMOD_OFFSET 0x01
+#define DW_WDT_CR_RMOD_VAL 0x00
+#define DW_WDT_CRR_RESTART_VAL 0x76
+
+/*
+ * Set the watchdog time interval.
+ * Counter is 32 bit.
+ */
+static int designware_wdt_settimeout(unsigned int timeout)
+{
+ signed int i;
+
+ /* calculate the timeout range value */
+ i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16;
+ if (i > 15)
+ i = 15;
+ if (i < 0)
+ i = 0;
+
+ writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
+ return 0;
+}
+
+static void designware_wdt_enable(void)
+{
+ writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
+ (0x1 << DW_WDT_CR_EN_OFFSET)),
+ (CONFIG_DW_WDT_BASE + DW_WDT_CR));
+}
+
+static unsigned int designware_wdt_is_enabled(void)
+{
+ unsigned long val;
+ val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
+ return val & 0x1;
+}
+
+#if defined(CONFIG_HW_WATCHDOG)
+void hw_watchdog_reset(void)
+{
+ if (designware_wdt_is_enabled())
+ /* restart the watchdog counter */
+ writel(DW_WDT_CRR_RESTART_VAL,
+ (CONFIG_DW_WDT_BASE + DW_WDT_CRR));
+}
+
+void hw_watchdog_init(void)
+{
+ /* reset to disable the watchdog */
+ hw_watchdog_reset();
+ /* set timer in miliseconds */
+ designware_wdt_settimeout(CONFIG_HW_WATCHDOG_TIMEOUT_MS);
+ /* enable the watchdog */
+ designware_wdt_enable();
+ /* reset the watchdog */
+ hw_watchdog_reset();
+}
+#endif