aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c')
-rw-r--r--roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c b/roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c
new file mode 100644
index 000000000..1687a4599
--- /dev/null
+++ b/roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx AXI platforms watchdog timer driver.
+ *
+ * Author(s): Michal Simek <michal.simek@xilinx.com>
+ * Shreenidhi Shedi <yesshedi@gmail.com>
+ *
+ * Copyright (c) 2011-2018 Xilinx Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <wdt.h>
+#include <linux/err.h>
+#include <linux/io.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 */
+};
+
+struct xlnx_wdt_plat {
+ bool enable_once;
+ struct watchdog_regs *regs;
+};
+
+static int xlnx_wdt_reset(struct udevice *dev)
+{
+ u32 reg;
+ struct xlnx_wdt_plat *plat = dev_get_plat(dev);
+
+ debug("%s ", __func__);
+
+ /* Read the current contents of TCSR0 */
+ reg = readl(&plat->regs->twcsr0);
+
+ /* Clear the watchdog WDS bit */
+ if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK))
+ writel(reg | XWT_CSR0_WDS_MASK, &plat->regs->twcsr0);
+
+ return 0;
+}
+
+static int xlnx_wdt_stop(struct udevice *dev)
+{
+ u32 reg;
+ struct xlnx_wdt_plat *plat = dev_get_plat(dev);
+
+ if (plat->enable_once) {
+ debug("Can't stop Xilinx watchdog.\n");
+ return -EBUSY;
+ }
+
+ /* Read the current contents of TCSR0 */
+ reg = readl(&plat->regs->twcsr0);
+
+ writel(reg & ~XWT_CSR0_EWDT1_MASK, &plat->regs->twcsr0);
+ writel(~XWT_CSRX_EWDT2_MASK, &plat->regs->twcsr1);
+
+ debug("Watchdog disabled!\n");
+
+ return 0;
+}
+
+static int xlnx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ struct xlnx_wdt_plat *plat = dev_get_plat(dev);
+
+ debug("%s:\n", __func__);
+
+ writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK),
+ &plat->regs->twcsr0);
+
+ writel(XWT_CSRX_EWDT2_MASK, &plat->regs->twcsr1);
+
+ return 0;
+}
+
+static int xlnx_wdt_probe(struct udevice *dev)
+{
+ debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
+
+ return 0;
+}
+
+static int xlnx_wdt_of_to_plat(struct udevice *dev)
+{
+ struct xlnx_wdt_plat *plat = dev_get_plat(dev);
+
+ plat->regs = (struct watchdog_regs *)dev_read_addr(dev);
+ if (IS_ERR(plat->regs))
+ return PTR_ERR(plat->regs);
+
+ plat->enable_once = dev_read_u32_default(dev, "xlnx,wdt-enable-once",
+ 0);
+
+ debug("%s: wdt-enable-once %d\n", __func__, plat->enable_once);
+
+ return 0;
+}
+
+static const struct wdt_ops xlnx_wdt_ops = {
+ .start = xlnx_wdt_start,
+ .reset = xlnx_wdt_reset,
+ .stop = xlnx_wdt_stop,
+};
+
+static const struct udevice_id xlnx_wdt_ids[] = {
+ { .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
+ { .compatible = "xlnx,xps-timebase-wdt-1.01.a", },
+ {},
+};
+
+U_BOOT_DRIVER(xlnx_wdt) = {
+ .name = "xlnx_wdt",
+ .id = UCLASS_WDT,
+ .of_match = xlnx_wdt_ids,
+ .probe = xlnx_wdt_probe,
+ .plat_auto = sizeof(struct xlnx_wdt_plat),
+ .of_to_plat = xlnx_wdt_of_to_plat,
+ .ops = &xlnx_wdt_ops,
+};