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

# Cogent CSB337
#   http://cogcomp.com/csb_csb337.htm

source [find target/at91rm9200.cfg]

# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME

# ETM9 trace port connector present on this board, 16 data pins.
if { [info exists ETM_DRIVER] } {
	etm config $_TARGETNAME 16 normal half $ETM_DRIVER
	# OpenOCD may someday support a real trace port driver...
	# system config file would need to configure it.
} else {
	etm config $_TARGETNAME 16 normal half dummy
	etm_dummy config $_TARGETNAME
}

proc csb337_clk_init { } {
	# CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock
	adapter speed 8

	# CKGR_MOR:  start main oscillator (3.6864 MHz)
	mww 0xfffffc20 0xff01
	sleep 10

	# CKGR_PLLAR:  start PLL A for CPU and peripherals (184.32 MHz)
	mww 0xfffffc28 0x20313e01
	# CKGR_PLLBR:  start PLL B for USB timing (96 MHz, with div2)
	mww 0xfffffc2c 0x12703e18
	# let PLLs lock
	sleep 10

	# PMC_MCKR:  switch to CPU clock = PLLA, master clock = CPU/4
	mww 0xfffffc30 0x0302
	sleep 20

	# CPU is in Normal Mode ... allows faster JTAG clock speed
	adapter speed 40000
}

proc csb337_nor_init { } {
	# SMC_CSR0:  adjust timings (10 wait states)
	mww 0xffffff70 0x1100318a

	flash probe 0
}

proc csb337_sdram_init { } {
	# enable PIOC clock
	mww 0xfffffc10 0x0010
	# PC31..PC16 are D31..D16, with internal pullups like D15..D0
	mww 0xfffff870 0xffff0000
	mww 0xfffff874 0x0
	mww 0xfffff804 0xffff0000

	# SDRC_CR: set timings
	mww 0xffffff98 0x2188b0d5

	# SDRC_MR: issue all banks precharge to SDRAM
	mww 0xffffff90 2
	mww 0x20000000 0

	# SDRC_MR: 8 autorefresh cycles
	mww 0xffffff90 4
	mww 0x20000000 0
	mww 0x20000000 0
	mww 0x20000000 0
	mww 0x20000000 0
	mww 0x20000000 0
	mww 0x20000000 0
	mww 0x20000000 0
	mww 0x20000000 0

	# SDRC_MR: set SDRAM mode registers (CAS, burst len, etc)
	mww 0xffffff90 3
	mww 0x20000080 0

	# SDRC_TR: set refresh rate
	mww 0xffffff94 0x200
	mww 0x20000000 0

	# SDRC_MR: normal mode, 32 bit bus
	mww 0xffffff90 0
	mww 0x20000000 0
}

# The rm9200 chip has just been reset.  Bring it up far enough
# that we can write flash or run code from SDRAM.
proc csb337_reset_init { } {
	csb337_clk_init

	# EBI_CSA:  CS0 = NOR, CS1 = SDRAM
	mww 0xffffff60 0x02

	csb337_nor_init
	csb337_sdram_init

	# Update CP15 control register ... we don't seem to be able to
	# read/modify/write its value through a TCL variable, so just
	# write it.  Fields are zero unless listed here ... and note
	# that OpenOCD numbers this register "2", not "1" (!).
	#
	#  - Core to use Async Clocking mode (so it uses 184 MHz most
	#    of the time instead of limiting to the master clock rate):
	#	iA(31) = 1, nF(30) = 1
	#  - Icache on (it's disabled now, slowing i-fetches)
	#	I(12) = 1
	#  - Reserved/ones
	#	6:3 = 1
	arm920t cp15 2 0xc0001078
}

$_TARGETNAME configure -event reset-init {csb337_reset_init}

arm7_9 fast_memory_access enable
