uboot/drivers/watchdog/omap_wdt.c
<<
>>
Prefs
   1/*
   2 * omap_wdt.c
   3 *
   4 * (C) Copyright 2013
   5 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0
   8 *
   9 * Based on:
  10 *
  11 * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
  12 *
  13 * commit 2d991a164a61858012651e13c59521975504e260
  14 * Author: Bill Pemberton <wfp5p@virginia.edu>
  15 * Date:   Mon Nov 19 13:21:41 2012 -0500
  16 *
  17 * watchdog: remove use of __devinit
  18 *
  19 * CONFIG_HOTPLUG is going away as an option so __devinit is no longer
  20 * needed.
  21 *
  22 * Author: MontaVista Software, Inc.
  23 *       <gdavis@mvista.com> or <source@mvista.com>
  24 *
  25 * History:
  26 *
  27 * 20030527: George G. Davis <gdavis@mvista.com>
  28 *      Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
  29 *      (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
  30 *      Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
  31 *
  32 * Copyright (c) 2004 Texas Instruments.
  33 *      1. Modified to support OMAP1610 32-KHz watchdog timer
  34 *      2. Ported to 2.6 kernel
  35 *
  36 * Copyright (c) 2005 David Brownell
  37 *      Use the driver model and standard identifiers; handle bigger timeouts.
  38 */
  39
  40#include <common.h>
  41#include <watchdog.h>
  42#include <asm/arch/hardware.h>
  43#include <asm/io.h>
  44#include <asm/processor.h>
  45#include <asm/arch/cpu.h>
  46
  47/* Hardware timeout in seconds */
  48#define WDT_HW_TIMEOUT 60
  49
  50static unsigned int wdt_trgr_pattern = 0x1234;
  51
  52void hw_watchdog_reset(void)
  53{
  54        struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  55
  56        /* wait for posted write to complete */
  57        while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
  58                ;
  59
  60        wdt_trgr_pattern = ~wdt_trgr_pattern;
  61        writel(wdt_trgr_pattern, &wdt->wdtwtgr);
  62
  63        /* wait for posted write to complete */
  64        while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
  65                ;
  66}
  67
  68static int omap_wdt_set_timeout(unsigned int timeout)
  69{
  70        struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  71        u32 pre_margin = GET_WLDR_VAL(timeout);
  72
  73        /* just count up at 32 KHz */
  74        while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
  75                ;
  76
  77        writel(pre_margin, &wdt->wdtwldr);
  78        while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
  79                ;
  80
  81        return 0;
  82}
  83
  84void hw_watchdog_init(void)
  85{
  86        struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  87
  88        /* initialize prescaler */
  89        while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
  90                ;
  91
  92        writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
  93        while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
  94                ;
  95
  96        omap_wdt_set_timeout(WDT_HW_TIMEOUT);
  97
  98        /* Sequence to enable the watchdog */
  99        writel(0xBBBB, &wdt->wdtwspr);
 100        while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
 101                ;
 102
 103        writel(0x4444, &wdt->wdtwspr);
 104        while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
 105                ;
 106}
 107
 108void hw_watchdog_disable(void)
 109{
 110        struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
 111
 112        /*
 113         * Disable watchdog
 114         */
 115        writel(0xAAAA, &wdt->wdtwspr);
 116        while (readl(&wdt->wdtwwps) != 0x0)
 117                ;
 118        writel(0x5555, &wdt->wdtwspr);
 119        while (readl(&wdt->wdtwwps) != 0x0)
 120                ;
 121}
 122