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

# 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

	echo "Initialize DM355 EVM board"

	# CLKIN	= 24 MHz ... can't talk quickly to ARM yet
	jtag_rclk 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 4
	pll_v02_setup $addr 144 $pll_divs

	# ARM is now running at 216 MHz, so JTAG can go faster
	jtag_rclk 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 div1 1
	dict set pll_divs prediv 8
	pll_v02_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

	# VTPIOCR impedance calibration
	set addr [dict get $dm355 sysbase]
	set addr [expr {$addr + 0x70}]

	# clear CLR, LOCK, PWRDN; wait a clock; set CLR
	mmw $addr 0 0x20c0
	mmw $addr 0x2000 0

	# wait for READY
        while { [expr {[mrw $addr] & 0x8000}] == 0 } { sleep 1 }

	# set IO_READY; then LOCK and PWRSAVE; then PWRDN
	mmw $addr 0x4000 0
	mmw $addr 0x0180 0
	mmw $addr 0x0040 0

	# NOTE:  this DDR2 initialization sequence borrows from
	# both UBL 1.50 and the SPRUEH7D DDR2 EMIF spec.

	# reset (then re-enable) DDR controller
	psc_reset 13
	psc_go
	psc_enable 13
	psc_go

	# now set it up for Micron MT47H64M16HR-37E @ 171 MHz

	set addr [dict get $dm355 ddr_emif]

	# DDRPHYCR1
	mww [expr {$addr + 0xe4}] 0x50006404

	# PBBPR -- burst priority
	mww [expr {$addr + 0x20}] 0xfe

	# SDCR -- unlock boot config; init for DDR2, relock, unlock SDTIM*
	mmw [expr {$addr + 0x08}] 0x00800000 0
	mmw [expr {$addr + 0x08}] 0x0013c632 0x03870fff

	# SDTIMR0, SDTIMR1
	mww [expr {$addr + 0x10}] 0x2a923249
	mww [expr {$addr + 0x14}] 0x4c17c763

	# SDCR -- relock SDTIM*
	mmw [expr {$addr + 0x08}] 0 0x00008000

	# SDRCR -- refresh rate (171 MHz * 7.8usec)
	mww [expr {$addr + 0x0c}] 1336

	########################
	# 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

	# default: both chipselects to the NAND socket are used
	nand probe 0
	nand probe 1

	########################
	# UART0

	set addr [dict get $dm355 uart0]

	# PWREMU_MGNT -- rx + tx in reset
	mww [expr {$addr + 0x30}] 0

	# DLL, DLH -- 115200 baud
	mwb [expr {$addr + 0x20}] 0x0d
	mwb [expr {$addr + 0x24}] 0x00

	# FCR - clear and disable FIFOs
	mwb [expr {$addr + 0x08}] 0x07
	mwb [expr {$addr + 0x08}] 0x00

	# IER - disable IRQs
	mwb [expr {$addr + 0x04}] 0x00

	# LCR - 8-N-1
	mwb [expr {$addr + 0x0c}] 0x03

	# MCR - no flow control or loopback
	mwb [expr {$addr + 0x10}] 0x00

	# PWREMU_MGNT -- rx + tx normal, free running during JTAG halt
	mww [expr {$addr + 0x30}] 0xe001


	########################

	# turn on icache - set I bit in cp15 register c1
	arm mcr 15 0 0 1 0 0x00051078
}

# NAND -- socket has two chipselects, MT29F16G08FAA puts 1GByte on each one.
#
# NOTE:  "hwecc4" here presumes that if you're using the standard 2GB NAND
# you either (a) have 'new' DM355 chips, with boot ROMs that don't need to
# use "hwecc4_infix" for the UBL; or else (b) aren't updating anything that
# needs infix layout ... like an old UBL, old U-Boot, old MVL kernel, etc.
set _FLASHNAME $_CHIPNAME.boot
nand device $_FLASHNAME davinci $_TARGETNAME 0x02000000 hwecc4 0x01e10000
set _FLASHNAME $_CHIPNAME.flash
nand device $_FLASHNAME davinci $_TARGETNAME 0x02004000 hwecc4 0x01e10000

# FIXME
#  - support writing UBL with its header (new layout only with new ROMs)
#  - support writing ABL/U-Boot with its header (new layout)