From df7f1e819f79232830d99bbb5875396db7f23335 Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Thu, 7 Oct 2021 19:43:07 +0200 Subject: [PATCH] init sdram in PROM --- .../9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c | 7 +- .../sbus_to_fpga_prom.py | 23 + sbus-to-ztex-gateware-migen/sdram_csr.fth | 152 +++--- sbus-to-ztex-gateware-migen/sdram_init.fth | 508 +++--------------- 4 files changed, 167 insertions(+), 523 deletions(-) diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c b/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c index b25cae6..0c6c882 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/sbusfpga_sdram.c @@ -306,12 +306,15 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux) sc->sc_bustag, sc->sc_burst, sbsc->sc_burst); - + + // the controller is now initialized in the PROM from values computed by sdram_init() + // if the board isn't a ZTex 2.13a, new bitslip/delays value might be needed + /* if (!sdram_init(sc)) { aprint_error_dev(self, "couldn't initialize SDRAM\n"); return; } - + */ if (!dma_init(sc)) { aprint_error_dev(self, "couldn't initialize DMA for SDRAM\n"); return; diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py index 80cb0ea..c764f4d 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py @@ -19,6 +19,27 @@ def get_header_map_stuff(name, size, type="csr"): r += f": map-out-{name} ( -- ) {name}-virt h# {size:x} map-out ;\n" return r +def get_header_map2_stuff(gname, name1, name2, size1, size2, type1="csr", type2="csr"): + r = f"my-address sbusfpga_{type1}addr_{name1} + my-space xdrphys h# {size1:x} xdrint xdr+\n" + r += f"my-address sbusfpga_{type2}addr_{name2} + my-space xdrphys xdr+ h# {size2:x} xdrint xdr+\n" + r += "\" reg\" attribute\n" + r += "h# 7f xdrint \" slave-burst-sizes\" attribute\n" # fixme: burst-sizes + r += "h# 7f xdrint \" burst-sizes\" attribute\n" # fixme: burst-sizes + r += "headers\n" + r += f"-1 instance value {name1}-virt\n" + r += f"-1 instance value {name2}-virt\n" + r += "my-address constant my-sbus-address\nmy-space constant my-sbus-space\n" + r += ": map-in ( adr space size -- virt ) \" map-in\" $call-parent ;\n: map-out ( virt size -- ) \" map-out\" $call-parent ;\n"; + r += f": map-in-{gname} ( -- )\n" + r += f"my-sbus-address sbusfpga_{type1}addr_{name1} + my-sbus-space h# {size1:x} map-in is {name1}-virt\n" + r += f"my-sbus-address sbusfpga_{type2}addr_{name2} + my-sbus-space h# {size2:x} map-in is {name2}-virt\n" + r += ";\n" + r += f": map-out-{gname} ( -- )\n" + r += f"{name1}-virt h# {size1:x} map-out\n" + r += f"{name2}-virt h# {size2:x} map-out\n" + r += ";\n" + return r + def get_header_map3_stuff(gname, name1, name2, name3, size1, size2, size3, type1="csr", type2="csr", type3="csr"): r = f"my-address sbusfpga_{type1}addr_{name1} + my-space xdrphys h# {size1:x} xdrint xdr+\n" r += f"my-address sbusfpga_{type2}addr_{name2} + my-space xdrphys xdr+ h# {size2:x} xdrint xdr+\n" @@ -99,6 +120,7 @@ def get_prom(soc, if (sdram): r += "\" RDOL,sdram\" device-name\n" r += get_header_map3_stuff("mregs", "ddrphy", "sdram", "exchange_with_mem", 4096, 4096, 4096) + r += "fload sdram_init.fth\ninit!\n" if (engine or i2c or cg3): r += "finish-device\nnew-device\n" @@ -126,6 +148,7 @@ def get_prom(soc, buf_size=int(ceil(hres*vres)/1048576) for line in cg3_lines: r += line.replace("SBUSFPGA_CG3_WIDTH", hres_h).replace("SBUSFPGA_CG3_HEIGHT", vres_h).replace("SBUSFPGA_CG3_BUFSIZE", f"{buf_size*1048576:x}") + r += get_header_map2_stuff("cg3extraregs", "video_framebuffer", "video_framebuffer_vtg", 4096, 4096) r += "end0\n" diff --git a/sbus-to-ztex-gateware-migen/sdram_csr.fth b/sbus-to-ztex-gateware-migen/sdram_csr.fth index 84275c7..f7ab5f8 100644 --- a/sbus-to-ztex-gateware-migen/sdram_csr.fth +++ b/sbus-to-ztex-gateware-migen/sdram_csr.fth @@ -1,228 +1,228 @@ : dphy_rst_rd ( -- csr_value ) - mregs-virt h# 1000 + l@ + ddrphy-virt h# 0000 + l@ ; : dphy_half_sys8x_taps_rd ( -- csr_value ) - mregs-virt h# 1004 + l@ + ddrphy-virt h# 0004 + l@ ; : dphy_wlevel_en_rd ( -- csr_value ) - mregs-virt h# 1008 + l@ + ddrphy-virt h# 0008 + l@ ; : dphy_wlevel_strobe_rd ( -- csr_value ) - mregs-virt h# 100c + l@ + ddrphy-virt h# 000c + l@ ; : dphy_dly_sel_rd ( -- csr_value ) - mregs-virt h# 1010 + l@ + ddrphy-virt h# 0010 + l@ ; : dphy_rdly_dq_rst_rd ( -- csr_value ) - mregs-virt h# 1014 + l@ + ddrphy-virt h# 0014 + l@ ; : dphy_rdly_dq_inc_rd ( -- csr_value ) - mregs-virt h# 1018 + l@ + ddrphy-virt h# 0018 + l@ ; : dphy_rdly_dq_bitslip_rst_rd ( -- csr_value ) - mregs-virt h# 101c + l@ + ddrphy-virt h# 001c + l@ ; : dphy_rdly_dq_bitslip_rd ( -- csr_value ) - mregs-virt h# 1020 + l@ + ddrphy-virt h# 0020 + l@ ; : dphy_wdly_dq_bitslip_rst_rd ( -- csr_value ) - mregs-virt h# 1024 + l@ + ddrphy-virt h# 0024 + l@ ; : dphy_wdly_dq_bitslip_rd ( -- csr_value ) - mregs-virt h# 1028 + l@ + ddrphy-virt h# 0028 + l@ ; : dphy_rdphase_rd ( -- csr_value ) - mregs-virt h# 102c + l@ + ddrphy-virt h# 002c + l@ ; : dphy_wrphase_rd ( -- csr_value ) - mregs-virt h# 1030 + l@ + ddrphy-virt h# 0030 + l@ ; : sdr_dfii_control_rd ( -- csr_value ) - mregs-virt h# 2000 + l@ + sdram-virt h# 0000 + l@ ; : sdr_dfii_pi0_command_rd ( -- csr_value ) - mregs-virt h# 2004 + l@ + sdram-virt h# 0004 + l@ ; : sdr_dfii_pi0_command_issue_rd ( -- csr_value ) - mregs-virt h# 2008 + l@ + sdram-virt h# 0008 + l@ ; : sdr_dfii_pi0_address_rd ( -- csr_value ) - mregs-virt h# 200c + l@ + sdram-virt h# 000c + l@ ; : sdr_dfii_pi0_baddress_rd ( -- csr_value ) - mregs-virt h# 2010 + l@ + sdram-virt h# 0010 + l@ ; : sdr_dfii_pi0_wrdata_rd ( -- csr_value ) - mregs-virt h# 2014 + l@ + sdram-virt h# 0014 + l@ ; : sdr_dfii_pi0_rddata_rd ( -- csr_value ) - mregs-virt h# 2018 + l@ + sdram-virt h# 0018 + l@ ; : sdr_dfii_pi1_command_rd ( -- csr_value ) - mregs-virt h# 201c + l@ + sdram-virt h# 001c + l@ ; : sdr_dfii_pi1_command_issue_rd ( -- csr_value ) - mregs-virt h# 2020 + l@ + sdram-virt h# 0020 + l@ ; : sdr_dfii_pi1_address_rd ( -- csr_value ) - mregs-virt h# 2024 + l@ + sdram-virt h# 0024 + l@ ; : sdr_dfii_pi1_baddress_rd ( -- csr_value ) - mregs-virt h# 2028 + l@ + sdram-virt h# 0028 + l@ ; : sdr_dfii_pi1_wrdata_rd ( -- csr_value ) - mregs-virt h# 202c + l@ + sdram-virt h# 002c + l@ ; : sdr_dfii_pi1_rddata_rd ( -- csr_value ) - mregs-virt h# 2030 + l@ + sdram-virt h# 0030 + l@ ; : sdr_dfii_pi2_command_rd ( -- csr_value ) - mregs-virt h# 2034 + l@ + sdram-virt h# 0034 + l@ ; : sdr_dfii_pi2_command_issue_rd ( -- csr_value ) - mregs-virt h# 2038 + l@ + sdram-virt h# 0038 + l@ ; : sdr_dfii_pi2_address_rd ( -- csr_value ) - mregs-virt h# 203c + l@ + sdram-virt h# 003c + l@ ; : sdr_dfii_pi2_baddress_rd ( -- csr_value ) - mregs-virt h# 2040 + l@ + sdram-virt h# 0040 + l@ ; : sdr_dfii_pi2_wrdata_rd ( -- csr_value ) - mregs-virt h# 2044 + l@ + sdram-virt h# 0044 + l@ ; : sdr_dfii_pi2_rddata_rd ( -- csr_value ) - mregs-virt h# 2048 + l@ + sdram-virt h# 0048 + l@ ; : sdr_dfii_pi3_command_rd ( -- csr_value ) - mregs-virt h# 204c + l@ + sdram-virt h# 004c + l@ ; : sdr_dfii_pi3_command_issue_rd ( -- csr_value ) - mregs-virt h# 2050 + l@ + sdram-virt h# 0050 + l@ ; : sdr_dfii_pi3_address_rd ( -- csr_value ) - mregs-virt h# 2054 + l@ + sdram-virt h# 0054 + l@ ; : sdr_dfii_pi3_baddress_rd ( -- csr_value ) - mregs-virt h# 2058 + l@ + sdram-virt h# 0058 + l@ ; : sdr_dfii_pi3_wrdata_rd ( -- csr_value ) - mregs-virt h# 205c + l@ + sdram-virt h# 005c + l@ ; : sdr_dfii_pi3_rddata_rd ( -- csr_value ) - mregs-virt h# 2060 + l@ + sdram-virt h# 0060 + l@ ; : dphy_rst_wr ( value -- ) - mregs-virt h# 1000 + l! + ddrphy-virt h# 0000 + l! ; : dphy_half_sys8x_taps_wr ( value -- ) - mregs-virt h# 1004 + l! + ddrphy-virt h# 0004 + l! ; : dphy_wlevel_en_wr ( value -- ) - mregs-virt h# 1008 + l! + ddrphy-virt h# 0008 + l! ; : dphy_wlevel_strobe_wr ( value -- ) - mregs-virt h# 100c + l! + ddrphy-virt h# 000c + l! ; : dphy_dly_sel_wr ( value -- ) - mregs-virt h# 1010 + l! + ddrphy-virt h# 0010 + l! ; : dphy_rdly_dq_rst_wr ( value -- ) - mregs-virt h# 1014 + l! + ddrphy-virt h# 0014 + l! ; : dphy_rdly_dq_inc_wr ( value -- ) - mregs-virt h# 1018 + l! + ddrphy-virt h# 0018 + l! ; : dphy_rdly_dq_bitslip_rst_wr ( value -- ) - mregs-virt h# 101c + l! + ddrphy-virt h# 001c + l! ; : dphy_rdly_dq_bitslip_wr ( value -- ) - mregs-virt h# 1020 + l! + ddrphy-virt h# 0020 + l! ; : dphy_wdly_dq_bitslip_rst_wr ( value -- ) - mregs-virt h# 1024 + l! + ddrphy-virt h# 0024 + l! ; : dphy_wdly_dq_bitslip_wr ( value -- ) - mregs-virt h# 1028 + l! + ddrphy-virt h# 0028 + l! ; : dphy_rdphase_wr ( value -- ) - mregs-virt h# 102c + l! + ddrphy-virt h# 002c + l! ; : dphy_wrphase_wr ( value -- ) - mregs-virt h# 1030 + l! + ddrphy-virt h# 0030 + l! ; : sdr_dfii_control_wr ( value -- ) - mregs-virt h# 2000 + l! + sdram-virt h# 0000 + l! ; : sdr_dfii_pi0_command_wr ( value -- ) - mregs-virt h# 2004 + l! + sdram-virt h# 0004 + l! ; : sdr_dfii_pi0_command_issue_wr ( value -- ) - mregs-virt h# 2008 + l! + sdram-virt h# 0008 + l! ; : sdr_dfii_pi0_address_wr ( value -- ) - mregs-virt h# 200c + l! + sdram-virt h# 000c + l! ; : sdr_dfii_pi0_baddress_wr ( value -- ) - mregs-virt h# 2010 + l! + sdram-virt h# 0010 + l! ; : sdr_dfii_pi0_wrdata_wr ( value -- ) - mregs-virt h# 2014 + l! + sdram-virt h# 0014 + l! ; : sdr_dfii_pi0_rddata_wr ( value -- ) - mregs-virt h# 2018 + l! + sdram-virt h# 0018 + l! ; : sdr_dfii_pi1_command_wr ( value -- ) - mregs-virt h# 201c + l! + sdram-virt h# 001c + l! ; : sdr_dfii_pi1_command_issue_wr ( value -- ) - mregs-virt h# 2020 + l! + sdram-virt h# 0020 + l! ; : sdr_dfii_pi1_address_wr ( value -- ) - mregs-virt h# 2024 + l! + sdram-virt h# 0024 + l! ; : sdr_dfii_pi1_baddress_wr ( value -- ) - mregs-virt h# 2028 + l! + sdram-virt h# 0028 + l! ; : sdr_dfii_pi1_wrdata_wr ( value -- ) - mregs-virt h# 202c + l! + sdram-virt h# 002c + l! ; : sdr_dfii_pi1_rddata_wr ( value -- ) - mregs-virt h# 2030 + l! + sdram-virt h# 0030 + l! ; : sdr_dfii_pi2_command_wr ( value -- ) - mregs-virt h# 2034 + l! + sdram-virt h# 0034 + l! ; : sdr_dfii_pi2_command_issue_wr ( value -- ) - mregs-virt h# 2038 + l! + sdram-virt h# 0038 + l! ; : sdr_dfii_pi2_address_wr ( value -- ) - mregs-virt h# 203c + l! + sdram-virt h# 003c + l! ; : sdr_dfii_pi2_baddress_wr ( value -- ) - mregs-virt h# 2040 + l! + sdram-virt h# 0040 + l! ; : sdr_dfii_pi2_wrdata_wr ( value -- ) - mregs-virt h# 2044 + l! + sdram-virt h# 0044 + l! ; : sdr_dfii_pi2_rddata_wr ( value -- ) - mregs-virt h# 2048 + l! + sdram-virt h# 0048 + l! ; : sdr_dfii_pi3_command_wr ( value -- ) - mregs-virt h# 204c + l! + sdram-virt h# 004c + l! ; : sdr_dfii_pi3_command_issue_wr ( value -- ) - mregs-virt h# 2050 + l! + sdram-virt h# 0050 + l! ; : sdr_dfii_pi3_address_wr ( value -- ) - mregs-virt h# 2054 + l! + sdram-virt h# 0054 + l! ; : sdr_dfii_pi3_baddress_wr ( value -- ) - mregs-virt h# 2058 + l! + sdram-virt h# 0058 + l! ; : sdr_dfii_pi3_wrdata_wr ( value -- ) - mregs-virt h# 205c + l! + sdram-virt h# 005c + l! ; : sdr_dfii_pi3_rddata_wr ( value -- ) - mregs-virt h# 2060 + l! + sdram-virt h# 0060 + l! ; diff --git a/sbus-to-ztex-gateware-migen/sdram_init.fth b/sbus-to-ztex-gateware-migen/sdram_init.fth index e86ed69..39f458b 100644 --- a/sbus-to-ztex-gateware-migen/sdram_init.fth +++ b/sbus-to-ztex-gateware-migen/sdram_init.fth @@ -1,14 +1,12 @@ -headers - fload sdram_csr.fth -external +\ useful stuff -: popcnt ( n -- u) - 0 swap - BEGIN dup WHILE tuck 1 AND + swap 1 rshift REPEAT - DROP -; +\ : popcnt ( n -- u) +\ 0 swap +\ BEGIN dup WHILE tuck 1 AND + swap 1 rshift REPEAT +\ DROP +\ ; : cdelay ( count -- ) \ Forth loop always have a least one iteration @@ -17,7 +15,7 @@ external else drop then ; -headers +\ helpers : sdram_software_control_on ( -- ) sdr_dfii_control_rd @@ -29,6 +27,8 @@ headers h# 1 <> if h# 1 sdr_dfii_control_wr then ; +\ only p0 is really used + : command_p0 ( cmd -- ) sdr_dfii_pi0_command_wr 1 sdr_dfii_pi0_command_issue_wr @@ -46,470 +46,52 @@ headers 1 sdr_dfii_pi3_command_issue_wr ; +\ init for 2.13a (might need change for others?) + : init_sequence ( -- ) - .( init_sequence ) cr + \ .( init_sequence ) cr + \ Release reset h# 0 sdr_dfii_pi0_address_wr h# 0 sdr_dfii_pi0_baddress_wr h# c sdr_dfii_control_wr - 50 ms + 5 ms + \ Bring CKE high h# 0 sdr_dfii_pi0_address_wr h# 0 sdr_dfii_pi0_baddress_wr h# e sdr_dfii_control_wr - 10 ms + 1 ms + \ Load Mode register 2, CWL=5 h# 200 sdr_dfii_pi0_address_wr h# 2 sdr_dfii_pi0_baddress_wr h# f command_p0 + \ Load Mode register 3 h# 0 sdr_dfii_pi0_address_wr h# 3 sdr_dfii_pi0_baddress_wr h# f command_p0 + \ Load Mode Register 1 h# 6 sdr_dfii_pi0_address_wr h# 1 sdr_dfii_pi0_baddress_wr h# f command_p0 + \ Load Mode Register 0, CL=6, BL=8 h# 920 sdr_dfii_pi0_address_wr h# 0 sdr_dfii_pi0_baddress_wr h# f command_p0 200 cdelay + \ ZQ Calibration h# 400 sdr_dfii_pi0_address_wr 0 sdr_dfii_pi0_baddress_wr h# 3 command_p0 200 cdelay ; -: sdram_read_leveling_rst_delay ( modulenum -- ) - h# 1 swap << dphy_dly_sel_wr - h# 1 dphy_rdly_dq_rst_wr - h# 0 dphy_dly_sel_wr -; - -: sdram_read_leveling_inc_delay ( modulenum -- ) - h# 1 swap << dphy_dly_sel_wr - h# 1 dphy_rdly_dq_inc_wr - h# 0 dphy_dly_sel_wr -; - -: sdram_read_leveling_rst_bitslip ( modulenum -- ) - h# 1 swap << dphy_dly_sel_wr - h# 1 dphy_rdly_dq_bitslip_rst_wr - h# 0 dphy_dly_sel_wr -; - -: sdram_read_leveling_inc_bitslip ( modulenum -- ) - h# 1 swap << dphy_dly_sel_wr - h# 1 dphy_rdly_dq_bitslip_wr - h# 0 dphy_dly_sel_wr -; - -: lfsr ( bits prev -- res ) - dup 1 and not ( bits prev -- bits prev ~{prev&1} ) - swap 1 >> ( bits prev ~{prev&1} -- bits ~{prev&1} {prev>>1} ) - swap ( bits prev ~{prev&1} -- bits {prev>>1} ~{prev&1} ) - rot ( bits {prev>>1} ~{prev&1} -- {prev>>1} ~{prev&1} bits ) - \ assume bits is 32, 'cause it is - drop h# 80200003 ( {prev>>1} ~{prev&1} bits -- {prev>>1} ~{prev&1} lfsr_taps[bits] ) - and - xor -; - -: sdram_activate_test_row ( -- ) - h# 0 sdr_dfii_pi0_address_wr - h# 0 sdr_dfii_pi0_baddress_wr - h# 9 command_p0 - 15 cdelay -; - -: sdram_precharge_test_row ( -- ) - h# 0 sdr_dfii_pi0_address_wr - h# 0 sdr_dfii_pi0_baddress_wr - h# b command_p0 - 15 cdelay -; - -: command_px ( phase value -- ) - over 3 = if dup command_p3 then - over 2 = if dup command_p2 then - over 1 = if dup command_p1 then - over 0 = if dup command_p0 then - 2drop -; - -: command_prd ( value -- ) - dphy_rdphase_rd - swap command_px -; - -: command_pwr ( value -- ) - dphy_wrphase_rd - swap command_px -; - -: sdr_dfii_pix_address_wr ( phase value -- ) - over 3 = if dup sdr_dfii_pi3_address_wr then - over 2 = if dup sdr_dfii_pi2_address_wr then - over 1 = if dup sdr_dfii_pi1_address_wr then - over 0 = if dup sdr_dfii_pi0_address_wr then - 2drop -; - -: sdr_dfii_pird_address_wr ( value -- ) - dphy_rdphase_rd - swap sdr_dfii_pix_address_wr -; - -: sdr_dfii_piwr_address_wr ( value -- ) - dphy_wrphase_rd - swap sdr_dfii_pix_address_wr -; - -: sdr_dfii_pix_baddress_wr ( phase value -- ) - over 3 = if dup sdr_dfii_pi3_baddress_wr then - over 2 = if dup sdr_dfii_pi2_baddress_wr then - over 1 = if dup sdr_dfii_pi1_baddress_wr then - over 0 = if dup sdr_dfii_pi0_baddress_wr then - 2drop -; - -: sdr_dfii_pird_baddress_wr ( value -- ) - dphy_rdphase_rd - swap sdr_dfii_pix_baddress_wr -; - -: sdr_dfii_piwr_baddress_wr ( value -- ) - dphy_wrphase_rd - swap sdr_dfii_pix_baddress_wr -; - -: sdr_wr_rd_chk_tst_pat_get ( seed -- A B C D ) -\ .( sdr_wr_rd_chk_tst_pat_get ) cr - dup 42 = if h# 00000080 swap then - dup 42 = if h# 00000000 swap then - dup 42 = if h# 00000000 swap then - dup 42 = if h# 15090700 swap then - dup 84 = if h# 00000000 swap then - dup 84 = if h# 00000000 swap then - dup 84 = if h# 00000000 swap then - dup 84 = if h# 2a150907 swap then - drop -; - -: sdr_wr_rd_check_test_pattern ( modulenum seed -- errors ) -\ .( sdr_wr_rd_check_test_pattern ) cr - sdram_activate_test_row - dup sdr_wr_rd_chk_tst_pat_get - \ should have the 4 patterns on top of the stack: modulenum seed p0 p1 p2 p3 - sdr_dfii_pi0_wrdata_wr - sdr_dfii_pi1_wrdata_wr - sdr_dfii_pi2_wrdata_wr - sdr_dfii_pi3_wrdata_wr - \ should be back at modulenum seed - h# 0 sdr_dfii_piwr_address_wr - h# 0 sdr_dfii_piwr_baddress_wr - h# 17 command_pwr - 15 cdelay - - h# 0 sdr_dfii_pird_address_wr - h# 0 sdr_dfii_pird_baddress_wr - h# 25 command_prd - 15 cdelay - - sdram_precharge_test_row - - sdr_wr_rd_chk_tst_pat_get - \ should have the 4 patterns on top of the stack: modulenum p0 p1 p2 p3 - sdr_dfii_pi0_rddata_rd xor popcnt - \ should be at modulenum p0 p1 p2 errors - swap sdr_dfii_pi0_rddata_rd xor popcnt + - \ should be at modulenum p0 p1 errors - swap sdr_dfii_pi0_rddata_rd xor popcnt + - \ should be at modulenum p0 errors - swap sdr_dfii_pi0_rddata_rd xor popcnt + - \ should be at modulenum errors - \ drop modulenum - nip -; - -: sdram_read_leveling_scan_module ( modulenum bitslip -- score ) -\ .( sdram_read_leveling_scan_module ) cr - over sdram_read_leveling_rst_delay - \ push score - 0 - \ we should be at 'modulenum bitslip score' - 32 0 do -\ .( starting rd_lvl_scan loop with stack: ) .s cr - 2 pick 42 sdr_wr_rd_check_test_pattern - \ now we have an error count at the top - 3 pick 84 sdr_wr_rd_check_test_pattern - \ merge both error count - + - \ we should be at 'modulenum bitslip score errorcount' - dup 0= - \ we should be at 'modulenum bitslip score errorcount working?' - if 16384 else 0 then - \ we should be at 'modulenum bitslip score errorcount (0|16384)' - swap 512 swap - - \ we should be at 'modulenum bitslip score (0|16384) (512-errorcount)' - + - + - \ we should be at 'modulenum bitslip score' - 2 pick sdram_read_leveling_inc_delay - loop - nip - nip -; - -: sdr_wr_lat_cal_bitslip_loop ( modulenum bestbitslip bestscore bitslip -- modulenum bestbitslip bestscore ) -\ .( sdr_wr_lat_cal_bitslip_loop for module: ) 3 pick . .( bitslip: ) dup . cr -\ .( sdr_wr_lat_cal_bitslip_loop, stack: ) .s cr - 1 4 pick << dphy_dly_sel_wr ( '4 pick' will extract modulenum, needed as we're stacking the '1' ) - 1 dphy_wdly_dq_bitslip_rst_wr - \ Forth loop always have a least one iteration - dup 0<> if - dup 0 do - 1 dphy_wdly_dq_bitslip_wr - loop - then - 0 dphy_dly_sel_wr -\ .( sdr_wr_lat_cal_bitslip_loop after bitslip init loop, stack: ) .s cr - \ push current score - 0 ( we should be at 'modulenum bestbitslip bestscore bitslip score' ) - 4 pick sdram_read_leveling_rst_bitslip - 8 0 do - 4 pick over sdram_read_leveling_scan_module - \ we should be at 'modulenum bestbitslip bestscore bitslip score score', max will merge scores - max - \ we should be at 'modulenum bestbitslip bestscore bitslip score' again - 4 pick sdram_read_leveling_inc_bitslip - loop - .( sdr_wr_lat_cal_bitslip_loop after bitslip check loop, stack: ) .s cr - dup 3 pick > - if -\ .( lat_cal best bitslip was: ) 3 pick . .( with score: ) 2 pick . cr - 2swap - .( lat_cal best bitslip now: ) 3 pick . .( with score: ) 2 pick . cr - then - 2drop -\ .( sdr_wr_lat_cal_bitslip_loop end, stack: ) .s cr -; - -: sdr_wr_lat_cal_module_loop ( modulenum -- ) - .( sdr_wr_lat_cal_module_loop for module: ) dup . cr - \ push best_bitslip - -1 - \ push best_score - 0 - \ we should have 'modulenum 1 0' - 8 0 do - i sdr_wr_lat_cal_bitslip_loop - 2 +loop - \ we should be at 'modulenum bestbitslip bestscore' - \ we don't need score anymore - drop - \ we should be at 'modulenum bestbitslip' - 1 2 pick << dphy_dly_sel_wr - 1 dphy_wdly_dq_bitslip_rst_wr - .( sdr_wr_lat_cal_module_loop: best bitslip: ) dup . cr - \ loop that consumes bestbitslip as the upper bound - \ Forth loop always have a least one iteration - dup 0<> if - 0 do - 1 dphy_wdly_dq_bitslip_wr - loop - else drop then - 0 dphy_dly_sel_wr - \ drop the modulenum - drop -; - -: sdram_write_latency_calibration ( -- ) - .( sdram_write_latency_calibration ) cr - 2 0 do - i sdr_wr_lat_cal_module_loop - loop -; - -: sdram_leveling_center_module ( modulenum -- ) - .( sdram_leveling_center_module ) cr - dup sdram_read_leveling_rst_delay - \ push delay_min - -1 - \ push delay - 0 - \ we should be at 'modulenum delay_min delay' - begin -\ .( starting lvl_center loop with stack: ) .s cr - 2 pick 42 sdr_wr_rd_check_test_pattern - .( we should be at 'modulenum delay_min delay error' stack: ) .s cr - 3 pick 84 sdr_wr_rd_check_test_pattern - .( we should be at 'modulenum delay_min delay error error' stack: ) .s cr - + - \ we should be at 'modulenum delay_min delay error' -\ .( we should be at 'modulenum delay_min delay error' stack: ) .s cr - 0= - \ we should be at 'modulenum delay_min delay working' -\ .( we should be at 'modulenum delay_min delay working' stack: ) .s cr - 2 pick 0< and - \ we should be at 'modulenum delay_min delay {working&delay_min<0}' -\ .( we should be at 'modulenum delay_min delay {working&delay_min<0}' stack: ) .s cr - dup if rot drop 2dup rot drop then - not - \ we should be at 'modulenum new_delay_min delay !{working&delay_min<0}' -\ .( we should be at 'modulenum new_delay_min delay !{working&delay_min<0}' stack: ) .s cr - \ test delay before incrementing, if already 31 no point in continuing/incrementing - over 31 < -\ .( we should be at 'modulenum new_delay_min delay !{working&delay_min<0} <31' stack: ) .s cr - dup if rot 1+ -rot then - dup if 4 pick sdram_read_leveling_inc_delay then - \ and the conditions to signal end-of-loop - and -\ .( we should be at 'modulenum new_delay_min delay !{working&delay_min<0}&<31' stack: ) .s cr -\ .( finishing lvl_center loop with stack: ) .s cr - not until - \ we should be at 'modulenum new_delay_min delay', the while has consumed the condition - .( we should be at 'modulenum new_delay_min delay' stack: ) .s cr - 1+ - 2 pick sdram_read_leveling_inc_delay - \ build a clean stack, startin with a copy of modulenum - 2 pick - \ push delay_max - -1 - \ we're at 'modulenum new_delay_min delay modulenum delay_max' - \ push delay - 2 pick - \ we're at 'modulenum new_delay_min delay modulenum delay_max delay' - .( we should be at 'modulenum new_delay_min delay modulenum delay_max delay ' stack: ) .s cr - \ this is almost the same loop, except with !working instead of working and delay_max instead of delay_min - begin - 2 pick 42 sdr_wr_rd_check_test_pattern - 3 pick 84 sdr_wr_rd_check_test_pattern - + - \ we should be at 'modulenum delay_max delay error' - 0<> - \ we should be at 'modulenum delay_max delay !working' - 2 pick 0< and - \ we should be at 'modulenum delay_max delay {!working&delay_max<0}' - dup if rot drop 2dup rot drop then - not - \ we should be at 'modulenum new_delay_max delay !{!working&delay_max<0}' - \ test delay before incrementing, if already 31 no point in continuing/incrementing - over 31 < - dup not if rot 1+ -rot then - dup not if 4 pick sdram_read_leveling_inc_delay then - \ and the conditions to signal end-of-loop - and - not until - \ we should be at 'modulenum new_delay_min delay modulenum new_delay_max delay', the while has consumed the condition - .( we should be at 'modulenum new_delay_min delay modulenum new_delay_max delay ' stack: ) .s cr - \ keep delay if new_delay_max<0, new_delay_max otherwise - over 0< if nip else drop then - \ we should be at 'modulenum new_delay_min delay modulenum new_delay_max' - nip - nip - \ we should be at 'modulenum new_delay_min new_delay_max' - .( we should be at 'modulenum new_delay_min new_delay_max' stack: ) .s cr - \ compute delay_mid - 2dup + 2/ 32 mod - \ we should be at 'modulenum new_delay_min new_delay_max {{new_delay_min+new_delay_max}/2%32}' - \ compute delay_range - 3dup drop swap - 2/ - \ we should be at 'modulenum new_delay_min new_delay_max {{new_delay_min+new_delay_max}/2%32} {{new_delay_max-new_delay_min}/2}' - .( we should be at 'modulenum new_delay_min new_delay_max delay_mid delay_range ' stack: ) .s cr - 4 pick sdram_read_leveling_rst_delay - 100 cdelay - \ Forth loop always have a least one iteration - over 0<> if - over 0 do - 4 pick sdram_read_leveling_inc_delay - 100 cdelay - loop - then - drop - drop - drop - drop - drop -; - -: sdr_rd_lvl_bitslip_loop ( modulenum bestbitslip bestscore bitslip -- modulenum bestbitslip bestscore ) -\ .( sdr_rd_lvl_bitslip_loop, stack: ) .s cr - 3 pick over sdram_read_leveling_scan_module - \ we should be at 'modulenum bestbitslip bestscore bitslip score' - 4 pick sdram_leveling_center_module - \ preserve a bitslip for the later test - over - \ (we should be at 'modulenum bestbitslip bestscore bitslip score bitslip') move it out of the way - .( we should be at 'modulenum bestbitslip bestscore bitslip score bitslip' stack: ) .s cr - 5 roll ( 'modulenum bestscore bitslip score bitslip bestbitslip' ) - 5 roll ( 'modulenum bitslip score bitslip bestbitslip bestscore' ) - 5 roll ( 'modulenum score bitslip bestbitslip bestscore bitslip' ) - 5 roll ( 'modulenum bitslip bestbitslip bestscore bitslip score' ) - .( we should be at 'modulenum bitslip bestbitslip bestscore bitslip score' stack: ) .s cr - \ compare the score and bestcore - dup 3 pick > - if - 2swap - .( rd_lvl best bitslip now: ) 3 pick . .( with score: ) 2 pick . cr - then - 2drop - \ we should be at 'modulenum bitslip bestbitslip bestscore' - rot - \ we should be at 'modulenum bestbitslip bestscore bitslip' - .( we should be at 'modulenum bestbitslip bestscore bitslip' stack: ) .s cr - 7 <> if 2 pick sdram_read_leveling_inc_bitslip then -; - -: sdr_rd_lvl_module_loop ( modulenum -- ) - .( sdr_rd_lvl_module_loop ) cr - 1 over << sdram_read_leveling_rst_bitslip - \ push best_bitslip - 0 - \ push best_score - 0 - \ we should have 'modulenum 0 0' - 8 0 do - i sdr_rd_lvl_bitslip_loop - loop - \ don't need the score anymore - drop - 2 pick sdram_read_leveling_rst_bitslip - .( sdr_rd_lvl_module_loop, best bitslip: ) dup . cr - \ Forth loop always have a least one iteration - dup 0<> if - \ consume best_bitslip as loop upper bound - 0 do - dup sdram_leveling_center_module - loop - else drop then - drop -; - -: sdram_read_leveling ( -- ) - .( sdram_read_leveling ) cr - 2 0 do - i sdr_rd_lvl_module_loop - loop -; - -: sdram_leveling ( -- ) - .( sdram_leveling ) cr - sdram_software_control_on - 2 0 do - i sdram_read_leveling_rst_delay - i sdram_read_leveling_rst_bitslip - loop - sdram_write_latency_calibration - sdram_read_leveling - sdram_software_control_off -; - -external - : init_sdram ( -- ) - .( init_sdram ) cr + \ .( init_sdram ) cr 2 dphy_rdphase_wr 3 dphy_wrphase_wr sdram_software_control_on @@ -517,17 +99,53 @@ external 1 ms 0 dphy_rst_wr 1 ms - .( going to init_sequence ) cr + \ .( going to init_sequence ) cr init_sequence - .( going to sdram_leveling ) cr - sdram_leveling - \ redundant + \ .( hw ctrl ) cr sdram_software_control_off + + \ .( config module 0 write ) cr + 1 dphy_dly_sel_wr + 1 dphy_wdly_dq_bitslip_rst_wr + \ 0 bitslip + 0 dphy_dly_sel_wr + + \ .( config module 1 write ) cr + 2 dphy_dly_sel_wr + 1 dphy_wdly_dq_bitslip_rst_wr + \ 0 bitslip + 0 dphy_dly_sel_wr + + \ .( config module 0 read ) cr + 1 dphy_dly_sel_wr + 1 dphy_rdly_dq_bitslip_rst_wr + 1 0 do + 1 0 do 1 dphy_rdly_dq_bitslip_wr loop + loop + 1 dphy_rdly_dq_rst_wr + 25 0 do + 1 dphy_rdly_dq_inc_wr + loop + + \ .( config module 1 read ) cr + 2 dphy_dly_sel_wr + 1 dphy_rdly_dq_bitslip_rst_wr + 1 0 do + 1 0 do 1 dphy_rdly_dq_bitslip_wr loop + loop + 1 dphy_rdly_dq_rst_wr + 25 0 do + 1 dphy_rdly_dq_inc_wr + loop + \ .( finish ) cr + 0 dphy_dly_sel_wr + \ .( done ) cr ; : init! ( -- ) - .( init ) cr + \ .( init ) cr map-in-mregs init_sdram map-out-mregs ; +