# SPDX-License-Identifier: GPL-2.0-or-later

# DM365 EVM board -- Beta
#   http://focus.ti.com/docs/toolsw/folders/print/tmdxevm365.html
#   http://support.spectrumdigital.com/boards/evmdm365

source [find target/ti_dm365.cfg]

# NOTE:  in Rev C boards, the CPLD ignores SRST from the ARM-20 JTAG
# connector, so it doesn't affect generation of the reset signal.
# Accordingly, resets require something else.  ICEpick could do it;
# but its docs aren't generally available.
#
# At this writing, newer boards aren't available ... so assume no SRST.
# Also ICEpick docs aren't available ... so we must use watchdog reset,
# and hope the CPU isn't wedged or in a WFI loop (either of which can
# block access to CPU and thus watchdog registers).

reset_config trst_only
$_TARGETNAME configure -event reset-assert "davinci_wdog_reset"

# SW5.1 routes CS0: NAND vs OneNAND.
# SW4.6:4 controls AEMIF width (8 for NAND, 16 for OneNand)
# for boot-from-flash, those must agree with SW4.3:1 settings.

if { [info exists CS0MODE] } {
	# NAND or OneNAND
	set CS0 $CS0MODE
} else {
	set CS0 ""
	echo "WARNING:  CS0 configuration not known"
	proc cs0_setup {a_emif} {}
	proc flashprobe {} {}
}

set a_emif [dict get $dm365 a_emif]

# As shipped:  boot from NAND.
if { $CS0 == "NAND" } {
	echo "CS0 NAND"

	# NAND socket has two chipselects.  Default MT29F16G08FAA chip
	# has 1GByte on each one.
	# NOTE:  "hwecc4" here presumes that you're not updating anything
	# that needs infix layout (e.g. UBL, old U-Boot, etc)
	nand device low davinci $_TARGETNAME 0x02000000 hwecc4 $a_emif
	nand device high davinci $_TARGETNAME 0x02004000 hwecc4 $a_emif

	proc cs0_setup {a_emif} {
		global dm365

		# 8 bit EMIF
		davinci_pinmux $dm365 2 0x00000016

		# slow/pessimistic timings
		set nand_timings 0x40400204
		# fast (25% faster page reads)
		#set nand_timings 0x0400008c

		# CS0 == socketed NAND (default MT29F16G08FAA, 2 GBytes)
		mww [expr {$a_emif + 0x10}] $nand_timings

		# NANDFCR -- CS0 has NAND
		mww [expr {$a_emif + 0x60}] 0x01
	}
	proc flashprobe {} {
		nand probe 0
		nand probe 1
	}

} elseif { $CS0 == "OneNAND" } {
	echo "CS0 OneNAND"

	# No support for this OneNAND in OpenOCD (yet) or Linux ...
	# REVISIT OneNAND timings not verified to work!
	echo "WARNING -- OneNAND not yet tested!"

	proc cs0_setup {a_emif} {
		global dm365

		# 16 bit EMIF
		davinci_pinmux $dm365 2 0x00000055

		# CS0 == OneNAND (KFG1G16U2B-DIB6, 128 KBytes)
		mww [expr {$a_emif + 0x10}] 0x00000001

		# ONENANDCTRL -- CS0 has OneNAND, enable sync reads
		mww [expr {$a_emif + 0x5c}] 0x0441
	}
	proc flashprobe {} { }
}

# NOTE:  disable or replace this call to dm365evm_init if you're
# debugging new UBL/NANDboot code from SRAM.
$_TARGETNAME configure -event reset-init { dm365evm_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 dm365evm_init {} {
	global dm365

	echo "Initialize DM365 EVM board"

	# CLKIN	= 24 MHz ... can't talk quickly to ARM yet
	adapter speed 1500

	# FIXME -- PLL init

	########################
	# PINMUX setup

	davinci_pinmux $dm365 0 0x00fd0000
	davinci_pinmux $dm365 1 0x00145555
	# mux2 controls AEMIF ... 8 bit for NAND, 16 for OneNand
	davinci_pinmux $dm365 3 0x375affff
	davinci_pinmux $dm365 4 0x55556555

	########################
	# PSC setup (minimal)

	# DDR EMIF/13, AEMIF/14, UART0/19
	psc_enable 13
	psc_enable 14
	psc_enable 19
	psc_go

	# FIXME setup DDR2 (needs PLL)

	########################
	# ASYNC EMIF

	set a_emif [dict get $dm365 a_emif]

	# AWCCR
	mww [expr {$a_emif + 0x04}] 0xff
	# CS0 == NAND or OneNAND
	cs0_setup $a_emif
	# CS1 == CPLD
	mww [expr {$a_emif + 0x14}] 0x00a00505

	# FIXME setup UART0

	flashprobe
}
