ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/drivers/watchdog/Makefile b/marvell/uboot/drivers/watchdog/Makefile
new file mode 100644
index 0000000..06ced10
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/Makefile
@@ -0,0 +1,17 @@
+#
+# (C) Copyright 2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
+obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
+ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610))
+obj-y += imx_watchdog.o
+endif
+obj-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
+obj-$(CONFIG_S5P)               += s5p_wdt.o
+obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
+obj-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
+obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
diff --git a/marvell/uboot/drivers/watchdog/at91sam9_wdt.c b/marvell/uboot/drivers/watchdog/at91sam9_wdt.c
new file mode 100644
index 0000000..ffd49a2
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/at91sam9_wdt.c
@@ -0,0 +1,77 @@
+/*
+ * [origin: Linux kernel drivers/watchdog/at91sam9_wdt.c]
+ *
+ * Watchdog driver for Atmel AT91SAM9x processors.
+ *
+ * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * The Watchdog Timer Mode Register can be only written to once. If the
+ * timeout need to be set from U-Boot, be sure that the bootstrap doesn't
+ * write to this register. Inform Linux to it too
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/at91_wdt.h>
+
+/*
+ * AT91SAM9 watchdog runs a 12bit counter @ 256Hz,
+ * use this to convert a watchdog
+ * value from/to milliseconds.
+ */
+#define ms_to_ticks(t)	(((t << 8) / 1000) - 1)
+#define ticks_to_ms(t)	(((t + 1) * 1000) >> 8)
+
+/* Hardware timeout in seconds */
+#define WDT_HW_TIMEOUT 2
+
+/*
+ * Set the watchdog time interval in 1/256Hz (write-once)
+ * Counter is 12 bit.
+ */
+static int at91_wdt_settimeout(unsigned int timeout)
+{
+	unsigned int reg;
+	at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT;
+
+	/* Check if disabled */
+	if (readl(&wd->mr) & AT91_WDT_MR_WDDIS) {
+		printf("sorry, watchdog is disabled\n");
+		return -1;
+	}
+
+	/*
+	 * All counting occurs at SLOW_CLOCK / 128 = 256 Hz
+	 *
+	 * Since WDV is a 12-bit counter, the maximum period is
+	 * 4096 / 256 = 16 seconds.
+	 */
+
+	reg = AT91_WDT_MR_WDRSTEN		/* causes watchdog reset */
+		| AT91_WDT_MR_WDDBGHLT		/* disabled in debug mode */
+		| AT91_WDT_MR_WDD(0xfff)	/* restart at any time */
+		| AT91_WDT_MR_WDV(timeout);	/* timer value */
+
+	writel(reg, &wd->mr);
+
+	return 0;
+}
+
+void hw_watchdog_reset(void)
+{
+	at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT;
+	writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, &wd->cr);
+}
+
+void hw_watchdog_init(void)
+{
+	/* 16 seconds timer, resets enabled */
+	at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000));
+}
diff --git a/marvell/uboot/drivers/watchdog/bfin_wdt.c b/marvell/uboot/drivers/watchdog/bfin_wdt.c
new file mode 100644
index 0000000..7a6756b
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/bfin_wdt.c
@@ -0,0 +1,26 @@
+/*
+ * watchdog.c - driver for Blackfin on-chip watchdog
+ *
+ * Copyright (c) 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/watchdog.h>
+
+void hw_watchdog_reset(void)
+{
+	bfin_write_WDOG_STAT(0);
+}
+
+void hw_watchdog_init(void)
+{
+	bfin_write_WDOG_CTL(WDDIS);
+	SSYNC();
+	bfin_write_WDOG_CNT(CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000 * get_sclk());
+	hw_watchdog_reset();
+	bfin_write_WDOG_CTL(WDEN);
+}
diff --git a/marvell/uboot/drivers/watchdog/ftwdt010_wdt.c b/marvell/uboot/drivers/watchdog/ftwdt010_wdt.c
new file mode 100644
index 0000000..11f58f5
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/ftwdt010_wdt.c
@@ -0,0 +1,92 @@
+/*
+ * Watchdog driver for the FTWDT010 Watch Dog Driver
+ *
+ * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com)
+ * Based on sa1100_wdt.c by Oleg Drokin <green@crimea.edu>
+ * Based on SoftDog driver by Alan Cox <alan@redhat.com>
+ *
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * 27/11/2004 Initial release, Faraday.
+ * 12/01/2011 Port to u-boot, Macpaul Lin.
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <faraday/ftwdt010_wdt.h>
+
+/*
+ * Set the watchdog time interval.
+ * Counter is 32 bit.
+ */
+int ftwdt010_wdt_settimeout(unsigned int timeout)
+{
+	unsigned int reg;
+
+	struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE;
+
+	debug("Activating WDT..\n");
+
+	/* Check if disabled */
+	if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) {
+		printf("sorry, watchdog is disabled\n");
+		return -1;
+	}
+
+	/*
+	 * In a 66MHz system,
+	 * if you set WDLOAD as 0x03EF1480 (66000000)
+	 * the reset timer is 1 second.
+	 */
+	reg = FTWDT010_WDLOAD(timeout * FTWDT010_TIMEOUT_FACTOR);
+
+	writel(reg, &wd->wdload);
+
+	return 0;
+}
+
+void ftwdt010_wdt_reset(void)
+{
+	struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE;
+
+	/* clear control register */
+	writel(0, &wd->wdcr);
+
+	/* Write Magic number */
+	writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart);
+
+	/* Enable WDT */
+	writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr);
+}
+
+void ftwdt010_wdt_disable(void)
+{
+	struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE;
+
+	debug("Deactivating WDT..\n");
+
+	/*
+	 * It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux
+	 *
+	 * Shut off the timer.
+	 * Lock it in if it's a module and we defined ...NOWAYOUT
+	 */
+	writel(0, &wd->wdcr);
+}
+
+#if defined(CONFIG_HW_WATCHDOG)
+void hw_watchdog_reset(void)
+{
+	ftwdt010_wdt_reset();
+}
+
+void hw_watchdog_init(void)
+{
+	/* set timer in ms */
+	ftwdt010_wdt_settimeout(CONFIG_FTWDT010_HW_TIMEOUT * 1000);
+}
+#endif
diff --git a/marvell/uboot/drivers/watchdog/imx_watchdog.c b/marvell/uboot/drivers/watchdog/imx_watchdog.c
new file mode 100644
index 0000000..d5993b4
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/imx_watchdog.c
@@ -0,0 +1,67 @@
+/*
+ * watchdog.c - driver for i.mx on-chip watchdog
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <watchdog.h>
+#include <asm/arch/imx-regs.h>
+
+struct watchdog_regs {
+	u16	wcr;	/* Control */
+	u16	wsr;	/* Service */
+	u16	wrsr;	/* Reset Status */
+};
+
+#define WCR_WDZST	0x01
+#define WCR_WDBG	0x02
+#define WCR_WDE		0x04	/* WDOG enable */
+#define WCR_WDT		0x08
+#define WCR_SRS		0x10
+#define WCR_WDW		0x80
+#define SET_WCR_WT(x)	(x << 8)
+
+#ifdef CONFIG_IMX_WATCHDOG
+void hw_watchdog_reset(void)
+{
+	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+	writew(0x5555, &wdog->wsr);
+	writew(0xaaaa, &wdog->wsr);
+}
+
+void hw_watchdog_init(void)
+{
+	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+	u16 timeout;
+
+	/*
+	 * The timer watchdog can be set between
+	 * 0.5 and 128 Seconds. If not defined
+	 * in configuration file, sets 128 Seconds
+	 */
+#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
+#define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
+#endif
+	timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1;
+	writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS |
+		WCR_WDW | SET_WCR_WT(timeout), &wdog->wcr);
+	hw_watchdog_reset();
+}
+#endif
+
+void reset_cpu(ulong addr)
+{
+	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+	writew(WCR_WDE, &wdog->wcr);
+	writew(0x5555, &wdog->wsr);
+	writew(0xaaaa, &wdog->wsr);	/* load minimum 1/2 second timeout */
+	while (1) {
+		/*
+		 * spin for .5 seconds before reset
+		 */
+	}
+}
diff --git a/marvell/uboot/drivers/watchdog/omap_wdt.c b/marvell/uboot/drivers/watchdog/omap_wdt.c
new file mode 100644
index 0000000..7ea4b60
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/omap_wdt.c
@@ -0,0 +1,121 @@
+/*
+ * omap_wdt.c
+ *
+ * (C) Copyright 2013
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ *
+ * Based on:
+ *
+ * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
+ *
+ * commit 2d991a164a61858012651e13c59521975504e260
+ * Author: Bill Pemberton <wfp5p@virginia.edu>
+ * Date:   Mon Nov 19 13:21:41 2012 -0500
+ *
+ * watchdog: remove use of __devinit
+ *
+ * CONFIG_HOTPLUG is going away as an option so __devinit is no longer
+ * needed.
+ *
+ * Author: MontaVista Software, Inc.
+ *	 <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * History:
+ *
+ * 20030527: George G. Davis <gdavis@mvista.com>
+ *	Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
+ *	(c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ *	Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * Copyright (c) 2004 Texas Instruments.
+ *	1. Modified to support OMAP1610 32-KHz watchdog timer
+ *	2. Ported to 2.6 kernel
+ *
+ * Copyright (c) 2005 David Brownell
+ *	Use the driver model and standard identifiers; handle bigger timeouts.
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/cpu.h>
+
+/* Hardware timeout in seconds */
+#define WDT_HW_TIMEOUT 60
+
+static unsigned int wdt_trgr_pattern = 0x1234;
+
+void hw_watchdog_reset(void)
+{
+	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+	/* wait for posted write to complete */
+	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+		;
+
+	wdt_trgr_pattern = ~wdt_trgr_pattern;
+	writel(wdt_trgr_pattern, &wdt->wdtwtgr);
+
+	/* wait for posted write to complete */
+	while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
+		;
+}
+
+static int omap_wdt_set_timeout(unsigned int timeout)
+{
+	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+	u32 pre_margin = GET_WLDR_VAL(timeout);
+
+	/* just count up at 32 KHz */
+	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
+		;
+
+	writel(pre_margin, &wdt->wdtwldr);
+	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
+		;
+
+	return 0;
+}
+
+void hw_watchdog_init(void)
+{
+	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+	/* initialize prescaler */
+	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
+		;
+
+	writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
+	while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
+		;
+
+	omap_wdt_set_timeout(WDT_HW_TIMEOUT);
+
+	/* Sequence to enable the watchdog */
+	writel(0xBBBB, &wdt->wdtwspr);
+	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
+		;
+
+	writel(0x4444, &wdt->wdtwspr);
+	while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
+		;
+}
+
+void hw_watchdog_disable(void)
+{
+	struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+	/*
+	 * Disable watchdog
+	 */
+	writel(0xAAAA, &wdt->wdtwspr);
+	while (readl(&wdt->wdtwwps) != 0x0)
+		;
+	writel(0x5555, &wdt->wdtwspr);
+	while (readl(&wdt->wdtwwps) != 0x0)
+		;
+}
diff --git a/marvell/uboot/drivers/watchdog/s5p_wdt.c b/marvell/uboot/drivers/watchdog/s5p_wdt.c
new file mode 100644
index 0000000..a6e54d9
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/s5p_wdt.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/watchdog.h>
+
+#define PRESCALER_VAL 255
+
+void wdt_stop(void)
+{
+	struct s5p_watchdog *wdt =
+		(struct s5p_watchdog *)samsung_get_base_watchdog();
+	unsigned int wtcon;
+
+	wtcon = readl(&wdt->wtcon);
+	wtcon &= ~(WTCON_EN | WTCON_INT | WTCON_RESET);
+
+	writel(wtcon, &wdt->wtcon);
+}
+
+void wdt_start(unsigned int timeout)
+{
+	struct s5p_watchdog *wdt =
+		(struct s5p_watchdog *)samsung_get_base_watchdog();
+	unsigned int wtcon;
+
+	wdt_stop();
+
+	wtcon = readl(&wdt->wtcon);
+	wtcon |= (WTCON_EN | WTCON_CLK(WTCON_CLK_128));
+	wtcon &= ~WTCON_INT;
+	wtcon |= WTCON_RESET;
+	wtcon |= WTCON_PRESCALER(PRESCALER_VAL);
+
+	writel(timeout, &wdt->wtdat);
+	writel(timeout, &wdt->wtcnt);
+	writel(wtcon, &wdt->wtcon);
+}
diff --git a/marvell/uboot/drivers/watchdog/tnetv107x_wdt.c b/marvell/uboot/drivers/watchdog/tnetv107x_wdt.c
new file mode 100644
index 0000000..3d3f366
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/tnetv107x_wdt.c
@@ -0,0 +1,165 @@
+/*
+ * TNETV107X: Watchdog timer implementation (for reset)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#define MAX_DIV		0xFFFE0001
+
+struct wdt_regs {
+	u32 kick_lock;
+#define KICK_LOCK_1	0x5555
+#define KICK_LOCK_2	0xaaaa
+	u32 kick;
+
+	u32 change_lock;
+#define CHANGE_LOCK_1	0x6666
+#define CHANGE_LOCK_2	0xbbbb
+	u32 change;
+
+	u32 disable_lock;
+#define DISABLE_LOCK_1	0x7777
+#define DISABLE_LOCK_2	0xcccc
+#define DISABLE_LOCK_3	0xdddd
+	u32 disable;
+
+	u32 prescale_lock;
+#define PRESCALE_LOCK_1	0x5a5a
+#define PRESCALE_LOCK_2	0xa5a5
+	u32 prescale;
+};
+
+static struct wdt_regs* regs = (struct wdt_regs *)TNETV107X_WDT0_ARM_BASE;
+
+#define wdt_reg_read(reg)	__raw_readl(&regs->reg)
+#define wdt_reg_write(reg, val)	__raw_writel((val), &regs->reg)
+
+static int write_prescale_reg(unsigned long prescale_value)
+{
+	wdt_reg_write(prescale_lock, PRESCALE_LOCK_1);
+	if ((wdt_reg_read(prescale_lock) & 0x3) != 0x1)
+		return -1;
+
+	wdt_reg_write(prescale_lock, PRESCALE_LOCK_2);
+	if ((wdt_reg_read(prescale_lock) & 0x3) != 0x3)
+		return -1;
+
+	wdt_reg_write(prescale, prescale_value);
+
+	return 0;
+}
+
+static int write_change_reg(unsigned long initial_timer_value)
+{
+	wdt_reg_write(change_lock, CHANGE_LOCK_1);
+	if ((wdt_reg_read(change_lock) & 0x3) != 0x1)
+		return -1;
+
+	wdt_reg_write(change_lock, CHANGE_LOCK_2);
+	if ((wdt_reg_read(change_lock) & 0x3) != 0x3)
+		return -1;
+
+	wdt_reg_write(change, initial_timer_value);
+
+	return 0;
+}
+
+static int wdt_control(unsigned long disable_value)
+{
+	wdt_reg_write(disable_lock, DISABLE_LOCK_1);
+	if ((wdt_reg_read(disable_lock) & 0x3) != 0x1)
+		return -1;
+
+	wdt_reg_write(disable_lock, DISABLE_LOCK_2);
+	if ((wdt_reg_read(disable_lock) & 0x3) != 0x2)
+		return -1;
+
+	wdt_reg_write(disable_lock, DISABLE_LOCK_3);
+	if ((wdt_reg_read(disable_lock) & 0x3) != 0x3)
+		return -1;
+
+	wdt_reg_write(disable, disable_value);
+	return 0;
+}
+
+static int wdt_set_period(unsigned long msec)
+{
+	unsigned long change_value, count_value;
+	unsigned long prescale_value = 1;
+	unsigned long refclk_khz, maxdiv;
+	int ret;
+
+	refclk_khz = clk_get_rate(TNETV107X_LPSC_WDT_ARM);
+	maxdiv = (MAX_DIV / refclk_khz);
+
+	if ((!msec) || (msec > maxdiv))
+		return -1;
+
+	count_value = refclk_khz * msec;
+	if (count_value > 0xffff) {
+		change_value = count_value / 0xffff + 1;
+		prescale_value = count_value / change_value;
+	} else {
+		change_value = count_value;
+	}
+
+	ret = write_prescale_reg(prescale_value - 1);
+	if (ret)
+		return ret;
+
+	ret = write_change_reg(change_value);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+unsigned long last_wdt = -1;
+
+int wdt_start(unsigned long msecs)
+{
+	int ret;
+	ret = wdt_control(0);
+	if (ret)
+		return ret;
+	ret = wdt_set_period(msecs);
+	if (ret)
+		return ret;
+	ret = wdt_control(1);
+	if (ret)
+		return ret;
+	ret = wdt_kick();
+	last_wdt = msecs;
+	return ret;
+}
+
+int wdt_stop(void)
+{
+	last_wdt = -1;
+	return wdt_control(0);
+}
+
+int wdt_kick(void)
+{
+	wdt_reg_write(kick_lock, KICK_LOCK_1);
+	if ((wdt_reg_read(kick_lock) & 0x3) != 0x1)
+		return -1;
+
+	wdt_reg_write(kick_lock, KICK_LOCK_2);
+	if ((wdt_reg_read(kick_lock) & 0x3) != 0x3)
+		return -1;
+
+	wdt_reg_write(kick, 1);
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	clk_enable(TNETV107X_LPSC_WDT_ARM);
+	wdt_start(1);
+	wdt_kick();
+}
diff --git a/marvell/uboot/drivers/watchdog/xilinx_tb_wdt.c b/marvell/uboot/drivers/watchdog/xilinx_tb_wdt.c
new file mode 100644
index 0000000..6336c94
--- /dev/null
+++ b/marvell/uboot/drivers/watchdog/xilinx_tb_wdt.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011-2013 Xilinx Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/microblaze_intc.h>
+#include <asm/processor.h>
+#include <watchdog.h>
+
+#define XWT_CSR0_WRS_MASK	0x00000008 /* Reset status Mask */
+#define XWT_CSR0_WDS_MASK	0x00000004 /* Timer state Mask */
+#define XWT_CSR0_EWDT1_MASK	0x00000002 /* Enable bit 1 Mask*/
+#define XWT_CSRX_EWDT2_MASK	0x00000001 /* Enable bit 2 Mask */
+
+struct watchdog_regs {
+	u32 twcsr0; /* 0x0 */
+	u32 twcsr1; /* 0x4 */
+	u32 tbr; /* 0x8 */
+};
+
+static struct watchdog_regs *watchdog_base =
+			(struct watchdog_regs *)CONFIG_WATCHDOG_BASEADDR;
+
+void hw_watchdog_reset(void)
+{
+	u32 reg;
+
+	/* Read the current contents of TCSR0 */
+	reg = readl(&watchdog_base->twcsr0);
+
+	/* Clear the watchdog WDS bit */
+	if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK))
+		writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0);
+}
+
+void hw_watchdog_disable(void)
+{
+	u32 reg;
+
+	/* Read the current contents of TCSR0 */
+	reg = readl(&watchdog_base->twcsr0);
+
+	writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0);
+	writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1);
+
+	puts("Watchdog disabled!\n");
+}
+
+static void hw_watchdog_isr(void *arg)
+{
+	hw_watchdog_reset();
+}
+
+void hw_watchdog_init(void)
+{
+	int ret;
+
+	writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK),
+	       &watchdog_base->twcsr0);
+	writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1);
+
+	ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ,
+						hw_watchdog_isr, NULL);
+	if (ret)
+		puts("Watchdog IRQ registration failed.");
+}