On 27/12/2016 11:04, Peng Fan wrote: > From: Ye Li <[email protected]> > > This driver implements the HW WATCHDOG functions. Which needs > to set CONFIG_HW_WATCHDOG to use them. This is disabled by default for > mx7ulp. > > Use watchdog for reset cpu. Implement this in the driver. > Need to define CONFIG_ULP_WATCHDOG to build it. > > Signed-off-by: Peng Fan <[email protected]> > Signed-off-by: Ye Li <[email protected]> > Cc: Stefano Babic <[email protected]> > --- > > V2: > Add License > > drivers/watchdog/Kconfig | 8 ++++ > drivers/watchdog/Makefile | 1 + > drivers/watchdog/ulp_wdog.c | 98 > +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 107 insertions(+) > create mode 100644 drivers/watchdog/ulp_wdog.c > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > index e69de29..dbdaafc 100644 > --- a/drivers/watchdog/Kconfig > +++ b/drivers/watchdog/Kconfig > @@ -0,0 +1,8 @@ > +menu "WATCHDOG support" > + > +config ULP_WATCHDOG > + bool "i.MX7ULP watchdog" > + help > + Say Y here to enable i.MX7ULP watchdog driver. > + > +endmenu > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > index a007ae8..dea1836 100644 > --- a/drivers/watchdog/Makefile > +++ b/drivers/watchdog/Makefile > @@ -15,3 +15,4 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o > obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o > obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o > obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o > +obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o > diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c > new file mode 100644 > index 0000000..72ec694 > --- /dev/null > +++ b/drivers/watchdog/ulp_wdog.c > @@ -0,0 +1,98 @@ > +/* > + * Copyright (C) 2016 Freescale Semiconductor, Inc. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <asm/io.h> > +#include <asm/arch/imx-regs.h> > + > +/* > + * MX7ULP WDOG Register Map > + */ > +struct wdog_regs { > + u8 cs1; > + u8 cs2; > + u16 reserve0; > + u32 cnt; > + u32 toval; > + u32 win; > +}; > + > +#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS > +#define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500 > +#endif > + > +#define REFRESH_WORD0 0xA602 /* 1st refresh word */ > +#define REFRESH_WORD1 0xB480 /* 2nd refresh word */ > + > +#define UNLOCK_WORD0 0xC520 /* 1st unlock word */ > +#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ > + > +#define WDGCS1_WDGE (1<<7) > +#define WDGCS1_WDGUPDATE (1<<5) > + > +#define WDGCS2_FLG (1<<6) > + > +#define WDG_BUS_CLK (0x0) > +#define WDG_LPO_CLK (0x1) > +#define WDG_32KHZ_CLK (0x2) > +#define WDG_EXT_CLK (0x3) > + > +DECLARE_GLOBAL_DATA_PTR; > + > +void hw_watchdog_set_timeout(u16 val) > +{ > + /* setting timeout value */ > + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; > + > + writel(val, &wdog->toval); > +} > + > +void hw_watchdog_reset(void) > +{ > + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; > + > + writel(REFRESH_WORD0, &wdog->cnt); > + writel(REFRESH_WORD1, &wdog->cnt); > +} > + > +void hw_watchdog_init(void) > +{ > + u8 val; > + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; > + > + writel(UNLOCK_WORD0, &wdog->cnt); > + writel(UNLOCK_WORD1, &wdog->cnt); > + > + val = readb(&wdog->cs2); > + val |= WDGCS2_FLG; > + writeb(val, &wdog->cs2); > + > + hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); > + writel(0, &wdog->win); > + > + writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ > + writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter > running */ > + > + hw_watchdog_reset(); > +} > + > +void reset_cpu(ulong addr) > +{ > + struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; > + > + writel(UNLOCK_WORD0, &wdog->cnt); > + writel(UNLOCK_WORD1, &wdog->cnt); > + > + hw_watchdog_set_timeout(5); /* 5ms timeout */ > + writel(0, &wdog->win); > + > + writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ > + writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */ > + > + hw_watchdog_reset(); > + > + while (1); > +} >
This goes into drivers/watchdog, and it slightly differs from the implementation in imx-watchdog.c. Code is quite simple, too, I think it could be merged into the same file. Best regards, Stefano Babic -- ===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: [email protected] ===================================================================== _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

