diff options
-rw-r--r-- | plat/nvidia/tegra194/include/platform_def.h | 2 | ||||
-rw-r--r-- | plat/nvidia/tegra194/platform.mk | 3 | ||||
-rw-r--r-- | plat/nvidia/tegra194/setup.c | 13 | ||||
-rw-r--r-- | plat/nvidia/tegra194/watchdog.c | 92 |
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); +} |