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

# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4394
#
# use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst srst_pulls_trst

if { [info exists CHIPNAME] } {
   set  _CHIPNAME $CHIPNAME
} else {
   set  _CHIPNAME cap7
}

if { [info exists ENDIAN] } {
   set  _ENDIAN $ENDIAN
} else {
   set  _ENDIAN little
}

if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   set _CPUTAPID 0x40700f0f
}

jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME

$_TARGETNAME configure -event reset-start {
	# start off real slow when we're running off internal RC oscillator
	adapter speed 32
}

proc peek32 {address} {
	return [read_memory $address 32 1]
}

# Wait for an expression to be true with a timeout
proc wait_state {expression} {
	for {set i 0} {$i < 1000} {set i [expr {$i + 1}]} {
		if {[uplevel 1 $expression] == 0} {
			return
		}
	}
	return -code 1 "Timed out"
}

# Use a global variable here to be able to tinker interactively with
# post reset jtag frequency.
global post_reset_khz
# Danger!!!! Even 16MHz kinda works with this target, but
# it needs to be as low as 2000kHz to be stable.
set post_reset_khz 2000

$_TARGETNAME configure -event reset-init {
	echo "Configuring master clock"
	# disable watchdog
	mww 0xfffffd44 0xff008000
	# enable user reset
	mww 0xfffffd08 0xa5000001
	# Enable main oscillator
	mww 0xFFFFFc20  0x00000f01
	wait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}}

	# Set PLLA to 96MHz
	mww 0xFFFFFc28 0x20072801
	wait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}}

	# Select prescaler
	mww 0xFFFFFC30 0x00000004
	wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}

	# Select master clock to 48MHz
	mww 0xFFFFFC30 0x00000006
	wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}

	echo "Master clock ok."

	# Now that we're up and running, crank up speed!
	global post_reset_khz ;	adapter speed $post_reset_khz

	echo "Configuring the SDRAM controller..."

	# Configure EBI Chip select for SDRAM
	mww 0xFFFFEF30 0x00000102

	# Enable clock on EBI PIOs
	mww 0xFFFFFC10 0x00000004

	# Configure PIO for SDRAM
	mww 0xFFFFF470 0xFFFF0000
	mww 0xFFFFF474 0x00000000
	mww 0xFFFFF404 0xFFFF0000

	# Configure SDRAMC CR
	mww 0xFFFFEA08 0xA63392F9

	# NOP command
	mww 0xFFFFEA00 0x1
	mww 0x20000000 0

	# Precharge All Banks command
	mww 0xFFFFEA00 0x2
	mww 0x20000000 0

	# Set 1st CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000010 0x00000001

	# Set 2nd CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000020 0x00000002

	# Set 3rd CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000030 0x00000003

	# Set 4th CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000040 0x00000004

	# Set 5th CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000050 0x00000005

	# Set 6th CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000060 0x00000006

	# Set 7th CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000070 0x00000007

	# Set 8th CBR
	mww 0xFFFFEA00 0x00000004
	mww 0x20000080 0x00000008

	# Set LMR operation
	mww 0xFFFFEA00 0x00000003

	# Perform LMR burst=1, lat=2
	mww 0x20000020 0xCAFEDEDE

	# Set Refresh Timer
	mww 0xFFFFEA04 0x00000203

	# Set Normal mode
	mww 0xFFFFEA00 0x00000000
	mww 0x20000000 0x00000000

	#remap internal memory at address 0x0
	mww 0xffffef00 0x3

	echo "SDRAM configuration ok."
}

$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0

arm7_9 dcc_downloads enable
arm7_9 fast_memory_access enable

#set _FLASHNAME $_CHIPNAME.flash
#flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432
