mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-13 21:36:57 +00:00
watchdog: omap_wdt: Convert watchdog driver to use DT and DM
This patch adds device tree and driver model watchdog support, converts the legacy omap watchdog driver to driver model for TI AM335x chipsets. The following compile warning is removed: ===================== WARNING ====================== This board does not use CONFIG_WDT (DM watchdog support). Please update the board to use CONFIG_WDT before the v2019.10 release. Failure to update by the deadline may result in board removal. See doc/driver-model/MIGRATION.txt for more info. ==================================================== CONFIG_HW_WATCHDOG is no more a default option for AM33XX devices after DT/DM conversion, adjusted kconfig accordingly. DM watchdog support is enabled by default in SPL. The SPL image doesn't fit into SRAM because of size constraints and build breaks with an overflow. For this reason DM watchdog support should be disabled in SPL, driver code should be adjusted accordingly to serve this purpose. Built and tested on AM335x device (BeagleboneBlack), compile tested for all other AM33xx based boards. Signed-off-by: Suniel Mahesh <sunil.m@techveda.org>
This commit is contained in:
parent
2800bb155b
commit
7659ea32a6
5 changed files with 130 additions and 1 deletions
|
@ -56,4 +56,9 @@ struct wd_timer {
|
|||
unsigned int wdt_unfr; /* offset 0x100 */
|
||||
};
|
||||
|
||||
struct omap3_wdt_priv {
|
||||
struct wd_timer *regs;
|
||||
unsigned int wdt_trgr_pattern;
|
||||
};
|
||||
|
||||
#endif /* __OMAP_WDT_H__ */
|
||||
|
|
|
@ -58,6 +58,8 @@ CONFIG_DM_SPI=y
|
|||
CONFIG_OMAP3_SPI=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_OMAP3=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_DM_USB_GADGET=y
|
||||
|
|
|
@ -28,7 +28,6 @@ config OMAP_WATCHDOG
|
|||
bool "TI OMAP watchdog driver"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
select HW_WATCHDOG
|
||||
default y if AM33XX
|
||||
help
|
||||
Say Y here to enable the OMAP3+ watchdog driver.
|
||||
|
||||
|
@ -113,6 +112,14 @@ config WDT_MTK
|
|||
The watchdog timer is stopped when initialized.
|
||||
It performs full SoC reset.
|
||||
|
||||
config WDT_OMAP3
|
||||
bool "TI OMAP watchdog timer support"
|
||||
depends on WDT && ARCH_OMAP2PLUS
|
||||
default y if AM33XX
|
||||
help
|
||||
This enables OMAP3+ watchdog timer driver, which can be
|
||||
found on some TI chipsets and inline with driver model.
|
||||
|
||||
config WDT_ORION
|
||||
bool "Orion watchdog timer support"
|
||||
depends on WDT
|
||||
|
|
|
@ -25,6 +25,7 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
|
|||
obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
|
||||
obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
|
||||
obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
|
||||
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
|
||||
obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
|
||||
obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
|
||||
obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
|
||||
|
|
|
@ -42,10 +42,14 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <wdt.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Hardware timeout in seconds */
|
||||
#define WDT_HW_TIMEOUT 60
|
||||
|
||||
#if !CONFIG_IS_ENABLED(WDT)
|
||||
static unsigned int wdt_trgr_pattern = 0x1234;
|
||||
|
||||
void hw_watchdog_reset(void)
|
||||
|
@ -134,3 +138,113 @@ void hw_watchdog_init(void)
|
|||
while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
|
||||
;
|
||||
}
|
||||
#else
|
||||
static int omap3_wdt_reset(struct udevice *dev)
|
||||
{
|
||||
struct omap3_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->wdt_trgr_pattern = 0x1234;
|
||||
/*
|
||||
* Somebody just triggered watchdog reset and write to WTGR register
|
||||
* is in progress. It is resetting right now, no need to trigger it
|
||||
* again
|
||||
*/
|
||||
if ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
|
||||
return 0;
|
||||
|
||||
priv->wdt_trgr_pattern = ~(priv->wdt_trgr_pattern);
|
||||
writel(priv->wdt_trgr_pattern, &priv->regs->wdtwtgr);
|
||||
/*
|
||||
* Don't wait for posted write to complete, i.e. don't check
|
||||
* WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to
|
||||
* WTGR register outside of this func, and if entering it
|
||||
* we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset
|
||||
* was just triggered. This prevents us from wasting time in busy
|
||||
* polling of WDT_WWPS_PEND_WTGR bit.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_wdt_stop(struct udevice *dev)
|
||||
{
|
||||
struct omap3_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
/* disable watchdog */
|
||||
writel(0xAAAA, &priv->regs->wdtwspr);
|
||||
while (readl(&priv->regs->wdtwwps) != 0x0)
|
||||
;
|
||||
writel(0x5555, &priv->regs->wdtwspr);
|
||||
while (readl(&priv->regs->wdtwwps) != 0x0)
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
|
||||
{
|
||||
struct omap3_wdt_priv *priv = dev_get_priv(dev);
|
||||
u32 pre_margin = GET_WLDR_VAL(timeout_ms);
|
||||
/*
|
||||
* Make sure the watchdog is disabled. This is unfortunately required
|
||||
* because writing to various registers with the watchdog running has no
|
||||
* effect.
|
||||
*/
|
||||
omap3_wdt_stop(dev);
|
||||
|
||||
/* initialize prescaler */
|
||||
while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR)
|
||||
;
|
||||
|
||||
writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &priv->regs->wdtwclr);
|
||||
while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR)
|
||||
;
|
||||
/* just count up at 32 KHz */
|
||||
while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR)
|
||||
;
|
||||
|
||||
writel(pre_margin, &priv->regs->wdtwldr);
|
||||
while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR)
|
||||
;
|
||||
/* Sequence to enable the watchdog */
|
||||
writel(0xBBBB, &priv->regs->wdtwspr);
|
||||
while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
|
||||
;
|
||||
|
||||
writel(0x4444, &priv->regs->wdtwspr);
|
||||
while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_wdt_probe(struct udevice *dev)
|
||||
{
|
||||
struct omap3_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->regs = (struct wd_timer *)devfdt_get_addr(dev);
|
||||
if (!priv->regs)
|
||||
return -EINVAL;
|
||||
|
||||
debug("%s: Probing wdt%u\n", __func__, dev->seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct wdt_ops omap3_wdt_ops = {
|
||||
.start = omap3_wdt_start,
|
||||
.stop = omap3_wdt_stop,
|
||||
.reset = omap3_wdt_reset,
|
||||
};
|
||||
|
||||
static const struct udevice_id omap3_wdt_ids[] = {
|
||||
{ .compatible = "ti,omap3-wdt" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(omap3_wdt) = {
|
||||
.name = "omap3_wdt",
|
||||
.id = UCLASS_WDT,
|
||||
.of_match = omap3_wdt_ids,
|
||||
.ops = &omap3_wdt_ops,
|
||||
.probe = omap3_wdt_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct omap3_wdt_priv),
|
||||
};
|
||||
#endif /* !CONFIG_IS_ENABLED(WDT) */
|
||||
|
|
Loading…
Add table
Reference in a new issue