tangier_wdt.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2017 Intel Corporation
  4. */
  5. #include <common.h>
  6. #include <watchdog.h>
  7. #include <asm/scu.h>
  8. /* Hardware timeout in seconds */
  9. #define WDT_PRETIMEOUT 15
  10. #define WDT_TIMEOUT_MIN (1 + WDT_PRETIMEOUT)
  11. #define WDT_TIMEOUT_MAX 170
  12. #define WDT_DEFAULT_TIMEOUT 90
  13. #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
  14. #define WATCHDOG_HEARTBEAT 60000
  15. #else
  16. #define WATCHDOG_HEARTBEAT CONFIG_WATCHDOG_TIMEOUT_MSECS
  17. #endif
  18. enum {
  19. SCU_WATCHDOG_START = 0,
  20. SCU_WATCHDOG_STOP = 1,
  21. SCU_WATCHDOG_KEEPALIVE = 2,
  22. SCU_WATCHDOG_SET_ACTION_ON_TIMEOUT = 3,
  23. };
  24. void hw_watchdog_reset(void)
  25. {
  26. static unsigned long last;
  27. unsigned long now;
  28. if (gd->timer)
  29. now = timer_get_us();
  30. else
  31. now = rdtsc() / 1000;
  32. /* Do not flood SCU */
  33. if (last > now)
  34. last = 0;
  35. if (unlikely((now - last) > (WDT_PRETIMEOUT / 2) * 1000000)) {
  36. last = now;
  37. scu_ipc_simple_command(IPCMSG_WATCHDOG_TIMER, SCU_WATCHDOG_KEEPALIVE);
  38. }
  39. }
  40. int hw_watchdog_disable(void)
  41. {
  42. return scu_ipc_simple_command(IPCMSG_WATCHDOG_TIMER, SCU_WATCHDOG_STOP);
  43. }
  44. void hw_watchdog_init(void)
  45. {
  46. u32 timeout = WATCHDOG_HEARTBEAT / 1000;
  47. int in_size;
  48. struct ipc_wd_start {
  49. u32 pretimeout;
  50. u32 timeout;
  51. } ipc_wd_start = { timeout - WDT_PRETIMEOUT, timeout };
  52. /*
  53. * SCU expects the input size for watchdog IPC
  54. * to be based on 4 bytes
  55. */
  56. in_size = DIV_ROUND_UP(sizeof(ipc_wd_start), 4);
  57. scu_ipc_command(IPCMSG_WATCHDOG_TIMER, SCU_WATCHDOG_START,
  58. (u32 *)&ipc_wd_start, in_size, NULL, 0);
  59. }