--- /dev/null
+#
+# DM355 EVM board
+# http://focus.ti.com/docs/toolsw/folders/print/tmdsevm355.html
+# http://c6000.spectrumdigital.com/evmdm355/
+
+source [find target/ti_dm355.cfg]
+
+reset_config trst_and_srst separate
+
+# NOTE: disable or replace this call to dm355evm_init if you're
+# debugging new UBL code from SRAM.
+$_TARGETNAME configure -event reset-init { dm355evm_init }
+
+#
+# This post-reset init is called when the MMU isn't active, all IRQs
+# are disabled, etc. It should do most of what a UBL does, except for
+# loading code (like U-Boot) into DRAM and running it.
+#
+proc dm355evm_init {} {
+ global dm355
+
+ puts "Initialize DM355 EVM board"
+
+ # CLKIN = 24 MHz ... can't talk quickly to ARM yet
+ jtag_khz 1500
+
+ ########################
+ # PLL1 = 432 MHz (/8, x144)
+ # ...SYSCLK1 = 216 MHz (/2) ... ARM, MJCP
+ # ...SYSCLK2 = 108 MHz (/4) ... Peripherals
+ # ...SYSCLK3 = 27 MHz (/16) ... VPBE, DAC
+ # ...SYSCLK4 = 108 MHz (/4) ... VPSS
+ # pll1.{prediv,div1,div2} are fixed
+ # pll1.postdiv set in MISC (for *this* speed grade)
+
+ set addr [dict get $dm355 pllc1]
+ set pll_divs [dict create]
+ dict set pll_divs div3 16
+ dict set pll_divs div4 8
+ pll_setup $addr 144 $pll_divs
+
+ # ARM is now running at 216 MHz, so JTAG can go faster
+ jtag_khz 20000
+
+ ########################
+ # PLL2 = 342 MHz (/8, x114)
+ # ....SYSCLK1 = 342 MHz (/1) ... DDR PHY at 171 MHz, 2x clock
+ # pll2.{postdiv,div1} are fixed
+
+ set addr [dict get $dm355 pllc2]
+ set pll_divs [dict create]
+ dict set pll_divs prediv 8
+ pll_setup $addr 114 $pll_divs
+
+ ########################
+ # PINMUX
+
+ # All Video Inputs
+ davinci_pinmux $dm355 0 0x00007f55
+ # All Video Outputs
+ davinci_pinmux $dm355 1 0x00145555
+ # EMIFA (NOTE: more could be set up for use as GPIOs)
+ davinci_pinmux $dm355 2 0x00000c08
+ # SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs
+ davinci_pinmux $dm355 3 0x1bff55ff
+ # MMC/SD0 instead of MS; SPI0
+ davinci_pinmux $dm355 4 0x00000000
+
+ ########################
+ # PSC setup (minimal)
+
+ # DDR EMIF/13, AEMIF/14, UART0/19
+ psc_enable 13
+ psc_enable 14
+ psc_enable 19
+ psc_go
+
+ ########################
+ # DDR2 EMIF
+
+ # FIXME setup
+
+ ########################
+ # ASYNC EMIF
+
+ set addr [dict get $dm355 a_emif]
+
+ # slow/pessimistic timings
+ set nand_timings 0x40400204
+ # fast (25% faster page reads)
+ #set nand_timings 0x0400008c
+
+ # AWCCR
+ mww [expr $addr + 0x04] 0xff
+ # CS0 == socketed NAND (default MT29F16G08FAA, 2GByte)
+ mww [expr $addr + 0x10] $nand_timings
+ # CS1 == dm9000 Ethernet
+ mww [expr $addr + 0x14] 0x00a00505
+ # NANDFCR -- only CS0 has NAND
+ mww [expr $addr + 0x60] 0x01
+
+ ########################
+ # UART0
+
+ # FIXME setup
+}
+
+# FIXME
+# - declare the NAND flash; use the 4-bit ECC
+# - support writing UBL with its header (new layout only with new ROMs)
+# - support writing ABL/U-Boot with its header (both layouts)
--- /dev/null
+#
+# Utility code for DaVinci-family chips
+#
+
+# davinci_pinmux: assigns PINMUX$reg <== $value
+proc davinci_pinmux {soc reg value} {
+ mww [expr [dict get $soc sysbase] + 4 * $reg] $value
+}
+
+# mrw: "memory read word", returns value of $reg
+proc mrw {reg} {
+ set value ""
+ ocd_mem2array value 32 $reg 1
+ return $value(0)
+}
+
+# mmw: "memory modify word", updates value of $reg
+# $reg <== ((value & ~$clearbits) | $setbits)
+proc mmw {reg setbits clearbits} {
+ set old [mrw $reg]
+ set new [expr ($old & ~$clearbits) | $setbits]
+ mww $reg $new
+}
+
+#
+# pll_setup: initialize PLL
+# - pll_addr ... physical addr of controller
+# - mult ... pll multiplier
+# - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers
+#
+# 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} {
+ set pll_ctrl_addr [expr $pll_addr + 0x100]
+ set pll_ctrl [mrw $pll_ctrl_addr]
+
+ # 1 - clear CLKMODE (bit 8) iff using on-chip oscillator
+ # NOTE: this assumes we should clear that bit
+ set pll_ctrl [expr $pll_ctrl & ~0x0100]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 2 - clear PLLENSRC (bit 5)
+ set pll_ctrl [expr $pll_ctrl & ~0x0020]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 3 - clear PLLEN (bit 0) ... enter bypass mode
+ set pll_ctrl [expr $pll_ctrl & ~0x0001]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 4 - wait at least 4 refclk cycles
+ sleep 1
+
+ # 5 - set PLLRST (bit 3)
+ set pll_ctrl [expr $pll_ctrl | 0x0008]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 6 - set PLLDIS (bit 4)
+ set pll_ctrl [expr $pll_ctrl | 0x0010]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 7 - clear PLLPWRDN (bit 1)
+ set pll_ctrl [expr $pll_ctrl & ~0x0002]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 8 - clear PLLDIS (bit 4)
+ set pll_ctrl [expr $pll_ctrl & ~0x0010]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 9 - optional: write prediv, postdiv, and pllm
+ # NOTE: for dm355 PLL1, postdiv is controlled via MISC register
+ mww [expr $pll_addr + 0x0110] [expr ($mult - 1) & 0xff]
+ if { [dict exists $config prediv] } {
+ set div [dict get $config prediv]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x0114] $div
+ }
+ if { [dict exists $config postdiv] } {
+ set div [dict get $config postdiv]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x0128] $div
+ }
+
+ # 10 - optional: set plldiv1, plldiv2, ...
+ # NOTE: this assumes some registers have their just-reset values:
+ # - PLLSTAT.GOSTAT is clear when we enter
+ # - ALNCTL has everything set
+ set go 0
+ if { [dict exists $config div1] } {
+ set div [dict get $config div1]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x0118] $div
+ set go 1
+ }
+ if { [dict exists $config div2] } {
+ 1et div [dict get $config div2]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x011c] $div
+ set go 1
+ }
+ if { [dict exists $config div3] } {
+ set div [dict get $config div3]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x011c] $div
+ set go 1
+ }
+ if { [dict exists $config div4] } {
+ set div [dict get $config div4]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x0160] $div
+ set go 1
+ }
+ if { [dict exists $config div5] } {
+ set div [dict get $config div5]
+ set div [expr 0x8000 | ($div - 1)]
+ mww [expr $pll_addr + 0x0164] $div
+ set go 1
+ }
+ if {$go != 0} {
+ # write pllcmd.GO; poll pllstat.GO
+ mww [expr $pll_addr + 0x0138] 0x01
+ set pllstat [expr $pll_addr + 0x013c]
+ while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 }
+ }
+
+ # 11 - wait at least 5 usec for reset to finish
+ # (assume covered by overheads including JTAG messaging)
+
+ # 12 - clear PLLRST (bit 3)
+ set pll_ctrl [expr $pll_ctrl & ~0x0008]
+ mww $pll_ctrl_addr $pll_ctrl
+
+ # 13 - wait at least 8000 refclk cycles for PLL to lock
+ # if we assume 24 MHz (slowest osc), that's 1/3 msec
+ sleep 3
+
+ # 14 - set PLLEN (bit 0) ... leave bypass mode
+ set pll_ctrl [expr $pll_ctrl | 0x0001]
+ mww $pll_ctrl_addr $pll_ctrl
+}
+
+# NOTE: dm6446 requires EMURSTIE set in MDCTL before certain
+# modules can be enabled.
+
+# prepare a non-DSP module to be enabled; finish with psc_go
+proc psc_enable {module} {
+ set psc_addr 0x01c41000
+ # write MDCTL
+ mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x03 0x1f
+}
+
+# execute non-DSP PSC transition(s) set up by psc_enable
+proc psc_go {} {
+ set psc_addr 0x01c41000
+ set ptstat_addr [expr $psc_addr + 0x0128]
+
+ # just in case PTSTAT.go isn't clear
+ while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
+
+ # write PTCMD.go ... ignoring any DSP power domain
+ mww [expr $psc_addr + 0x0120] 1
+
+ # wait for PTSTAT.go to clear (again ignoring DSP power domain)
+ while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
+}
}
jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID
+################
+
+# various symbol definitions, to avoid hard-wiring addresses
+# and enable some sharing of DaVinci-family utility code
+global dm355
+set dm355 [ dict create ]
+
+# Physical addresses for controllers and memory
+# (Some of these are valid for many DaVinci family chips)
+dict set dm355 sram0 0x00010000
+dict set dm355 sram1 0x00014000
+dict set dm355 sysbase 0x01c40000
+dict set dm355 pllc1 0x01c40800
+dict set dm355 pllc2 0x01c40c00
+dict set dm355 psc 0x01c41000
+dict set dm355 gpio 0x01c67000
+dict set dm355 a_emif 0x01e10000
+dict set dm355 a_emif_cs0 0x02000000
+dict set dm355 a_emif_cs1 0x04000000
+dict set dm355 ddr_emif 0x20000000
+dict set dm355 ddr 0x80000000
+
+source [find target/davinci.cfg]
+
+################
# GDB target: the ARM, using SRAM1 for scratch. SRAM0 (also 16K)
# and the ETB memory (4K) are other options, while trace is unused.
set _TARGETNAME $_CHIPNAME.arm
target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME
-$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x00014000 -work-area-size 0x4000 -work-area-backup 0
+
+# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,
+# and that the work area is used only with a kernel mmu context ...
+$_TARGETNAME configure \
+ -work-area-virt [expr 0xfffe0000 + 0x4000] \
+ -work-area-phys [dict get $dm355 sram1] \
+ -work-area-size 0x4000 \
+ -work-area-backup 0
arm7_9 dbgrq enable
arm7_9 fast_memory_access enable