blob: 8a8e55370a0e4725f57f1a272cb211f34dc1f74e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Michal Simek80e045f2013-04-22 11:23:16 +02002/*
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +05303 * Xilinx AXI platforms watchdog timer driver.
4 *
Michal Simeka8c94362023-07-10 14:35:49 +02005 * Author(s): Michal Simek <michal.simek@amd.com>
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +05306 * Shreenidhi Shedi <yesshedi@gmail.com>
7 *
8 * Copyright (c) 2011-2018 Xilinx Inc.
Michal Simek80e045f2013-04-22 11:23:16 +02009 */
10
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053011#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060012#include <log.h>
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053013#include <wdt.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070014#include <linux/err.h>
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053015#include <linux/io.h>
Michal Simek80e045f2013-04-22 11:23:16 +020016
17#define XWT_CSR0_WRS_MASK 0x00000008 /* Reset status Mask */
18#define XWT_CSR0_WDS_MASK 0x00000004 /* Timer state Mask */
19#define XWT_CSR0_EWDT1_MASK 0x00000002 /* Enable bit 1 Mask*/
20#define XWT_CSRX_EWDT2_MASK 0x00000001 /* Enable bit 2 Mask */
21
22struct watchdog_regs {
23 u32 twcsr0; /* 0x0 */
24 u32 twcsr1; /* 0x4 */
25 u32 tbr; /* 0x8 */
26};
27
Simon Glassb75b15b2020-12-03 16:55:23 -070028struct xlnx_wdt_plat {
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053029 bool enable_once;
30 struct watchdog_regs *regs;
31};
Michal Simek80e045f2013-04-22 11:23:16 +020032
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053033static int xlnx_wdt_reset(struct udevice *dev)
Michal Simek80e045f2013-04-22 11:23:16 +020034{
35 u32 reg;
Simon Glassb75b15b2020-12-03 16:55:23 -070036 struct xlnx_wdt_plat *plat = dev_get_plat(dev);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053037
38 debug("%s ", __func__);
Michal Simek80e045f2013-04-22 11:23:16 +020039
40 /* Read the current contents of TCSR0 */
Simon Glass71fa5b42020-12-03 16:55:18 -070041 reg = readl(&plat->regs->twcsr0);
Michal Simek80e045f2013-04-22 11:23:16 +020042
43 /* Clear the watchdog WDS bit */
44 if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK))
Simon Glass71fa5b42020-12-03 16:55:18 -070045 writel(reg | XWT_CSR0_WDS_MASK, &plat->regs->twcsr0);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053046
47 return 0;
Michal Simek80e045f2013-04-22 11:23:16 +020048}
49
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053050static int xlnx_wdt_stop(struct udevice *dev)
Michal Simek80e045f2013-04-22 11:23:16 +020051{
52 u32 reg;
Simon Glassb75b15b2020-12-03 16:55:23 -070053 struct xlnx_wdt_plat *plat = dev_get_plat(dev);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053054
Simon Glass71fa5b42020-12-03 16:55:18 -070055 if (plat->enable_once) {
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053056 debug("Can't stop Xilinx watchdog.\n");
57 return -EBUSY;
58 }
Michal Simek80e045f2013-04-22 11:23:16 +020059
60 /* Read the current contents of TCSR0 */
Simon Glass71fa5b42020-12-03 16:55:18 -070061 reg = readl(&plat->regs->twcsr0);
Michal Simek80e045f2013-04-22 11:23:16 +020062
Simon Glass71fa5b42020-12-03 16:55:18 -070063 writel(reg & ~XWT_CSR0_EWDT1_MASK, &plat->regs->twcsr0);
64 writel(~XWT_CSRX_EWDT2_MASK, &plat->regs->twcsr1);
Michal Simek80e045f2013-04-22 11:23:16 +020065
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053066 debug("Watchdog disabled!\n");
67
68 return 0;
Michal Simek80e045f2013-04-22 11:23:16 +020069}
70
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053071static int xlnx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
Michal Simek80e045f2013-04-22 11:23:16 +020072{
Simon Glassb75b15b2020-12-03 16:55:23 -070073 struct xlnx_wdt_plat *plat = dev_get_plat(dev);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053074
75 debug("%s:\n", __func__);
76
77 writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK),
Simon Glass71fa5b42020-12-03 16:55:18 -070078 &plat->regs->twcsr0);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053079
Simon Glass71fa5b42020-12-03 16:55:18 -070080 writel(XWT_CSRX_EWDT2_MASK, &plat->regs->twcsr1);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053081
82 return 0;
Michal Simek80e045f2013-04-22 11:23:16 +020083}
84
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053085static int xlnx_wdt_probe(struct udevice *dev)
Michal Simek80e045f2013-04-22 11:23:16 +020086{
Simon Glass75e534b2020-12-16 21:20:07 -070087 debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
Michal Simek80e045f2013-04-22 11:23:16 +020088
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053089 return 0;
90}
Michal Simek80e045f2013-04-22 11:23:16 +020091
Simon Glassaad29ae2020-12-03 16:55:21 -070092static int xlnx_wdt_of_to_plat(struct udevice *dev)
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053093{
Simon Glassb75b15b2020-12-03 16:55:23 -070094 struct xlnx_wdt_plat *plat = dev_get_plat(dev);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053095
Johan Jonker8d5d8e02023-03-13 01:32:04 +010096 plat->regs = dev_read_addr_ptr(dev);
97 if (!plat->regs)
98 return -EINVAL;
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +053099
Simon Glass71fa5b42020-12-03 16:55:18 -0700100 plat->enable_once = dev_read_u32_default(dev, "xlnx,wdt-enable-once",
101 0);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +0530102
Simon Glass71fa5b42020-12-03 16:55:18 -0700103 debug("%s: wdt-enable-once %d\n", __func__, plat->enable_once);
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +0530104
105 return 0;
Michal Simek80e045f2013-04-22 11:23:16 +0200106}
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +0530107
108static const struct wdt_ops xlnx_wdt_ops = {
109 .start = xlnx_wdt_start,
110 .reset = xlnx_wdt_reset,
111 .stop = xlnx_wdt_stop,
112};
113
114static const struct udevice_id xlnx_wdt_ids[] = {
115 { .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
116 { .compatible = "xlnx,xps-timebase-wdt-1.01.a", },
117 {},
118};
119
120U_BOOT_DRIVER(xlnx_wdt) = {
121 .name = "xlnx_wdt",
122 .id = UCLASS_WDT,
123 .of_match = xlnx_wdt_ids,
124 .probe = xlnx_wdt_probe,
Simon Glassb75b15b2020-12-03 16:55:23 -0700125 .plat_auto = sizeof(struct xlnx_wdt_plat),
Simon Glassaad29ae2020-12-03 16:55:21 -0700126 .of_to_plat = xlnx_wdt_of_to_plat,
Shreenidhi Shedi335fb5b2018-07-15 02:05:41 +0530127 .ops = &xlnx_wdt_ops,
128};