aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Simek <michal.simek@xilinx.com>2021-06-28 13:44:16 +0200
committerMichal Simek <michal.simek@xilinx.com>2021-07-01 09:25:06 +0200
commit76bf8f3e44813bb6f5e57860dbfe51aa27ea5e91 (patch)
tree9fae152d7e5cf609ab149cd1ad38a4392db3040a
parent6e257c69fb6fc72f345586bb8309371b09757618 (diff)
downloadu-boot-76bf8f3e44813bb6f5e57860dbfe51aa27ea5e91.zip
u-boot-76bf8f3e44813bb6f5e57860dbfe51aa27ea5e91.tar.gz
u-boot-76bf8f3e44813bb6f5e57860dbfe51aa27ea5e91.tar.bz2
watchdog: cadence: Add expire_now method
It is working in a way that only minimal timeout is setup to reach expiration just right after it is setup. Please make sure that PMUFW is compiled with ENABLE_EM flag. On U-Boot prompt you can test it like: ZynqMP> wdt dev watchdog@fd4d0000 ZynqMP> wdt list watchdog@fd4d0000 (cdns_wdt) ZynqMP> wdt dev dev: watchdog@fd4d0000 ZynqMP> wdt expire (And reset should happen here) Signed-off-by: Michal Simek <michal.simek@xilinx.com>
-rw-r--r--drivers/watchdog/cdns_wdt.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c
index 966d010..6dfdd31 100644
--- a/drivers/watchdog/cdns_wdt.c
+++ b/drivers/watchdog/cdns_wdt.c
@@ -215,6 +215,45 @@ static int cdns_wdt_stop(struct udevice *dev)
}
/**
+ * cdns_wdt_expire_now - Expire the watchdog.
+ *
+ * @dev: Watchdog device
+ * @flags: Driver flags
+ *
+ * Access WDT and configure with minimal counter value to expire ASAP.
+ * Expiration issues system reset. When DEBUG is enabled count should be
+ * bigger to at least see debug message.
+ *
+ * Return: Always 0
+ */
+static int cdns_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ struct cdns_wdt_priv *priv = dev_get_priv(dev);
+ u32 data, count = 0;
+
+#if defined(DEBUG)
+ count = 0x40; /* Increase the value if you need more time */
+ debug("%s: Expire wdt%u\n", __func__, dev_seq(dev));
+#endif
+
+ cdns_wdt_writereg(&priv->regs->zmr, CDNS_WDT_ZMR_ZKEY_VAL);
+
+ count = (count << 2) & CDNS_WDT_CCR_CRV_MASK;
+
+ /* Write counter access key first to be able write to register */
+ data = count | CDNS_WDT_REGISTER_ACCESS_KEY;
+ cdns_wdt_writereg(&priv->regs->ccr, data);
+
+ data = CDNS_WDT_ZMR_WDEN_MASK | CDNS_WDT_ZMR_RSTEN_MASK |
+ CDNS_WDT_ZMR_ZKEY_VAL;
+
+ cdns_wdt_writereg(&priv->regs->zmr, data);
+ cdns_wdt_writereg(&priv->regs->restart, CDNS_WDT_RESTART_KEY);
+
+ return 0;
+}
+
+/**
* cdns_wdt_probe - Probe call for the device.
*
* @dev: Handle to the udevice structure.
@@ -247,7 +286,7 @@ static const struct wdt_ops cdns_wdt_ops = {
.start = cdns_wdt_start,
.reset = cdns_wdt_reset,
.stop = cdns_wdt_stop,
- /* There is no bit/reg/support in IP for expire_now functionality */
+ .expire_now = cdns_wdt_expire_now,
};
static const struct udevice_id cdns_wdt_ids[] = {