X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=tcl%2Ftarget%2Fdavinci.cfg;h=ee840c8d01d0716caefc46055046fd458ebac78a;hb=00635e28ba5c405742cae261d8551f165dc78ba3;hp=0a3da27d50aa4a33e19bcf988abed39e0d1ad565;hpb=dbbc9c41f7db210b0a4e226540a28e0a8a5019bf;p=openocd diff --git a/tcl/target/davinci.cfg b/tcl/target/davinci.cfg index 0a3da27d..ee840c8d 100644 --- a/tcl/target/davinci.cfg +++ b/tcl/target/davinci.cfg @@ -31,12 +31,10 @@ proc mmw {reg setbits clearbits} { # For PLLs that don't have a given register (e.g. plldiv8), or where a # given divider is non-programmable, caller provides *NO* config mapping. # -# REVISIT there are minor differences between the PLL controllers. -# Handle those; maybe check the ID register. This version behaves -# for at least the dm355. On dm6446 and dm357 the PLLRST polarity -# is different. On dm365 there are more changes. -# -proc pll_setup {pll_addr mult config} { + +# PLL version 0x02: tested on dm355 +# 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] @@ -98,7 +96,7 @@ proc pll_setup {pll_addr mult config} { set go 1 } if { [dict exists $config div2] } { - 1et div [dict get $config div2] + set div [dict get $config div2] set div [expr 0x8000 | ($div - 1)] mww [expr $pll_addr + 0x011c] $div set go 1 @@ -106,7 +104,7 @@ proc pll_setup {pll_addr mult config} { if { [dict exists $config div3] } { set div [dict get $config div3] set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x011c] $div + mww [expr $pll_addr + 0x0120] $div set go 1 } if { [dict exists $config div4] } { @@ -127,6 +125,7 @@ proc pll_setup {pll_addr mult config} { set pllstat [expr $pll_addr + 0x013c] while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 } } + mww [expr $pll_addr + 0x0138] 0x00 # 11 - wait at least 5 usec for reset to finish # (assume covered by overheads including JTAG messaging) @@ -154,7 +153,14 @@ proc psc_enable {module} { mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x03 0x1f } -# execute non-DSP PSC transition(s) set up by psc_enable +# prepare a non-DSP module to be reset; finish with psc_go +proc psc_reset {module} { + set psc_addr 0x01c41000 + # write MDCTL + mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x01 0x1f +} + +# execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc proc psc_go {} { set psc_addr 0x01c41000 set ptstat_addr [expr $psc_addr + 0x0128] @@ -168,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 + mww phys [expr $timer2_phys + 0x28] 0x00004000 + + # + # Part II -- in case watchdog hasn't been set up + # + + # TCR: disable, force internal clock source + mww phys [expr $timer2_phys + 0x20] 0 + + # TGCR: reset, force to 64-bit wdog mode, un-reset ("initial" state) + mww phys [expr $timer2_phys + 0x24] 0 + mww phys [expr $timer2_phys + 0x24] 0x110b + + # clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers + # so watchdog triggers ASAP + mww phys [expr $timer2_phys + 0x10] 0 + mww phys [expr $timer2_phys + 0x14] 0 + mww phys [expr $timer2_phys + 0x18] 0 + mww phys [expr $timer2_phys + 0x1c] 0 + + # WDTCR: put into pre-active state, then active + mww phys [expr $timer2_phys + 0x28] 0xa5c64000 + mww phys [expr $timer2_phys + 0x28] 0xda7e4000 + + # + # Part III -- it's ready to rumble + # + + # WDTCR: write invalid WDKEY to trigger reset + mww phys [expr $timer2_phys + 0x28] 0x00004000 +}