diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
index 44bedd8b67..2e4468e8d8 100644
--- a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
@@ -56,3 +56,7 @@
 &portc {
 	bank-name = "portc";
 };
+
+&watchdog0 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
index e1cfb522bf..a41db08dd4 100755
--- a/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
@@ -23,3 +23,7 @@
 	spi-rx-bus-width = <4>;
 	u-boot,dm-pre-reloc;
 };
+
+&watchdog0 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/configs/socfpga_stratix10_defconfig b/configs/socfpga_stratix10_defconfig
index 82ffedf41a..29466d0c09 100644
--- a/configs/socfpga_stratix10_defconfig
+++ b/configs/socfpga_stratix10_defconfig
@@ -60,3 +60,5 @@ CONFIG_USB_DWC2=y
 CONFIG_USB_STORAGE=y
 # CONFIG_SPL_USE_TINY_PRINTF is not set
 CONFIG_DESIGNWARE_WATCHDOG=y
+CONFIG_WDT=y
+# CONFIG_SPL_WDT is not set
diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig
index 0e31e4f165..39be88b9b7 100644
--- a/configs/socfpga_vining_fpga_defconfig
+++ b/configs/socfpga_vining_fpga_defconfig
@@ -97,4 +97,5 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 # CONFIG_SPL_WDT is not set
+CONFIG_WDT=y
 CONFIG_DESIGNWARE_WATCHDOG=y
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5f8a070ef5..bf5612a811 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -47,7 +47,7 @@ config ULP_WATCHDOG
 
 config DESIGNWARE_WATCHDOG
 	bool "Designware watchdog timer support"
-	select HW_WATCHDOG
+	select HW_WATCHDOG if !WDT
 	help
 	   Enable this to support Designware Watchdog Timer IP, present e.g.
 	   on Altera SoCFPGA SoCs.
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
index c668567c66..a7b735979a 100644
--- a/drivers/watchdog/designware_wdt.c
+++ b/drivers/watchdog/designware_wdt.c
@@ -4,7 +4,8 @@
  */
 
 #include <common.h>
-#include <watchdog.h>
+#include <dm.h>
+#include <wdt.h>
 #include <asm/io.h>
 #include <asm/utils.h>
 
@@ -17,46 +18,51 @@
 #define DW_WDT_CR_RMOD_VAL	0x00
 #define DW_WDT_CRR_RESTART_VAL	0x76
 
+struct designware_wdt_priv {
+	void __iomem	*base;
+};
+
 /*
  * Set the watchdog time interval.
  * Counter is 32 bit.
  */
-static int designware_wdt_settimeout(unsigned int timeout)
+static int designware_wdt_settimeout(void __iomem *base, unsigned int clk_khz,
+				     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;
+	i = log_2_n_round_up(timeout * clk_khz) - 16;
+	i = clamp(i, 0, 15);
+
+	writel(i | (i << 4), base + DW_WDT_TORR);
 
-	writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
 	return 0;
 }
 
-static void designware_wdt_enable(void)
+static void designware_wdt_enable(void __iomem *base)
 {
-	writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
-	      (0x1 << DW_WDT_CR_EN_OFFSET)),
-	      (CONFIG_DW_WDT_BASE + DW_WDT_CR));
+	writel((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
+		BIT(DW_WDT_CR_EN_OFFSET),
+		base + DW_WDT_CR);
 }
 
-static unsigned int designware_wdt_is_enabled(void)
+static unsigned int designware_wdt_is_enabled(void __iomem *base)
 {
-	unsigned long val;
-	val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
-	return val & 0x1;
+	return readl(base + DW_WDT_CR) & BIT(0);
 }
 
-#if defined(CONFIG_HW_WATCHDOG)
-void hw_watchdog_reset(void)
+static void designware_wdt_reset_common(void __iomem *base)
 {
-	if (designware_wdt_is_enabled())
+	if (designware_wdt_is_enabled(base))
 		/* restart the watchdog counter */
-		writel(DW_WDT_CRR_RESTART_VAL,
-		       (CONFIG_DW_WDT_BASE + DW_WDT_CRR));
+		writel(DW_WDT_CRR_RESTART_VAL, base + DW_WDT_CRR);
+}
+
+#if !CONFIG_IS_ENABLED(WDT)
+void hw_watchdog_reset(void)
+{
+	designware_wdt_reset_common((void __iomem *)CONFIG_DW_WDT_BASE);
 }
 
 void hw_watchdog_init(void)
@@ -64,10 +70,80 @@ void hw_watchdog_init(void)
 	/* reset to disable the watchdog */
 	hw_watchdog_reset();
 	/* set timer in miliseconds */
-	designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
+	designware_wdt_settimeout((void __iomem *)CONFIG_DW_WDT_BASE,
+				  CONFIG_DW_WDT_CLOCK_KHZ,
+				  CONFIG_WATCHDOG_TIMEOUT_MSECS);
 	/* enable the watchdog */
-	designware_wdt_enable();
+	designware_wdt_enable((void __iomem *)CONFIG_DW_WDT_BASE);
 	/* reset the watchdog */
 	hw_watchdog_reset();
 }
+#else
+static int designware_wdt_reset(struct udevice *dev)
+{
+	struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+	designware_wdt_reset_common(priv->base);
+
+	return 0;
+}
+
+static int designware_wdt_stop(struct udevice *dev)
+{
+	struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+	designware_wdt_reset(dev);
+	writel(DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET,
+		priv->base + DW_WDT_CR);
+
+	return 0;
+}
+
+static int designware_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+	designware_wdt_stop(dev);
+
+	/* set timer in miliseconds */
+	designware_wdt_settimeout(priv->base, CONFIG_DW_WDT_CLOCK_KHZ, timeout);
+
+	designware_wdt_enable(priv->base);
+
+	/* reset the watchdog */
+	return designware_wdt_reset(dev);
+}
+
+static int designware_wdt_probe(struct udevice *dev)
+{
+	struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_remap_addr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	/* reset to disable the watchdog */
+	return designware_wdt_stop(dev);
+}
+
+static const struct wdt_ops designware_wdt_ops = {
+	.start = designware_wdt_start,
+	.reset = designware_wdt_reset,
+	.stop = designware_wdt_stop,
+};
+
+static const struct udevice_id designware_wdt_ids[] = {
+	{ .compatible = "snps,dw-wdt"},
+	{}
+};
+
+U_BOOT_DRIVER(designware_wdt) = {
+	.name = "designware_wdt",
+	.id = UCLASS_WDT,
+	.of_match = designware_wdt_ids,
+	.priv_auto_alloc_size = sizeof(struct designware_wdt_priv),
+	.probe = designware_wdt_probe,
+	.ops = &designware_wdt_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
 #endif
diff --git a/include/configs/socfpga_stratix10_socdk.h b/include/configs/socfpga_stratix10_socdk.h
index f7a4a30f3a..9e9209013a 100644
--- a/include/configs/socfpga_stratix10_socdk.h
+++ b/include/configs/socfpga_stratix10_socdk.h
@@ -151,6 +151,7 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
  * L4 Watchdog
  */
 #ifdef CONFIG_SPL_BUILD
+#undef CONFIG_WATCHDOG
 #define CONFIG_HW_WATCHDOG
 #else
 #undef CONFIG_HW_WATCHDOG
