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

#
# Support for General Plus GP326XXXA chips
#

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

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

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

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

# Use internal SRAM as a work area
$_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-area-backup 0

# The chip has both lines connected together
reset_config trst_and_srst srst_pulls_trst
# This delay is needed otherwise communication with the target would
# be unreliable
adapter srst delay 100

# Set the adapter speed ridiculously low just in case we are
# running off of a 32kHz clock
adapter speed 2

proc gp32xxxa_halt_and_reset_control_registers {} {
	# System control registers
	set P_SYSTEM_CTRL_NEW       0xD0000008
	set P_SYSTEM_CTRL           0xD000000C
	set P_SYSTEM_CLK_EN0        0xD0000010
	set P_SYSTEM_CLK_EN1        0xD0000014
	set P_SYSTEM_RESET_FLAG     0xD0000018
	set P_SYSTEM_CLK_CTRL       0xD000001C
	set P_SYSTEM_LVR_CTRL       0xD0000020
	set P_SYSTEM_WATCHDOG_CTRL  0xD0000024
	set P_SYSTEM_PLLEN          0xD000005C

	# Since we can't use SRST without pulling TRST
	# we can't assume the state of the clock configuration
	# or watchdog settings. So reset them before porceeding

	# Set the adapter speed ridiculously low just in case we are
	# running off of a 32kHz clock
	adapter speed 2

	# Disable any advanced features at this stage
	arm7_9 dcc_downloads disable
	arm7_9 fast_memory_access disable

	# Do a "soft reset"
	soft_reset_halt
	# Reset all system control registers to their default "after-reset" values
	mwh $P_SYSTEM_WATCHDOG_CTRL  0x0000
	mwh $P_SYSTEM_LVR_CTRL       0x0000

	mwh $P_SYSTEM_CTRL_NEW       0x0001
	mwh $P_SYSTEM_CTRL           0x0001
	# Clear all reset flags by writing 1's
	mwh $P_SYSTEM_RESET_FLAG     0x001C

	mwh $P_SYSTEM_CLK_CTRL       0x8000
	mwh $P_SYSTEM_CLK_EN0        0xFFFF
	mwh $P_SYSTEM_CLK_EN1        0xFFFF
	mwh $P_SYSTEM_PLLEN          0x0010

	# Unfortunately there's no register that would allow us to
	# know if PLL is locked. So just wait for 100ms in hopes that
	# it would be enough.
	sleep 100

	# Now that we know that we are running at 48Mhz
	# Increase JTAG speed and enable speed optimization features
	adapter speed 5000
	arm7_9 dcc_downloads enable
	arm7_9 fast_memory_access enable
}

$_TARGETNAME configure -event reset-end { gp32xxxa_halt_and_reset_control_registers }
