uboot/drivers/watchdog/ulp_wdog.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2016 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <cpu_func.h>
   8#include <asm/io.h>
   9#include <asm/arch/imx-regs.h>
  10
  11/*
  12 * MX7ULP WDOG Register Map
  13 */
  14struct wdog_regs {
  15        u32 cs;
  16        u32 cnt;
  17        u32 toval;
  18        u32 win;
  19};
  20
  21#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
  22#define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500
  23#endif
  24
  25#define REFRESH_WORD0 0xA602 /* 1st refresh word */
  26#define REFRESH_WORD1 0xB480 /* 2nd refresh word */
  27
  28#define UNLOCK_WORD0 0xC520 /* 1st unlock word */
  29#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
  30
  31#define WDGCS_WDGE                      BIT(7)
  32#define WDGCS_WDGUPDATE                 BIT(5)
  33
  34#define WDGCS_RCS                       BIT(10)
  35#define WDGCS_ULK                       BIT(11)
  36#define WDGCS_FLG                       BIT(14)
  37
  38#define WDG_BUS_CLK                      (0x0)
  39#define WDG_LPO_CLK                      (0x1)
  40#define WDG_32KHZ_CLK                    (0x2)
  41#define WDG_EXT_CLK                      (0x3)
  42
  43void hw_watchdog_set_timeout(u16 val)
  44{
  45        /* setting timeout value */
  46        struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
  47
  48        writel(val, &wdog->toval);
  49}
  50
  51void hw_watchdog_reset(void)
  52{
  53        struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
  54
  55        dmb();
  56        __raw_writel(REFRESH_WORD0, &wdog->cnt);
  57        __raw_writel(REFRESH_WORD1, &wdog->cnt);
  58        dmb();
  59}
  60
  61void hw_watchdog_init(void)
  62{
  63        struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
  64
  65        dmb();
  66        __raw_writel(UNLOCK_WORD0, &wdog->cnt);
  67        __raw_writel(UNLOCK_WORD1, &wdog->cnt);
  68        dmb();
  69
  70        /* Wait WDOG Unlock */
  71        while (!(readl(&wdog->cs) & WDGCS_ULK))
  72                ;
  73
  74        hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
  75        writel(0, &wdog->win);
  76
  77        /* setting 1-kHz clock source, enable counter running, and clear interrupt */
  78        writel((WDGCS_WDGE | WDGCS_WDGUPDATE |(WDG_LPO_CLK << 8) | WDGCS_FLG), &wdog->cs);
  79
  80        /* Wait WDOG reconfiguration */
  81        while (!(readl(&wdog->cs) & WDGCS_RCS))
  82                ;
  83
  84        hw_watchdog_reset();
  85}
  86
  87void reset_cpu(void)
  88{
  89        struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
  90
  91        dmb();
  92        __raw_writel(UNLOCK_WORD0, &wdog->cnt);
  93        __raw_writel(UNLOCK_WORD1, &wdog->cnt);
  94        dmb();
  95
  96        /* Wait WDOG Unlock */
  97        while (!(readl(&wdog->cs) & WDGCS_ULK))
  98                ;
  99
 100        hw_watchdog_set_timeout(5); /* 5ms timeout */
 101        writel(0, &wdog->win);
 102
 103        /* enable counter running */
 104        writel((WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);
 105
 106        /* Wait WDOG reconfiguration */
 107        while (!(readl(&wdog->cs) & WDGCS_RCS))
 108                ;
 109
 110        hw_watchdog_reset();
 111
 112        while (1);
 113}
 114