From: Felipe Balbi Date: Mon, 16 Mar 2015 23:50:55 +0000 (-0500) Subject: tcl: am437x: add reset-init event handler X-Git-Tag: v0.9.0-rc1~60 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5df0dfb7f42f6c5a82a08a61869609c389b34a21;p=openocd tcl: am437x: add reset-init event handler this event handler will configure and lock PLLs and configure DDR so platform is placed in usable state. Change-Id: Idd02f4c9789181d69578f8606ac3576ea1dd8a0b Tested-by: Tom Rini Signed-off-by: Felipe Balbi Reviewed-on: http://openocd.zylin.com/2616 Tested-by: jenkins Reviewed-by: Tom Rini Reviewed-by: Paul Fertser --- diff --git a/tcl/target/am437x.cfg b/tcl/target/am437x.cfg index ee62ef92..75c13e4b 100644 --- a/tcl/target/am437x.cfg +++ b/tcl/target/am437x.cfg @@ -508,5 +508,487 @@ proc disable_watchdog { } { } } +proc ceil { x y } { + return [ expr ($x + $y - 1) / $y ] +} + +proc device_type { } { + global CONTROL_STATUS + + set tmp [ mrw $CONTROL_STATUS ] + set tmp [ expr $tmp & 0x700 ] + set tmp [ expr $tmp >> 8 ] + + return $tmp +} + +proc get_input_clock_frequency { } { + global CONTROL_STATUS + + if { [ device_type ] != 3 } { + error "Unknown device type\n" + return -1 + } + + set freq [ mrw $CONTROL_STATUS ] + set freq [ expr $freq & 0x00c00000 ] + set freq [ expr $freq >> 22 ] + + switch $freq { + 0 { + set CLKIN 19200000 + } + + 1 { + set CLKIN 24000000 + } + + 2 { + set CLKIN 25000000 + } + + 3 { + set CLKIN 26000000 + } + } + + return $CLKIN +} + +proc mpu_pll_config { CLKIN N M M2 } { + global CM_CLKMODE_DPLL_MPU + global CM_CLKSEL_DPLL_MPU + global CM_DIV_M2_DPLL_MPU + global CM_IDLEST_DPLL_MPU + + set clksel [ mrw $CM_CLKSEL_DPLL_MPU ] + set div_m2 [ mrw $CM_DIV_M2_DPLL_MPU ] + + mww $CM_CLKMODE_DPLL_MPU 0x4 + while { !([ mrw $CM_IDLEST_DPLL_MPU ] & 0x0100) } { } + + set clksel [ expr $clksel & (~0x7ffff) ] + set clksel [ expr $clksel | ($M << 0x8) | $N ] + mww $CM_CLKSEL_DPLL_MPU $clksel + + set div_m2 [ expr $div_m2 & (~0x1f) ] + set div_m2 [ expr $div_m2 | $M2 ] + mww $CM_DIV_M2_DPLL_MPU $div_m2 + + mww $CM_CLKMODE_DPLL_MPU 0x7 + while { [ mrw $CM_IDLEST_DPLL_MPU ] != 1 } { } + + echo "MPU DPLL locked" +} + +proc core_pll_config { CLKIN N M M4 M5 M6 } { + global CM_CLKMODE_DPLL_CORE + global CM_CLKSEL_DPLL_CORE + global CM_DIV_M4_DPLL_CORE + global CM_DIV_M5_DPLL_CORE + global CM_DIV_M6_DPLL_CORE + global CM_IDLEST_DPLL_CORE + + set clksel [ mrw $CM_CLKSEL_DPLL_CORE ] + + mww $CM_CLKMODE_DPLL_CORE 0x4 + while { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x0100) } { } + + set clksel [ expr $clksel & (~0x7ffff) ] + set clksel [ expr $clksel | ($M << 0x8) | $N ] + mww $CM_CLKSEL_DPLL_CORE $clksel + mww $CM_DIV_M4_DPLL_CORE $M4 + mww $CM_DIV_M5_DPLL_CORE $M5 + mww $CM_DIV_M6_DPLL_CORE $M6 + + mww $CM_CLKMODE_DPLL_CORE 0x7 + while { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x01) } { } + + echo "CORE DPLL locked" +} + +proc per_pll_config { CLKIN N M M2 } { + global CM_CLKMODE_DPLL_PER + global CM_CLKSEL_DPLL_PER + global CM_DIV_M2_DPLL_PER + global CM_IDLEST_DPLL_PER + + set x [ expr $M * $CLKIN / 1000000 ] + set y [ expr ($N + 1) * 250 ] + set sd [ ceil $x $y ] + + set clksel [ mrw $CM_CLKSEL_DPLL_PER ] + set div_m2 [ mrw $CM_DIV_M2_DPLL_PER ] + + mww $CM_CLKMODE_DPLL_PER 0x4 + while { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x0100) } { } + + set clksel [ expr $clksel & (~0xff0fffff) ] + set clksel [ expr $clksel | ($M << 0x8) | $N ] + set clksel [ expr $clksel | ($sd << 24) ] + mww $CM_CLKSEL_DPLL_PER $clksel + + set div_m2 [ expr 0xffffff80 | $M2 ] + + mww $CM_CLKMODE_DPLL_PER 0x7 + while { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x01) } { } + + echo "PER DPLL locked" +} + +proc ddr_pll_config { CLKIN N M M2 M4 } { + global CM_CLKMODE_DPLL_DDR + global CM_CLKSEL_DPLL_DDR + global CM_DIV_M2_DPLL_DDR + global CM_DIV_M4_DPLL_DDR + global CM_IDLEST_DPLL_DDR + + set clksel [ mrw $CM_CLKSEL_DPLL_DDR ] + set div_m2 [ mrw $CM_DIV_M2_DPLL_DDR ] + + mww $CM_CLKMODE_DPLL_DDR 0x4 + while { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x0100) } { } + + set clksel [ expr $clksel & (~0x7ffff) ] + set clksel [ expr $clksel | ($M << 8) | $N ] + mww $CM_CLKSEL_DPLL_DDR $clksel + + set div_m2 [ expr ($div_m2 & 0xffffffe0) | $M2 ] + mww $CM_DIV_M2_DPLL_DDR $div_m2 + mww $CM_DIV_M4_DPLL_DDR $M4 + + mww $CM_CLKMODE_DPLL_DDR 0x7 + while { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x01) } { } + + echo "DDR DPLL Locked" +} + +proc config_opp100 { } { + set CLKIN [ get_input_clock_frequency ] + + if { $CLKIN == -1 } { + return -1 + } + + switch $CLKIN { + 24000000 { + mpu_pll_config $CLKIN 0 25 1 + core_pll_config $CLKIN 2 125 10 8 4 + per_pll_config $CLKIN 9 400 5 + ddr_pll_config $CLKIN 2 50 1 2 + } + + 25000000 { + mpu_pll_config $CLKIN 0 24 1 + core_pll_config $CLKIN 0 40 10 8 4 + per_pll_config $CLKIN 9 384 5 + ddr_pll_config $CLKIN 0 16 1 2 + } + + 26000000 { + mpu_pll_config $CLKIN 12 300 1 + core_pll_config $CLKIN 12 500 10 8 4 + per_pll_config $CLKIN 12 480 5 + ddr_pll_config $CLKIN 12 200 1 2 + } + + 19200000 { + mpu_pll_config $CLKIN 3 125 1 + core_pll_config $CLKIN 11 625 10 8 4 + per_pll_config $CLKIN 7 400 5 + ddr_pll_config $CLKIN 2 125 1 2 + } + } +} + +proc emif_prcm_clk_enable { } { + global CM_PER_EMIF_FW_CLKCTRL + global CM_PER_EMIF_CLKCTRL + + mww $CM_PER_EMIF_FW_CLKCTRL 0x02 + mww $CM_PER_EMIF_CLKCTRL 0x02 + + while { [ mrw $CM_PER_EMIF_CLKCTRL ] != 0x02 } { } +} + +proc vtp_enable { } { + global VTP_CTRL_REG + + set vtp [ expr [ mrw $VTP_CTRL_REG ] | 0x40 ] + mww $VTP_CTRL_REG $vtp + + set vtp [ expr [ mrw $VTP_CTRL_REG ] & ~0x01 ] + mww $VTP_CTRL_REG $vtp + + set vtp [ expr [ mrw $VTP_CTRL_REG ] | 0x01 ] + mww $VTP_CTRL_REG $vtp + +} + +proc config_ddr_ioctrl { } { + global DDR_ADDRCTRL_IOCTRL + global DDR_ADDRCTRL_WD0_IOCTRL + global DDR_ADDRCTRL_WD1_IOCTRL + global DDR_CKE_CTRL + global DDR_DATA0_IOCTRL + global DDR_DATA1_IOCTRL + global DDR_DATA2_IOCTRL + global DDR_DATA3_IOCTRL + global DDR_IO_CTRL + + mww $DDR_ADDRCTRL_IOCTRL 0x84 + mww $DDR_ADDRCTRL_WD0_IOCTRL 0x00 + mww $DDR_ADDRCTRL_WD1_IOCTRL 0x00 + mww $DDR_DATA0_IOCTRL 0x84 + mww $DDR_DATA1_IOCTRL 0x84 + mww $DDR_DATA2_IOCTRL 0x84 + mww $DDR_DATA3_IOCTRL 0x84 + + mww $DDR_IO_CTRL 0x00 + mww $DDR_CKE_CTRL 0x03 +} + +proc config_ddr_phy { } { + global EMIF_DDR_PHY_CTRL_1 + global EMIF_DDR_PHY_CTRL_1_SHDW + + global EXT_PHY_CTRL_1 + global EXT_PHY_CTRL_1_SHDW + global EXT_PHY_CTRL_2 + global EXT_PHY_CTRL_2_SHDW + global EXT_PHY_CTRL_3 + global EXT_PHY_CTRL_3_SHDW + global EXT_PHY_CTRL_4 + global EXT_PHY_CTRL_4_SHDW + global EXT_PHY_CTRL_5 + global EXT_PHY_CTRL_5_SHDW + global EXT_PHY_CTRL_6 + global EXT_PHY_CTRL_6_SHDW + global EXT_PHY_CTRL_7 + global EXT_PHY_CTRL_7_SHDW + global EXT_PHY_CTRL_8 + global EXT_PHY_CTRL_8_SHDW + global EXT_PHY_CTRL_9 + global EXT_PHY_CTRL_9_SHDW + global EXT_PHY_CTRL_10 + global EXT_PHY_CTRL_10_SHDW + global EXT_PHY_CTRL_11 + global EXT_PHY_CTRL_11_SHDW + global EXT_PHY_CTRL_12 + global EXT_PHY_CTRL_12_SHDW + global EXT_PHY_CTRL_13 + global EXT_PHY_CTRL_13_SHDW + global EXT_PHY_CTRL_14 + global EXT_PHY_CTRL_14_SHDW + global EXT_PHY_CTRL_15 + global EXT_PHY_CTRL_15_SHDW + global EXT_PHY_CTRL_16 + global EXT_PHY_CTRL_16_SHDW + global EXT_PHY_CTRL_17 + global EXT_PHY_CTRL_17_SHDW + global EXT_PHY_CTRL_18 + global EXT_PHY_CTRL_18_SHDW + global EXT_PHY_CTRL_19 + global EXT_PHY_CTRL_19_SHDW + global EXT_PHY_CTRL_20 + global EXT_PHY_CTRL_20_SHDW + global EXT_PHY_CTRL_21 + global EXT_PHY_CTRL_21_SHDW + global EXT_PHY_CTRL_22 + global EXT_PHY_CTRL_22_SHDW + global EXT_PHY_CTRL_23 + global EXT_PHY_CTRL_23_SHDW + global EXT_PHY_CTRL_24 + global EXT_PHY_CTRL_24_SHDW + global EXT_PHY_CTRL_25 + global EXT_PHY_CTRL_25_SHDW + global EXT_PHY_CTRL_26 + global EXT_PHY_CTRL_26_SHDW + global EXT_PHY_CTRL_27 + global EXT_PHY_CTRL_27_SHDW + global EXT_PHY_CTRL_28 + global EXT_PHY_CTRL_28_SHDW + global EXT_PHY_CTRL_29 + global EXT_PHY_CTRL_29_SHDW + global EXT_PHY_CTRL_30 + global EXT_PHY_CTRL_30_SHDW + global EXT_PHY_CTRL_31 + global EXT_PHY_CTRL_31_SHDW + global EXT_PHY_CTRL_32 + global EXT_PHY_CTRL_32_SHDW + global EXT_PHY_CTRL_33 + global EXT_PHY_CTRL_33_SHDW + global EXT_PHY_CTRL_34 + global EXT_PHY_CTRL_34_SHDW + global EXT_PHY_CTRL_35 + global EXT_PHY_CTRL_35_SHDW + global EXT_PHY_CTRL_36 + global EXT_PHY_CTRL_36_SHDW + + mww $EMIF_DDR_PHY_CTRL_1 0x8009 + mww $EMIF_DDR_PHY_CTRL_1_SHDW 0x8009 + + set slave_ratio 0x80 + set gatelvl_init_ratio 0x20 + set wr_dqs_slave_delay 0x60 + set rd_dqs_slave_delay 0x60 + set dq_offset 0x40 + set gatelvl_init_mode 0x01 + set wr_data_slave_delay 0x80 + set gatelvl_num_dq0 0x0f + set wrlvl_num_dq0 0x0f + + mww $EXT_PHY_CTRL_1 [ expr ($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio ] + mww $EXT_PHY_CTRL_1_SHDW [ expr ($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio ] + mww $EXT_PHY_CTRL_26 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_26_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_27 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_27_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_28 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_28_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_29 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_29_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_30 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_30_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] + mww $EXT_PHY_CTRL_31 0x00 + mww $EXT_PHY_CTRL_31_SHDW 0x00 + mww $EXT_PHY_CTRL_32 0x00 + mww $EXT_PHY_CTRL_32_SHDW 0x00 + mww $EXT_PHY_CTRL_33 0x00 + mww $EXT_PHY_CTRL_33_SHDW 0x00 + mww $EXT_PHY_CTRL_34 0x00 + mww $EXT_PHY_CTRL_34_SHDW 0x00 + mww $EXT_PHY_CTRL_35 0x00 + mww $EXT_PHY_CTRL_35_SHDW 0x00 + mww $EXT_PHY_CTRL_22 0x00 + mww $EXT_PHY_CTRL_22_SHDW 0x00 + mww $EXT_PHY_CTRL_23 [ expr ($wr_dqs_slave_delay << 16) | $rd_dqs_slave_delay ] + mww $EXT_PHY_CTRL_23_SHDW [ expr ($wr_dqs_slave_delay << 16) | $rd_dqs_slave_delay ] + mww $EXT_PHY_CTRL_24 [ expr ($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay ] + mww $EXT_PHY_CTRL_24_SHDW [ expr ($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay << 0 ] + mww $EXT_PHY_CTRL_25 [ expr ($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset ] + mww $EXT_PHY_CTRL_25_SHDW [ expr ($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset ] + mww $EXT_PHY_CTRL_36 [ expr ($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0 ] + mww $EXT_PHY_CTRL_36_SHDW [ expr ($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0 ] +} + +proc config_ddr_timing { } { + global EMIF_SDRAM_TIM_1 + global EMIF_SDRAM_TIM_2 + global EMIF_SDRAM_TIM_3 + global EMIF_SDRAM_TIM_1_SHDW + global EMIF_SDRAM_TIM_2_SHDW + global EMIF_SDRAM_TIM_3_SHDW + global EMIF_ZQ_CONFIG + + mww $EMIF_SDRAM_TIM_1 0xeaaad4db + mww $EMIF_SDRAM_TIM_1_SHDW 0xeaaad4db + + mww $EMIF_SDRAM_TIM_2 0x266b7fda + mww $EMIF_SDRAM_TIM_2_SHDW 0x266b7fda + + mww $EMIF_SDRAM_TIM_3 0x107f8678 + mww $EMIF_SDRAM_TIM_3_SHDW 0x107f8678 + + mww $EMIF_ZQ_CONFIG 0x50074be4 +} + +proc config_ddr_pm { } { + global EMIF_PWR_MGMT_CTRL + global EMIF_PWR_MGMT_CTRL_SHDW + global EMIF_DLL_CALIB_CTRL + global EMIF_DLL_CALIB_CTRL_SHDW + global EMIF_TEMP_ALERT_CONFIG + + mww $EMIF_PWR_MGMT_CTRL 0x00 + mww $EMIF_PWR_MGMT_CTRL_SHDW 0x00 + mww $EMIF_DLL_CALIB_CTRL 0x00050000 + mww $EMIF_DLL_CALIB_CTRL_SHDW 0x00050000 + mww $EMIF_TEMP_ALERT_CONFIG 0x00 +} + +proc config_ddr_priority { } { + global EMIF_PRI_COS_MAP + global EMIF_CONNID_COS_1_MAP + global EMIF_CONNID_COS_2_MAP + global EMIF_RD_WR_EXEC_THRSH + global COS_CONFIG + + mww $EMIF_PRI_COS_MAP 0x00 + mww $EMIF_CONNID_COS_1_MAP 0x00 + mww $EMIF_CONNID_COS_2_MAP 0x0 + mww $EMIF_RD_WR_EXEC_THRSH 0x0405 + mww $COS_CONFIG 0x00ffffff +} + +proc config_ddr3 { SDRAM_CONFIG } { + global CM_DLL_CTRL + global EMIF_IODFT_TLGC + global EMIF_RDWR_LVL_CTRL + global EMIF_RDWR_LVL_RMP_CTRL + global EMIF_SDRAM_CONFIG + global EMIF_SDRAM_CONFIG_EXT + global EMIF_SDRAM_REF_CTRL + global EMIF_SDRAM_REF_CTRL_SHDW + global EMIF_STATUS + global EXT_PHY_CTRL_36 + global EXT_PHY_CTRL_36_SHDW + + emif_prcm_clk_enable + vtp_enable + + set dll [ expr [ mrw $CM_DLL_CTRL ] & ~0x01 ] + mww $CM_DLL_CTRL $dll + while { !([ mrw $CM_DLL_CTRL ] & 0x04) } { } + + config_ddr_ioctrl + + mww $EMIF_SDRAM_CONFIG_EXT 0xc163 + mww $EMIF_IODFT_TLGC 0x2011 + mww $EMIF_IODFT_TLGC 0x2411 + mww $EMIF_IODFT_TLGC 0x2011 + mww $EMIF_SDRAM_REF_CTRL 0x80003000 + + config_ddr_phy + + mww $EMIF_IODFT_TLGC 0x2011 + mww $EMIF_IODFT_TLGC 0x2411 + mww $EMIF_IODFT_TLGC 0x2011 + + config_ddr_timing + config_ddr_pm + config_ddr_priority + + mww $EMIF_SDRAM_REF_CTRL 0x3000 + mww $EMIF_SDRAM_CONFIG $SDRAM_CONFIG + + mww $EMIF_SDRAM_REF_CTRL 0x0c30 + mww $EMIF_SDRAM_REF_CTRL_SHDW 0x0c30 + + sleep 10 + + set tmp [ expr [ mrw $EXT_PHY_CTRL_36 ] | 0x0100 ] + mww $EXT_PHY_CTRL_36 $tmp + mww $EXT_PHY_CTRL_36_SHDW $tmp + + mww $EMIF_RDWR_LVL_RMP_CTRL 0x80000000 + mww $EMIF_RDWR_LVL_CTRL 0x80000000 + + while { [ mrw $EMIF_RDWR_LVL_CTRL ] & 0x80000000 } { } + + if { [ mrw $EMIF_STATUS ] & 0x70 } { + error "DDR3 Hardware Leveling incomplete!!!" + } +} + +proc init_platform { SDRAM_CONFIG } { + config_opp100 + config_ddr3 $SDRAM_CONFIG + + # now that PLLs are configured, we can run JTAG at full speed + adapter_khz 16000 +} + $_TARGETNAME configure -event reset-start { adapter_khz 1000 } +$_TARGETNAME configure -event reset-init { init_platform 0x61a013b2 } $_TARGETNAME configure -event reset-end { disable_watchdog }