bios/sdram: update/simplify with new exported LiteDRAM parameters.

This commit is contained in:
Florent Kermarrec 2020-04-16 10:23:31 +02:00
parent 3915ed9760
commit c0f3710d66
3 changed files with 68 additions and 86 deletions

View File

@ -475,7 +475,7 @@ static void do_command(char *c)
else if(strcmp(token, "sdrwr") == 0) sdrwr(get_token(&c));
#ifdef CSR_DDRPHY_BASE
else if(strcmp(token, "sdrinit") == 0) sdrinit();
#ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
#ifdef SDRAM_PHY_WRITE_LEVELING_CAPABLE
else if(strcmp(token, "sdrwlon") == 0) sdrwlon();
else if(strcmp(token, "sdrwloff") == 0) sdrwloff();
#endif

View File

@ -1,5 +1,5 @@
// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
// This file is Copyright (c) 2013-2019 Florent Kermarrec <florent@enjoy-digital.fr>
// This file is Copyright (c) 2013-2020 Florent Kermarrec <florent@enjoy-digital.fr>
// This file is Copyright (c) 2018 Chris Ballance <chris.ballance@physics.ox.ac.uk>
// This file is Copyright (c) 2018 Dolu1990 <charles.papon.90@gmail.com>
// This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
@ -114,7 +114,7 @@ void sdrrdbuf(int dq)
step = DFII_PIX_DATA_BYTES/2;
}
for(p=0;p<DFII_NPHASES;p++) {
for(p=0;p<SDRAM_PHY_PHASES;p++) {
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
buf, DFII_PIX_DATA_BYTES);
for(i=first_byte;i<DFII_PIX_DATA_BYTES;i+=step)
@ -161,8 +161,8 @@ void sdrrderr(char *count)
char *c;
int _count;
int i, j, p;
unsigned char prev_data[DFII_NPHASES][DFII_PIX_DATA_BYTES];
unsigned char errs[DFII_NPHASES][DFII_PIX_DATA_BYTES];
unsigned char prev_data[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES];
unsigned char errs[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES];
unsigned char new_data[DFII_PIX_DATA_BYTES];
if(*count == 0) {
@ -175,7 +175,7 @@ void sdrrderr(char *count)
return;
}
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
for(i=0;i<DFII_PIX_DATA_BYTES;i++)
errs[p][i] = 0;
@ -184,14 +184,14 @@ void sdrrderr(char *count)
sdram_dfii_pird_baddress_write(0);
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
cdelay(15);
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
prev_data[p], DFII_PIX_DATA_BYTES);
for(j=0;j<_count;j++) {
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
cdelay(15);
for(p=0;p<DFII_NPHASES;p++) {
for(p=0;p<SDRAM_PHY_PHASES;p++) {
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
new_data, DFII_PIX_DATA_BYTES);
for(i=0;i<DFII_PIX_DATA_BYTES;i++) {
@ -202,11 +202,11 @@ void sdrrderr(char *count)
}
}
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
for(i=0;i<DFII_PIX_DATA_BYTES;i++)
printf("%02x", errs[p][i]);
printf("\n");
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
for(i=0;i<DFII_PIX_DATA_BYTES;i++)
printf("%2x", DFII_PIX_DATA_BYTES/2 - 1 - (i % (DFII_PIX_DATA_BYTES/2)));
printf("\n");
@ -229,7 +229,7 @@ void sdrwr(char *startaddr)
return;
}
for(p=0;p<DFII_NPHASES;p++) {
for(p=0;p<SDRAM_PHY_PHASES;p++) {
for(i=0;i<DFII_PIX_DATA_BYTES;i++)
buf[i] = 0x10*p + i;
csr_wr_buf_uint8(sdram_dfii_pix_wrdata_addr[p],
@ -243,20 +243,6 @@ void sdrwr(char *startaddr)
#ifdef CSR_DDRPHY_BASE
#if defined (USDDRPHY)
#define ERR_DDRPHY_DELAY 512
#define ERR_DDRPHY_BITSLIP 8
#define NBMODULES DFII_PIX_DATA_BYTES/2
#elif defined (ECP5DDRPHY)
#define ERR_DDRPHY_DELAY 8
#define ERR_DDRPHY_BITSLIP 4
#define NBMODULES DFII_PIX_DATA_BYTES/4
#else
#define ERR_DDRPHY_DELAY 32
#define ERR_DDRPHY_BITSLIP 8
#define NBMODULES DFII_PIX_DATA_BYTES/2
#endif
#if defined(DDRPHY_CMD_DELAY) || defined(USDDRPHY_DEBUG)
void ddrphy_cdly(unsigned int delay) {
printf("Setting clk/cmd delay to %d taps\n", delay);
@ -275,8 +261,7 @@ void ddrphy_cdly(unsigned int delay) {
}
#endif
#ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
#ifdef SDRAM_PHY_WRITE_LEVELING_CAPABLE
void sdrwlon(void)
{
sdram_dfii_pi0_address_write(DDRX_MR1 | (1 << 7));
@ -294,7 +279,7 @@ void sdrwloff(void)
}
static void write_delay_rst(int module) {
#ifdef USDDRPHY
#ifdef SDRAM_PHY_WRITE_LEVELING_REINIT
int i;
#endif
@ -304,7 +289,7 @@ static void write_delay_rst(int module) {
/* rst delay */
ddrphy_wdly_dq_rst_write(1);
ddrphy_wdly_dqs_rst_write(1);
#ifdef USDDRPHY /* need to init manually on Ultrascale */
#ifdef SDRAM_PHY_WRITE_LEVELING_REINIT
for(i=0; i<ddrphy_half_sys8x_taps_read(); i++)
ddrphy_wdly_dqs_inc_write(1);
#endif
@ -331,25 +316,25 @@ int write_level(void)
int err_ddrphy_wdly;
unsigned char taps_scan[ERR_DDRPHY_DELAY];
unsigned char taps_scan[SDRAM_PHY_DELAYS];
int one_window_active;
int one_window_start, one_window_best_start;
int one_window_count, one_window_best_count;
int delays[NBMODULES];
int delays[SDRAM_PHY_MODULES];
unsigned char buf[DFII_PIX_DATA_BYTES];
int ok;
err_ddrphy_wdly = ERR_DDRPHY_DELAY - ddrphy_half_sys8x_taps_read();
err_ddrphy_wdly = SDRAM_PHY_DELAYS - ddrphy_half_sys8x_taps_read();
printf("Write leveling:\n");
sdrwlon();
cdelay(100);
for(i=0;i<NBMODULES;i++) {
for(i=0;i<SDRAM_PHY_MODULES;i++) {
printf("m%d: |", i);
/* rst delay */
@ -360,7 +345,7 @@ int write_level(void)
int zero_count = 0;
int one_count = 0;
int show = 1;
#ifdef USDDRPHY
#if SDRAM_PHY_DELAYS > 32
show = (j%16 == 0);
#endif
for (k=0; k<128; k++) {
@ -368,7 +353,7 @@ int write_level(void)
cdelay(10);
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[0],
buf, DFII_PIX_DATA_BYTES);
if (buf[NBMODULES-1-i] != 0)
if (buf[SDRAM_PHY_MODULES-1-i] != 0)
one_count++;
else
zero_count++;
@ -420,7 +405,7 @@ int write_level(void)
sdrwloff();
ok = 1;
for(i=NBMODULES-1;i>=0;i--) {
for(i=SDRAM_PHY_MODULES-1;i>=0;i--) {
if(delays[i] < 0)
ok = 0;
}
@ -428,7 +413,7 @@ int write_level(void)
return ok;
}
#endif /* CSR_DDRPHY_WLEVEL_EN_ADDR */
#endif /* SDRAM_PHY_WRITE_LEVELING_CAPABLE */
static void read_delay_rst(int module) {
/* sel module */
@ -440,7 +425,7 @@ static void read_delay_rst(int module) {
/* unsel module */
ddrphy_dly_sel_write(0);
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
/* Sync all DQSBUFM's, By toggling all dly_sel (DQSBUFM.PAUSE) lines. */
ddrphy_dly_sel_write(0xFF);
ddrphy_dly_sel_write(0);
@ -457,7 +442,7 @@ static void read_delay_inc(int module) {
/* unsel module */
ddrphy_dly_sel_write(0);
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
/* Sync all DQSBUFM's, By toggling all dly_sel (DQSBUFM.PAUSE) lines. */
ddrphy_dly_sel_write(0xFF);
ddrphy_dly_sel_write(0);
@ -492,14 +477,14 @@ static void read_bitslip_inc(char m)
static int read_level_scan(int module, int bitslip)
{
unsigned int prv;
unsigned char prs[DFII_NPHASES][DFII_PIX_DATA_BYTES];
unsigned char prs[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES];
unsigned char tst[DFII_PIX_DATA_BYTES];
int p, i;
int score;
/* Generate pseudo-random sequence */
prv = 42;
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
for(i=0;i<DFII_PIX_DATA_BYTES;i++) {
prv = 1664525*prv + 1013904223;
prs[p][i] = prv;
@ -512,7 +497,7 @@ static int read_level_scan(int module, int bitslip)
cdelay(15);
/* Write test pattern */
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
csr_wr_buf_uint8(sdram_dfii_pix_wrdata_addr[p],
prs[p], DFII_PIX_DATA_BYTES);
sdram_dfii_piwr_address_write(0);
@ -526,27 +511,27 @@ static int read_level_scan(int module, int bitslip)
printf("m%d, b%d: |", module, bitslip);
read_delay_rst(module);
for(i=0;i<ERR_DDRPHY_DELAY;i++) {
for(i=0;i<SDRAM_PHY_DELAYS;i++) {
int working = 1;
int show = 1;
#ifdef USDDRPHY
#if SDRAM_PHY_DELAYS > 32
show = (i%16 == 0);
#endif
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
ddrphy_burstdet_clr_write(1);
#endif
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
cdelay(15);
for(p=0;p<DFII_NPHASES;p++) {
for(p=0;p<SDRAM_PHY_PHASES;p++) {
/* read back test pattern */
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
tst, DFII_PIX_DATA_BYTES);
/* verify bytes matching current 'module' */
if (prs[p][ NBMODULES-1-module] != tst[ NBMODULES-1-module] ||
prs[p][2*NBMODULES-1-module] != tst[2*NBMODULES-1-module])
if (prs[p][ SDRAM_PHY_MODULES-1-module] != tst[ SDRAM_PHY_MODULES-1-module] ||
prs[p][2*SDRAM_PHY_MODULES-1-module] != tst[2*SDRAM_PHY_MODULES-1-module])
working = 0;
}
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
working = 0;
#endif
@ -569,7 +554,7 @@ static int read_level_scan(int module, int bitslip)
static void read_level(int module)
{
unsigned int prv;
unsigned char prs[DFII_NPHASES][DFII_PIX_DATA_BYTES];
unsigned char prs[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES];
unsigned char tst[DFII_PIX_DATA_BYTES];
int p, i;
int working;
@ -579,7 +564,7 @@ static void read_level(int module)
/* Generate pseudo-random sequence */
prv = 42;
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
for(i=0;i<DFII_PIX_DATA_BYTES;i++) {
prv = 1664525*prv + 1013904223;
prs[p][i] = prv;
@ -592,7 +577,7 @@ static void read_level(int module)
cdelay(15);
/* Write test pattern */
for(p=0;p<DFII_NPHASES;p++)
for(p=0;p<SDRAM_PHY_PHASES;p++)
csr_wr_buf_uint8(sdram_dfii_pix_wrdata_addr[p],
prs[p], DFII_PIX_DATA_BYTES);
sdram_dfii_piwr_address_write(0);
@ -607,36 +592,36 @@ static void read_level(int module)
delay = 0;
read_delay_rst(module);
while(1) {
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
ddrphy_burstdet_clr_write(1);
#endif
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
cdelay(15);
working = 1;
for(p=0;p<DFII_NPHASES;p++) {
for(p=0;p<SDRAM_PHY_PHASES;p++) {
/* read back test pattern */
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
tst, DFII_PIX_DATA_BYTES);
/* verify bytes matching current 'module' */
if (prs[p][ NBMODULES-1-module] != tst[ NBMODULES-1-module] ||
prs[p][2*NBMODULES-1-module] != tst[2*NBMODULES-1-module])
if (prs[p][ SDRAM_PHY_MODULES-1-module] != tst[ SDRAM_PHY_MODULES-1-module] ||
prs[p][2*SDRAM_PHY_MODULES-1-module] != tst[2*SDRAM_PHY_MODULES-1-module])
working = 0;
}
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
working = 0;
#endif
if(working)
break;
delay++;
if(delay >= ERR_DDRPHY_DELAY)
if(delay >= SDRAM_PHY_DELAYS)
break;
read_delay_inc(module);
}
delay_min = delay;
/* Get a bit further into the working zone */
#ifdef USDDRPHY
#if SDRAM_PHY_DELAYS > 32
for(i=0;i<16;i++) {
delay += 1;
read_delay_inc(module);
@ -648,35 +633,35 @@ static void read_level(int module)
/* Find largest working delay */
while(1) {
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
ddrphy_burstdet_clr_write(1);
#endif
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
cdelay(15);
working = 1;
for(p=0;p<DFII_NPHASES;p++) {
for(p=0;p<SDRAM_PHY_PHASES;p++) {
/* read back test pattern */
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
tst, DFII_PIX_DATA_BYTES);
/* verify bytes matching current 'module' */
if (prs[p][ NBMODULES-1-module] != tst[ NBMODULES-1-module] ||
prs[p][2*NBMODULES-1-module] != tst[2*NBMODULES-1-module])
if (prs[p][ SDRAM_PHY_MODULES-1-module] != tst[ SDRAM_PHY_MODULES-1-module] ||
prs[p][2*SDRAM_PHY_MODULES-1-module] != tst[2*SDRAM_PHY_MODULES-1-module])
working = 0;
}
#ifdef ECP5DDRPHY
#ifdef SDRAM_PHY_ECP5DDRPHY
if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
working = 0;
#endif
if(!working)
break;
delay++;
if(delay >= ERR_DDRPHY_DELAY)
if(delay >= SDRAM_PHY_DELAYS)
break;
read_delay_inc(module);
}
delay_max = delay;
if (delay_min >= ERR_DDRPHY_DELAY)
if (delay_min >= SDRAM_PHY_DELAYS)
printf("-");
else
printf("%02d+-%02d", (delay_min+delay_max)/2, (delay_max-delay_min)/2);
@ -919,7 +904,7 @@ int memtest(void)
#ifdef CSR_SDRAM_BASE
#ifdef CSR_DDRPHY_BASE
#if defined(SDRAM_PHY_WRITE_LEVELING_CAPABLE) || defined(SDRAM_PHY_READ_LEVELING_CAPABLE)
int sdrlevel(void)
{
int module;
@ -930,25 +915,26 @@ int sdrlevel(void)
sdrsw();
for(module=0; module<NBMODULES; module++) {
#ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
for(module=0; module<SDRAM_PHY_MODULES; module++) {
#ifdef SDRAM_PHY_WRITE_LEVELING_CAPABLE
write_delay_rst(module);
#endif
read_delay_rst(module);
read_bitslip_rst(module);
}
#ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
#ifdef SDRAM_PHY_WRITE_LEVELING_CAPABLE
if(!write_level())
return 0;
#endif
#ifdef SDRAM_PHY_READ_LEVELING_CAPABLE
printf("Read leveling:\n");
for(module=0; module<NBMODULES; module++) {
for(module=0; module<SDRAM_PHY_MODULES; module++) {
/* scan possible read windows */
best_score = 0;
best_bitslip = 0;
for(bitslip=0; bitslip<ERR_DDRPHY_BITSLIP; bitslip++) {
for(bitslip=0; bitslip<SDRAM_PHY_BITSLIPS; bitslip++) {
/* compute score */
score = read_level_scan(module, bitslip);
read_level(module);
@ -958,7 +944,7 @@ int sdrlevel(void)
best_score = score;
}
/* exit */
if (bitslip == ERR_DDRPHY_BITSLIP-1)
if (bitslip == SDRAM_PHY_BITSLIPS-1)
break;
/* increment bitslip */
read_bitslip_inc(module);
@ -974,6 +960,7 @@ int sdrlevel(void)
read_level(module);
printf("\n");
}
#endif
return 1;
@ -997,7 +984,9 @@ int sdrinit(void)
#ifdef DDRPHY_CMD_DELAY
ddrphy_cdly(DDRPHY_CMD_DELAY);
#endif
#if defined(SDRAM_PHY_WRITE_LEVELING_CAPABLE) || defined(SDRAM_PHY_READ_LEVELING_CAPABLE)
sdrlevel();
#endif
#if CSR_DDRPHY_EN_VTC_ADDR
ddrphy_en_vtc_write(1);
#endif
@ -1067,8 +1056,8 @@ void sdrmpr(void)
printf("Read SDRAM MPR...\n");
/* rst phy */
for(module=0; module<NBMODULES; module++) {
#ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
for(module=0; module<SDRAM_PHY_MODULES; module++) {
#ifdef SDRAM_PHY_WRITE_LEVELING_CAPABLE
write_delay_rst(module);
#endif
read_delay_rst(module);
@ -1082,13 +1071,13 @@ void sdrmpr(void)
sdrmpron(MPR0_SEL);
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
cdelay(15);
for (module=0; module < NBMODULES; module++) {
for (module=0; module < SDRAM_PHY_MODULES; module++) {
printf("m%d: ", module);
for(phase=0; phase<DFII_NPHASES; phase++) {
for(phase=0; phase<SDRAM_PHY_PHASES; phase++) {
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[phase],
buf, DFII_PIX_DATA_BYTES);
printf("%d", buf[ NBMODULES-module-1] & 0x1);
printf("%d", buf[2*NBMODULES-module-1] & 0x1);
printf("%d", buf[ SDRAM_PHY_MODULES-module-1] & 0x1);
printf("%d", buf[2*SDRAM_PHY_MODULES-module-1] & 0x1);
}
printf("\n");
}
@ -1100,5 +1089,4 @@ void sdrmpr(void)
#endif
#endif

View File

@ -11,17 +11,11 @@ void sdrrd(char *startaddr, char *dq);
void sdrrderr(char *count);
void sdrwr(char *startaddr);
#ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
void sdrwlon(void);
void sdrwloff(void);
int write_level(void);
#endif
#ifdef CSR_DDRPHY_BASE
void sdrwlon(void);
void sdrwloff(void);
int sdrlevel(void);
#endif
int memtest_silent(void);
int memtest(void);