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