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

#xscale ixp42x CPU

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

if { [info exists ENDIAN] } {
   set _ENDIAN $ENDIAN
} else {
  # this defaults to a bigendian
   set _ENDIAN big
}

if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   set _CPUTAPID 0x19274013
}
set _CPUTAPID2 0x19275013
set _CPUTAPID3 0x19277013
set _CPUTAPID4 0x29274013
set _CPUTAPID5 0x29275013
set _CPUTAPID6 0x29277013

jtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 -expected-id $_CPUTAPID4 -expected-id $_CPUTAPID5 -expected-id $_CPUTAPID6

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


# register constants for IXP42x SDRAM controller
global IXP425_SDRAM_IR_MODE_SET_CAS2_CMD
global IXP425_SDRAM_IR_MODE_SET_CAS3_CMD
set IXP425_SDRAM_IR_MODE_SET_CAS2_CMD	0x0000
set IXP425_SDRAM_IR_MODE_SET_CAS3_CMD	0x0001

global IXP42x_SDRAM_CL3
global IXP42x_SDRAM_CL2
set IXP42x_SDRAM_CL3			0x0008
set IXP42x_SDRAM_CL2			0x0000

global IXP42x_SDRAM_8MB_2Mx32_1BANK
global IXP42x_SDRAM_16MB_2Mx32_2BANK
global IXP42x_SDRAM_16MB_4Mx16_1BANK
global IXP42x_SDRAM_32MB_4Mx16_2BANK
global IXP42x_SDRAM_32MB_8Mx16_1BANK
global IXP42x_SDRAM_64MB_8Mx16_2BANK
global IXP42x_SDRAM_64MB_16Mx16_1BANK
global IXP42x_SDRAM_128MB_16Mx16_2BANK
global IXP42x_SDRAM_128MB_32Mx16_1BANK
global IXP42x_SDRAM_256MB_32Mx16_2BANK

set IXP42x_SDRAM_8MB_2Mx32_1BANK	0x0030
set IXP42x_SDRAM_16MB_2Mx32_2BANK	0x0031
set IXP42x_SDRAM_16MB_4Mx16_1BANK	0x0032
set IXP42x_SDRAM_32MB_4Mx16_2BANK	0x0033
set IXP42x_SDRAM_32MB_8Mx16_1BANK	0x0010
set IXP42x_SDRAM_64MB_8Mx16_2BANK	0x0011
set IXP42x_SDRAM_64MB_16Mx16_1BANK	0x0012
set IXP42x_SDRAM_128MB_16Mx16_2BANK	0x0013
set IXP42x_SDRAM_128MB_32Mx16_1BANK	0x0014
set IXP42x_SDRAM_256MB_32Mx16_2BANK	0x0015


# helper function to init SDRAM on IXP42x.
# SDRAM_CFG: one of IXP42X_SDRAM_xxx
# REFRESH: refresh counter reload value (integer)
# CASLAT: 2 or 3
proc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } {

    switch $CASLAT {
	2 {
	    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL2} ]
	    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS2_CMD
	}
	3 {
	    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL3} ]
	    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS3_CMD
	}
	default { error [format "unsupported cas latency \"%s\" " $CASLAT] }
    }
    echo [format "\tIXP42x SDRAM Config: 0x%x, Refresh %d " $SDRAM_CFG $REFRESH]

    mww 0xCC000000 $SDRAM_CFG ;# SDRAM_CFG: 0x2A: 64MBit, CL3
    mww 0xCC000004          0 ;# disable refresh
    mww 0xCC000008          3 ;# NOP
    sleep 100
    mww 0xCC000004   $REFRESH ;# set refresh counter
    mww 0xCC000008          2 ;# Precharge All Banks
    sleep 100
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008          4 ;# Auto Refresh
    mww 0xCC000008    $CASCMD ;# Mode Select CL2/CL3
}

proc ixp42x_set_bigendian { } {
    reg XSCALE_CTRL 0xF8
}
