[U-Boot] [PATCH 2/2] tegra: Add watchdog driver
Julian Scheel
julian at jusst.de
Mon May 2 13:36:06 CEST 2016
Add support for the tegra (t30 and newer) watchdog component.
Signed-off-by: Julian Scheel <julian at jusst.de>
---
arch/arm/include/asm/arch-tegra/tegra.h | 2 ++
arch/arm/include/asm/arch-tegra/wdt.h | 41 ++++++++++++++++++++++
arch/arm/mach-tegra/board2.c | 4 +++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/tegra_wdt.c | 60 +++++++++++++++++++++++++++++++++
5 files changed, 108 insertions(+)
create mode 100644 arch/arm/include/asm/arch-tegra/wdt.h
create mode 100644 drivers/watchdog/tegra_wdt.c
diff --git a/arch/arm/include/asm/arch-tegra/tegra.h b/arch/arm/include/asm/arch-tegra/tegra.h
index 3add1b3..790a7ae 100644
--- a/arch/arm/include/asm/arch-tegra/tegra.h
+++ b/arch/arm/include/asm/arch-tegra/tegra.h
@@ -11,6 +11,8 @@
#define NV_PA_ARM_PERIPHBASE 0x50040000
#define NV_PA_PG_UP_BASE 0x60000000
#define NV_PA_TMRUS_BASE 0x60005010
+#define NV_PA_TMR5_BASE 0x60005060
+#define NV_PA_TMRWDT0_BASE 0x60005100
#define NV_PA_CLK_RST_BASE 0x60006000
#define NV_PA_FLOW_BASE 0x60007000
#define NV_PA_GPIO_BASE 0x6000D000
diff --git a/arch/arm/include/asm/arch-tegra/wdt.h b/arch/arm/include/asm/arch-tegra/wdt.h
new file mode 100644
index 0000000..642b0b2
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra/wdt.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Avionic Design GmbH
+ * Copyright 2016 Julian Scheel <julian at jusst.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA_WDT_H_
+#define _TEGRA_WDT_H_
+
+struct wdt_ctrl {
+ u32 config;
+ u32 status;
+ u32 command;
+ u32 unlock;
+};
+
+#define WDT_CFG_SOURCE_MASK 0xf
+
+#define WDT_CFG_PERIOD_SHIFT 4
+#define WDT_CFG_PERIOD_MASK (0xff << WDT_CFG_PERIOD_SHIFT)
+
+#define WDT_CFG_PMC2CAR_RST_EN (1 << 15)
+
+#define WDT_STS_COUNT_SHIFT 4
+#define WDT_STS_COUNT_MASK (0xff << WDT_STS_COUNT_SHIFT)
+
+#define WDT_CMD_START_COUNTER (1 << 0)
+#define WDT_CMD_DISABLE_COUNTER (1 << 1)
+
+#define WDT_UNLOCK_PATTERN 0xc45a
+
+/* Timer registers */
+struct timer_ctrl {
+ u32 ptv;
+};
+
+#define TIMER_PTV_EN (1 << 31)
+#define TIMER_PTV_PERIODIC (1 << 30)
+
+#endif /* _TEGRA_WDT_H_ */
diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c
index 896c1cc..77426f3 100644
--- a/arch/arm/mach-tegra/board2.c
+++ b/arch/arm/mach-tegra/board2.c
@@ -124,6 +124,10 @@ int board_init(void)
tegra_gpu_config();
+#ifdef CONFIG_HW_WATCHDOG
+ hw_watchdog_init();
+#endif
+
#ifdef CONFIG_TEGRA_SPI
pin_mux_spi();
#endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a007ae8..e580e1b 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o
obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
+obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
new file mode 100644
index 0000000..70c0de7
--- /dev/null
+++ b/drivers/watchdog/tegra_wdt.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 Avionic Design GmbH
+ * Copyright 2016 Julian Scheel <julian at jusst.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/arch-tegra/wdt.h>
+#include <asm/arch-tegra/tegra.h>
+
+/* Timeout in seconds */
+#define WDT_TIMEOUT 60
+
+/* Timer to use - 5 is used in linux kernel */
+#define WDT_TIMER_ID 5
+void hw_watchdog_init(void)
+{
+ struct timer_ctrl *timer = (struct timer_ctrl *)NV_PA_TMR5_BASE;
+ struct wdt_ctrl *wdt = (struct wdt_ctrl *)NV_PA_TMRWDT0_BASE;
+ u32 val;
+
+ /* Timer runs fixed at 1 MHz, reset is triggered at 4th timeout of
+ * timer */
+ val = 1000000ul / 4;
+ val |= (TIMER_PTV_EN | TIMER_PTV_PERIODIC);
+ writel(val, &timer->ptv);
+
+ /* Setup actual wdt */
+ val = WDT_TIMER_ID |
+ ((WDT_TIMEOUT << WDT_CFG_PERIOD_SHIFT) & WDT_CFG_PERIOD_MASK) |
+ WDT_CFG_PMC2CAR_RST_EN;
+ writel(val, &wdt->config);
+
+ /* Activate the wdt */
+ writel(WDT_CMD_START_COUNTER, &wdt->command);
+}
+
+void hw_watchdog_reset(void)
+{
+ struct wdt_ctrl *wdt = (struct wdt_ctrl *)NV_PA_TMRWDT0_BASE;
+
+ /* Activate the wdt */
+ writel(WDT_CMD_START_COUNTER, &wdt->command);
+}
+
+void hw_watchdog_disable(void)
+{
+ struct timer_ctrl *timer = (struct timer_ctrl *)NV_PA_TMR5_BASE;
+ struct wdt_ctrl *wdt = (struct wdt_ctrl *)NV_PA_TMRWDT0_BASE;
+
+ /* Write unlock pattern */
+ writel(WDT_UNLOCK_PATTERN, &wdt->unlock);
+ /* Disable wdt */
+ writel(WDT_CMD_DISABLE_COUNTER, &wdt->command);
+ /* Stop timer */
+ writel(0, &timer->ptv);
+}
--
2.8.0
More information about the U-Boot
mailing list