Message ID | 5e8e740265b6910d99339f23439b746e694fe62f.1624887918.git.michal.simek@xilinx.com |
---|---|
State | Accepted |
Commit | 76bf8f3e44813bb6f5e57860dbfe51aa27ea5e91 |
Delegated to: | Michal Simek |
Headers | show |
Series | watchdog: cadence: Add expire_now method | expand |
po 28. 6. 2021 v 15:45 odesÃlatel Michal Simek <michal.simek@xilinx.com> napsal: > > 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> > --- > > drivers/watchdog/cdns_wdt.c | 41 ++++++++++++++++++++++++++++++++++++- > 1 file changed, 40 insertions(+), 1 deletion(-) > > diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c > index 966d010e40d9..6dfdd31c8b8f 100644 > --- a/drivers/watchdog/cdns_wdt.c > +++ b/drivers/watchdog/cdns_wdt.c > @@ -214,6 +214,45 @@ static int cdns_wdt_stop(struct udevice *dev) > return 0; > } > > +/** > + * 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. > * > @@ -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[] = { > -- > 2.32.0 > Applied. M
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c index 966d010e40d9..6dfdd31c8b8f 100644 --- a/drivers/watchdog/cdns_wdt.c +++ b/drivers/watchdog/cdns_wdt.c @@ -214,6 +214,45 @@ static int cdns_wdt_stop(struct udevice *dev) return 0; } +/** + * 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. * @@ -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[] = {
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> --- drivers/watchdog/cdns_wdt.c | 41 ++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-)