From dc4f9772baabb406c8b3ca948663b9ec78111f96 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 28 Apr 2021 14:15:48 +0200 Subject: [PATCH] software/liblitedram/sdram.c: Move common centering functions to separate section. --- litex/soc/software/liblitedram/sdram.c | 330 +++++++++++++------------ 1 file changed, 167 insertions(+), 163 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index d25451155..432ce9ea1 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -250,6 +250,173 @@ void sdram_mode_register_write(char reg, int value) { #ifdef CSR_DDRPHY_BASE +/*-----------------------------------------------------------------------*/ +/* Leveling Centering (Common for Read/Write Leveling) */ +/*-----------------------------------------------------------------------*/ + +typedef void (*delay_callback)(int module); + +static void sdram_activate_test_row(void) { + sdram_dfii_pi0_address_write(0); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS); + cdelay(15); +} + +static void sdram_precharge_test_row(void) { + sdram_dfii_pi0_address_write(0); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS); + cdelay(15); +} + +static int sdram_write_read_check_test_pattern(int module, unsigned int seed) { + int p, i; + unsigned int prv; + unsigned char tst[DFII_PIX_DATA_BYTES]; + unsigned char prs[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES]; + + /* Generate pseudo-random sequence */ + prv = seed; + for(p=0;p> module) & 0x1) != 1) + return 0; +#endif + + return 1; +} + +static void sdram_leveling_center_module( + int module, int show_short, int show_long, delay_callback rst_delay, delay_callback inc_delay) +{ + int i; + int show; + int working; + int delay, delay_mid, delay_range; + int delay_min = -1, delay_max = -1; + + if (show_long) + printf("m%d: |", module); + + /* Find smallest working delay */ + delay = 0; + rst_delay(module); + while(1) { + working = sdram_write_read_check_test_pattern(module, 42); + working &= sdram_write_read_check_test_pattern(module, 84); + show = show_long; +#if SDRAM_PHY_DELAYS > 32 + show = show && (delay%16 == 0); +#endif + if (show) + printf(working ? "1" : "0"); + if(working && delay_min < 0) { + delay_min = delay; + break; + } + delay++; + if(delay >= SDRAM_PHY_DELAYS) + break; + inc_delay(module); + } + + /* Get a bit further into the working zone */ +#if SDRAM_PHY_DELAYS > 32 + for(i=0;i<16;i++) { + delay += 1; + inc_delay(module); + } +#else + delay++; + inc_delay(module); +#endif + + /* Find largest working delay */ + while(1) { + working = sdram_write_read_check_test_pattern(module, 42); + working &= sdram_write_read_check_test_pattern(module, 84); + show = show_long; +#if SDRAM_PHY_DELAYS > 32 + show = show && (delay%16 == 0); +#endif + if (show) + printf(working ? "1" : "0"); + if(!working && delay_max < 0) { + delay_max = delay; + } + delay++; + if(delay >= SDRAM_PHY_DELAYS) + break; + inc_delay(module); + } + if(delay_max < 0) { + delay_max = delay; + } + + if (show_long) + printf("| "); + + delay_mid = (delay_min+delay_max)/2 % SDRAM_PHY_DELAYS; + delay_range = (delay_max-delay_min)/2; + if (show_short) { + if (delay_min < 0) + printf("delays: -"); + else + printf("delays: %02d+-%02d", delay_mid, delay_range); + } + + if (show_long) + printf("\n"); + + /* Set delay to the middle */ + rst_delay(module); + cdelay(100); + for(i = 0; i < delay_mid; i++) { + inc_delay(module); + cdelay(100); + } +} + /*-----------------------------------------------------------------------*/ /* Write Leveling */ /*-----------------------------------------------------------------------*/ @@ -705,76 +872,6 @@ static void sdram_read_leveling_inc_bitslip(char m) ddrphy_dly_sel_write(0); } -static void sdram_activate_test_row(void) { - sdram_dfii_pi0_address_write(0); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS); - cdelay(15); -} - -static void sdram_precharge_test_row(void) { - sdram_dfii_pi0_address_write(0); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - cdelay(15); -} - -static int sdram_write_read_check_test_pattern(int module, unsigned int seed) { - int p, i; - unsigned int prv; - unsigned char tst[DFII_PIX_DATA_BYTES]; - unsigned char prs[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES]; - - /* Generate pseudo-random sequence */ - prv = seed; - for(p=0;p> module) & 0x1) != 1) - return 0; -#endif - - return 1; -} - static int sdram_read_leveling_scan_module(int module, int bitslip, int show) { int i; @@ -804,99 +901,6 @@ static int sdram_read_leveling_scan_module(int module, int bitslip, int show) return score; } -typedef void (*delay_callback)(int module); - -static void sdram_leveling_center_module( - int module, int show_short, int show_long, delay_callback rst_delay, delay_callback inc_delay) -{ - int i; - int show; - int working; - int delay, delay_mid, delay_range; - int delay_min = -1, delay_max = -1; - - if (show_long) - printf("m%d: |", module); - - /* Find smallest working delay */ - delay = 0; - rst_delay(module); - while(1) { - working = sdram_write_read_check_test_pattern(module, 42); - working &= sdram_write_read_check_test_pattern(module, 84); - show = show_long; -#if SDRAM_PHY_DELAYS > 32 - show = show && (delay%16 == 0); -#endif - if (show) - printf(working ? "1" : "0"); - if(working && delay_min < 0) { - delay_min = delay; - break; - } - delay++; - if(delay >= SDRAM_PHY_DELAYS) - break; - inc_delay(module); - } - - /* Get a bit further into the working zone */ -#if SDRAM_PHY_DELAYS > 32 - for(i=0;i<16;i++) { - delay += 1; - inc_delay(module); - } -#else - delay++; - inc_delay(module); -#endif - - /* Find largest working delay */ - while(1) { - working = sdram_write_read_check_test_pattern(module, 42); - working &= sdram_write_read_check_test_pattern(module, 84); - show = show_long; -#if SDRAM_PHY_DELAYS > 32 - show = show && (delay%16 == 0); -#endif - if (show) - printf(working ? "1" : "0"); - if(!working && delay_max < 0) { - delay_max = delay; - } - delay++; - if(delay >= SDRAM_PHY_DELAYS) - break; - inc_delay(module); - } - if(delay_max < 0) { - delay_max = delay; - } - - if (show_long) - printf("| "); - - delay_mid = (delay_min+delay_max)/2 % SDRAM_PHY_DELAYS; - delay_range = (delay_max-delay_min)/2; - if (show_short) { - if (delay_min < 0) - printf("delays: -"); - else - printf("delays: %02d+-%02d", delay_mid, delay_range); - } - - if (show_long) - printf("\n"); - - /* Set delay to the middle */ - rst_delay(module); - cdelay(100); - for(i = 0; i < delay_mid; i++) { - inc_delay(module); - cdelay(100); - } -} - #endif /* CSR_DDRPHY_BASE */ #endif /* CSR_SDRAM_BASE */