From c70073ef67e5148f4869f62e765863617ea1f4e4 Mon Sep 17 00:00:00 2001
From: David Brownell <dbrownell@users.sourceforge.net>
Date: Mon, 19 Oct 2009 22:50:51 -0700
Subject: [PATCH] davinci: add watchdog reset method

Lightly tested on dm365.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
---
 tcl/target/davinci.cfg | 63 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/tcl/target/davinci.cfg b/tcl/target/davinci.cfg
index 658e7fe5b..e1eb48f59 100644
--- a/tcl/target/davinci.cfg
+++ b/tcl/target/davinci.cfg
@@ -33,7 +33,7 @@ proc mmw {reg setbits clearbits} {
 #
 
 # PLL version 0x02: tested on dm355
-# REVISIT:  On dm6446 and dm357 the PLLRST polarity is different.
+# REVISIT:  On dm6446/dm357 the PLLRST polarity is different.
 proc pll_v02_setup {pll_addr mult config} {
 	set pll_ctrl_addr [expr $pll_addr + 0x100]
 	set pll_ctrl [mrw $pll_ctrl_addr]
@@ -174,3 +174,64 @@ proc psc_go {} {
 	# wait for PTSTAT.go to clear (again ignoring DSP power domain)
 	while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
 }
+
+#
+# A reset using only SRST is a "Warm Reset", resetting everything in the
+# chip except ARM emulation (and everything _outside_ the chip that hooks
+# up to SRST).  But many boards don't expose SRST via their JTAG connectors
+# (it's not present on TI-14 headers).
+#
+# From the chip-only perspective, a "Max Reset" is a "Warm" reset ... except
+# without any board-wide side effects, since it's triggered using JTAG using
+# either (a) ARM watchdog timer, or (b) ICEpick.
+#
+proc davinci_wdog_reset {} {
+	set timer2_phys 0x01c21c00
+
+	# NOTE -- on entry
+	#   - JTAG communication with the ARM *must* be working OK; this
+	#     may imply using adaptive clocking or disabling WFI-in-idle
+	#   - current target must be the DaVinci ARM
+	#   - that ARM core must be halted
+	#   - timer2 clock is still enabled (PSC 29 on most chips)
+
+	#
+	# Part I -- run regardless of being halted via JTAG
+	#
+	# NOTE:  for now, we assume there's no DSP that could control the
+	# watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog
+	# suspend signal is controlled via ARM emulation suspend.
+	#
+
+	# EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt
+	arm926ejs mww_phys [expr $timer2_phys + 0x28] 0x00004000
+
+	#
+	# Part II -- in case watchdog hasn't been set up
+	#
+
+	# TCR: disable, force internal clock source
+	arm926ejs mww_phys [expr $timer2_phys + 0x20] 0
+
+	# TGCR: reset, force to 64-bit wdog mode, un-reset ("initial" state)
+	arm926ejs mww_phys [expr $timer2_phys + 0x24] 0
+	arm926ejs mww_phys [expr $timer2_phys + 0x24] 0x110b
+
+	# clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers
+	# so watchdog triggers ASAP
+	arm926ejs mww_phys [expr $timer2_phys + 0x10] 0
+	arm926ejs mww_phys [expr $timer2_phys + 0x14] 0
+	arm926ejs mww_phys [expr $timer2_phys + 0x18] 0
+	arm926ejs mww_phys [expr $timer2_phys + 0x1c] 0
+
+	# WDTCR: put into pre-active state, then active
+	arm926ejs mww_phys [expr $timer2_phys + 0x28] 0xa5c64000
+	arm926ejs mww_phys [expr $timer2_phys + 0x28] 0xda7e4000
+
+	#
+	# Part III -- it's ready to rumble
+	#
+
+	# WDTCR: write invalid WDKEY to trigger reset
+	arm926ejs mww_phys [expr $timer2_phys + 0x28] 0x00004000
+}
-- 
GitLab