omap_wdt.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. #include <common.h>
  40. #include <watchdog.h>
  41. #include <asm/arch/hardware.h>
  42. #include <asm/io.h>
  43. #include <asm/processor.h>
  44. #include <asm/arch/cpu.h>
  45. /* Hardware timeout in seconds */
  46. #define WDT_HW_TIMEOUT 60
  47. static unsigned int wdt_trgr_pattern = 0x1234;
  48. void hw_watchdog_reset(void)
  49. {
  50. struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  51. /* wait for posted write to complete */
  52. while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
  53. ;
  54. wdt_trgr_pattern = ~wdt_trgr_pattern;
  55. writel(wdt_trgr_pattern, &wdt->wdtwtgr);
  56. /* wait for posted write to complete */
  57. while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
  58. ;
  59. }
  60. static int omap_wdt_set_timeout(unsigned int timeout)
  61. {
  62. struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  63. u32 pre_margin = GET_WLDR_VAL(timeout);
  64. /* just count up at 32 KHz */
  65. while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
  66. ;
  67. writel(pre_margin, &wdt->wdtwldr);
  68. while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
  69. ;
  70. return 0;
  71. }
  72. void hw_watchdog_init(void)
  73. {
  74. struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  75. /* initialize prescaler */
  76. while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
  77. ;
  78. writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
  79. while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
  80. ;
  81. omap_wdt_set_timeout(WDT_HW_TIMEOUT);
  82. /* Sequence to enable the watchdog */
  83. writel(0xBBBB, &wdt->wdtwspr);
  84. while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
  85. ;
  86. writel(0x4444, &wdt->wdtwspr);
  87. while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
  88. ;
  89. }
  90. void hw_watchdog_disable(void)
  91. {
  92. struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
  93. /*
  94. * Disable watchdog
  95. */
  96. writel(0xAAAA, &wdt->wdtwspr);
  97. while (readl(&wdt->wdtwwps) != 0x0)
  98. ;
  99. writel(0x5555, &wdt->wdtwspr);
  100. while (readl(&wdt->wdtwwps) != 0x0)
  101. ;
  102. }