[U-Boot] arm, arm335x: add watchdog support
Michael Trimarchi
michael at amarulasolutions.com
Wed Jun 5 15:31:19 CEST 2013
Hi
On Jun 4, 2013 10:55 AM, "Heiko Schocher" <hs at denx.de> wrote:
>
> Add TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog support.
>
> Signed-off-by: Heiko Schocher <hs at denx.de>
> Cc: Albert Aribaud <albert.u.boot at aribaud.net>
> Cc: Tom Rini <trini at ti.com>
> ---
> arch/arm/include/asm/arch-am33xx/cpu.h | 20 ++++++
> drivers/watchdog/Makefile | 1 +
> drivers/watchdog/omap_wdt.c | 115
+++++++++++++++++++++++++++++++++
> 3 Dateien geändert, 136 Zeilen hinzugefügt(+)
> create mode 100644 drivers/watchdog/omap_wdt.c
>
> diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h
b/arch/arm/include/asm/arch-am33xx/cpu.h
> index 3d3a7c8..fb44654 100644
> --- a/arch/arm/include/asm/arch-am33xx/cpu.h
> +++ b/arch/arm/include/asm/arch-am33xx/cpu.h
> @@ -61,6 +61,26 @@
> #define PRM_RSTCTRL_RESET 0x01
> #define PRM_RSTST_WARM_RESET_MASK 0x232
>
> +/*
> + * Watchdog:
> + * Using the prescaler, the OMAP watchdog could go for many
> + * months before firing. These limits work without scaling,
> + * with the 60 second default assumed by most tools and docs.
> + */
> +#define TIMER_MARGIN_MAX (24 * 60 * 60) /* 1 day */
> +#define TIMER_MARGIN_DEFAULT 60 /* 60 secs */
> +#define TIMER_MARGIN_MIN 1
> +
> +#define PTV 0 /* prescale */
> +#define GET_WLDR_VAL(secs) (0xffffffff - ((secs) * (32768/(1<<PTV)))
+ 1)
> +#define WDT_WWPS_PEND_WCLR BIT(0)
> +#define WDT_WWPS_PEND_WLDR BIT(2)
> +#define WDT_WWPS_PEND_WTGR BIT(3)
> +#define WDT_WWPS_PEND_WSPR BIT(4)
> +
> +#define WDT_WCLR_PRE BIT(5)
> +#define WDT_WCLR_PTV_OFF 2
> +
> #ifndef __KERNEL_STRICT_NAMES
> #ifndef __ASSEMBLY__
> struct gpmc_cs {
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index d57578d..46adc42 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -34,6 +34,7 @@ COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
> COBJS-$(CONFIG_S5P) += s5p_wdt.o
> COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
> COBJS-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o
> +COBJS-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
>
> COBJS := $(COBJS-y)
> SRCS := $(COBJS:.o=.c)
> diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> new file mode 100644
> index 0000000..dc4df98
> --- /dev/null
> +++ b/drivers/watchdog/omap_wdt.c
> @@ -0,0 +1,115 @@
> +/*
> + * omap_wdt.c
> + *
> + * (C) Copyright 2013
> + * Heiko Schocher, DENX Software Engineering, hs at denx.de.
> + *
> + * Based on:
> + *
> + * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure)
watchdog
> + *
> + * Author: MontaVista Software, Inc.
> + * <gdavis at mvista.com> or <source at mvista.com>
> + *
> + * 2003 (c) MontaVista Software, Inc. This file is licensed under the
> + * terms of the GNU General Public License version 2. This program is
> + * licensed "as is" without any warranty of any kind, whether express
> + * or implied.
> + *
> + * History:
> + *
> + * 20030527: George G. Davis <gdavis at mvista.com>
> + * Initially based on
linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
> + * (c) Copyright 2000 Oleg Drokin <green at crimea.edu>
> + * Based on SoftDog driver by Alan Cox <alan at lxorguk.ukuu.org.uk>
> + *
> + * Copyright (c) 2004 Texas Instruments.
> + * 1. Modified to support OMAP1610 32-KHz watchdog timer
> + * 2. Ported to 2.6 kernel
> + *
> + * Copyright (c) 2005 David Brownell
> + * Use the driver model and standard identifiers; handle bigger
timeouts.
> + */
> +
> +#include <common.h>
> +#include <watchdog.h>
> +#include <asm/arch/hardware.h>
> +#include <asm/io.h>
> +#include <asm/processor.h>
> +#include <asm/arch/cpu.h>
> +
> +/* Hardware timeout in seconds */
> +#define WDT_HW_TIMEOUT 60
> +
> +static unsigned int wdt_trgr_pattern = 0x1234;
> +
> +void hw_watchdog_reset(void)
> +{
> + struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
> +
> + /* wait for posted write to complete */
> + while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
> + ;
> +
> + wdt_trgr_pattern = ~wdt_trgr_pattern;
> + writel(wdt_trgr_pattern, &wdt->wdtwtgr);
> +
> + /* wait for posted write to complete */
> + while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
> + ;
> +}
> +
I think that this patch has some problem because watchdog reset is in getc
code. Did you try to paste very long string when it is enabled? You need to
avoid reset when it is not needed
Michael
> +static int omap_wdt_set_timeout(unsigned int timeout)
> +{
> + struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
> + u32 pre_margin = GET_WLDR_VAL(timeout);
> +
> + /* just count up at 32 KHz */
> + while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
> + ;
> +
> + writel(pre_margin, &wdt->wdtwldr);
> + while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
> + ;
> +
> + return 0;
> +}
> +
> +void hw_watchdog_init(void)
> +{
> + struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
> +
> + /* initialize prescaler */
> + while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
> + ;
> +
> + writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
> + while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
> + ;
> +
> + omap_wdt_set_timeout(WDT_HW_TIMEOUT);
> +
> + /* Sequence to enable the watchdog */
> + writel(0xBBBB, &wdt->wdtwspr);
> + while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
> + ;
> +
> + writel(0x4444, &wdt->wdtwspr);
> + while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
> + ;
> +}
> +
> +void hw_watchdog_disable(void)
> +{
> + struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
> +
> + /*
> + * Disable watchdog
> + */
> + writel(0xAAAA, &wdt->wdtwspr);
> + while (readl(&wdt->wdtwwps) != 0x0)
> + ;
> + writel(0x5555, &wdt->wdtwspr);
> + while (readl(&wdt->wdtwwps) != 0x0)
> + ;
> +}
> --
> 1.7.11.7
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
More information about the U-Boot
mailing list