diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/drivers/watchdog/xilinx_tb_wdt.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
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.c | 129 |
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, +}; |