Add support for the tegra (t30 and newer) watchdog component.

Signed-off-by: Julian Scheel <jul...@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 <jul...@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 <jul...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to