aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2020-03-26 16:17:01 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2020-06-08 16:36:28 -0700
commit8dcb737745c41222683b9c556c77c030de28e5bf (patch)
treec18379cc3f9c956bb430bde5f845e3dff9ec3679
parentae045908b4d757ce30ee4fc3aab77ca9afa5cf00 (diff)
downloadtf-a-tests-8dcb737745c41222683b9c556c77c030de28e5bf.tar.gz
Tegra194: introduce watchdog timer
This patch adds support for WDT0 that is connected to CPU0 to act as the watchdog timer for Tegra194 platforms. The watchdog timer uses TMR0 as the source and fires if the CPU is hung for more than 10 seconds. Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Change-Id: Ibe20c1130f86718b919c89436d7f5f49b74d9cc9
-rw-r--r--plat/nvidia/tegra194/include/platform_def.h2
-rw-r--r--plat/nvidia/tegra194/platform.mk3
-rw-r--r--plat/nvidia/tegra194/setup.c13
-rw-r--r--plat/nvidia/tegra194/watchdog.c92
4 files changed, 101 insertions, 9 deletions
diff --git a/plat/nvidia/tegra194/include/platform_def.h b/plat/nvidia/tegra194/include/platform_def.h
index 501b596..fd9ecf6 100644
--- a/plat/nvidia/tegra194/include/platform_def.h
+++ b/plat/nvidia/tegra194/include/platform_def.h
@@ -140,6 +140,8 @@
* Platform MMIO devices
******************************************************************************/
#define TEGRA194_MC_BASE U(0x02C10000)
+#define TEGRA194_TMR0_BASE U(0x03020000)
+#define TEGRA194_WDT0_BASE U(0x030c0000)
#define TEGRA194_GICD_BASE U(0x03881000)
#define TEGRA194_GICC_BASE U(0x03882000)
#define TEGRA194_SPE_BASE U(0x0C168000)
diff --git a/plat/nvidia/tegra194/platform.mk b/plat/nvidia/tegra194/platform.mk
index 46d6bf1..361e398 100644
--- a/plat/nvidia/tegra194/platform.mk
+++ b/plat/nvidia/tegra194/platform.mk
@@ -18,7 +18,8 @@ PLAT_SOURCES := drivers/arm/gic/arm_gic_v2.c \
plat/nvidia/tegra194/setup.c \
plat/nvidia/tegra194/topology.c \
plat/nvidia/tegra194/timers.c \
- plat/nvidia/tegra194/wake.c
+ plat/nvidia/tegra194/wake.c \
+ plat/nvidia/tegra194/watchdog.c
PLAT_TESTS_SKIP_LIST := plat/nvidia/tegra194/tests_to_skip.txt
diff --git a/plat/nvidia/tegra194/setup.c b/plat/nvidia/tegra194/setup.c
index a02a2d8..d420acd 100644
--- a/plat/nvidia/tegra194/setup.c
+++ b/plat/nvidia/tegra194/setup.c
@@ -14,18 +14,15 @@
#include <xlat_tables_v2.h>
/*
- * The memory map currently provides the following apertures
- *
- * GIC Distributor : 4KB
- * GIC CPU Interface : 4KB
- * UARTC for the console : 128KB
- * RTC : 4KB
- * us Timer : 4KB
- * DRAM aperture for NVM : 256MB
+ * Memory map
*/
static const mmap_region_t tegra194_mmap[] = {
MAP_REGION_FLAT(TEGRA194_MC_BASE, 0x2000, /* 8KB */
MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TEGRA194_TMR0_BASE, 0x1000, /* 4KB */
+ MT_DEVICE | MT_RW | MT_NS),
+ MAP_REGION_FLAT(TEGRA194_WDT0_BASE, 0x1000, /* 4KB */
+ MT_DEVICE | MT_RW | MT_NS),
MAP_REGION_FLAT(TEGRA194_GICD_BASE, 0x1000, /* 4KB */
MT_DEVICE | MT_RW | MT_NS),
MAP_REGION_FLAT(TEGRA194_GICC_BASE, 0x1000, /* 4KB */
diff --git a/plat/nvidia/tegra194/watchdog.c b/plat/nvidia/tegra194/watchdog.c
new file mode 100644
index 0000000..3773a3b
--- /dev/null
+++ b/plat/nvidia/tegra194/watchdog.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+
+/* Timer registers */
+#define TIMER_PTV U(0)
+ #define TIMER_EN_BIT BIT_32(31)
+ #define TIMER_PERIODIC_BIT BIT_32(30)
+#define TIMER_PCR U(0x4)
+ #define TIMER_PCR_INTR_BIT BIT_32(30)
+
+/* WDT registers */
+#define WDT_CFG U(0)
+ #define WDT_CFG_TMR_SRC U(0) /* for TMR0. */
+ #define WDT_CFG_PERIOD_BIT BIT_32(4)
+ #define WDT_CFG_INT_EN_BIT BIT_32(12)
+ #define WDT_CFG_SYS_RST_EN_BIT BIT_32(14)
+ #define WDT_CFG_PMC2CAR_RST_EN_BIT BIT_32(15)
+#define WDT_CMD U(8)
+ #define WDT_CMD_START_COUNTER_BIT BIT_32(0)
+ #define WDT_CMD_DISABLE_COUNTER_BIT BIT_32(1)
+#define WDT_UNLOCK U(0xC)
+ #define WDT_UNLOCK_PATTERN U(0xC45A)
+
+/* watchdog will fire after this timeout value is reached */
+#define WDT_TIMEOUT_SECONDS U(10)
+#define WDT_TIMEOUT_MULTIPLIER UL(125000)
+
+static inline void tegra194_wdt_write(uint32_t offset, uint32_t val)
+{
+ mmio_write_32(TEGRA194_WDT0_BASE + offset, val);
+}
+
+static inline uint32_t tegra194_wdt_read(uint32_t offset)
+{
+ return mmio_read_32(TEGRA194_WDT0_BASE + offset);
+}
+
+static inline void tegra194_tmr_write(uint32_t offset, uint32_t val)
+{
+ mmio_write_32(TEGRA194_TMR0_BASE + offset, val);
+}
+
+static inline uint32_t tegra194_tmr_read(uint32_t offset)
+{
+ return mmio_read_32(TEGRA194_TMR0_BASE + offset);
+}
+
+/*
+ * Start the watchdog timer
+ */
+void tftf_platform_watchdog_set(void)
+{
+ uint32_t val;
+
+ /* Clear pending interrupts first */
+ tegra194_tmr_write(TIMER_PCR, TIMER_PCR_INTR_BIT);
+
+ /*
+ * Normally, we would set the period to 1 second by writing 125000ul,
+ * but the watchdog system reset actually occurs on the 4th expiration
+ * of this counter, so we set the period to 1/4 of this amount.
+ */
+ val = (WDT_TIMEOUT_SECONDS * WDT_TIMEOUT_MULTIPLIER) / 4;
+ val |= (TIMER_EN_BIT | TIMER_PERIODIC_BIT);
+ tegra194_tmr_write(TIMER_PTV, val);
+
+ /*
+ * Set number of periods and start counter.
+ */
+ val = WDT_CFG_TMR_SRC | WDT_CFG_SYS_RST_EN_BIT |
+ WDT_CFG_PMC2CAR_RST_EN_BIT;
+ tegra194_wdt_write(WDT_CFG, val);
+ tegra194_wdt_write(WDT_CMD, WDT_CMD_START_COUNTER_BIT);
+}
+
+/*
+ * Stop the watchdog timer
+ */
+void tftf_platform_watchdog_reset(void)
+{
+ tegra194_tmr_write(TIMER_PCR, TIMER_PCR_INTR_BIT);
+ tegra194_wdt_write(WDT_UNLOCK, WDT_UNLOCK_PATTERN);
+ tegra194_wdt_write(WDT_CMD, WDT_CMD_DISABLE_COUNTER_BIT);
+ tegra194_tmr_write(TIMER_PTV, 0);
+}