aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 501b596a4..fd9ecf69b 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 46d6bf173..361e39836 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 a02a2d89b..d420acd6b 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 000000000..3773a3b6e
--- /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);
+}