bios/sdram: check for optimal read window before doing read leveling, increment bitslip if not optimal.
This commit is contained in:
parent
9e737d3c57
commit
477d224921
|
@ -336,6 +336,19 @@ static int write_level(int *delay, int *high_skew)
|
||||||
|
|
||||||
#endif /* CSR_DDRPHY_WLEVEL_EN_ADDR */
|
#endif /* CSR_DDRPHY_WLEVEL_EN_ADDR */
|
||||||
|
|
||||||
|
static void read_bitslip_inc(char m)
|
||||||
|
{
|
||||||
|
ddrphy_dly_sel_write(1 << m);
|
||||||
|
#ifdef KUSDDRPHY
|
||||||
|
ddrphy_rdly_dq_bitslip_write(1);
|
||||||
|
#else
|
||||||
|
/* 7-series SERDES in DDR mode needs 3 pulses for 1 bitslip */
|
||||||
|
ddrphy_rdly_dq_bitslip_write(1);
|
||||||
|
ddrphy_rdly_dq_bitslip_write(1);
|
||||||
|
ddrphy_rdly_dq_bitslip_write(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void read_bitslip(int *delay, int *high_skew)
|
static void read_bitslip(int *delay, int *high_skew)
|
||||||
{
|
{
|
||||||
int bitslip_thr;
|
int bitslip_thr;
|
||||||
|
@ -352,27 +365,21 @@ static void read_bitslip(int *delay, int *high_skew)
|
||||||
printf("Read bitslip: ");
|
printf("Read bitslip: ");
|
||||||
for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--)
|
for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--)
|
||||||
if(delay[i] > bitslip_thr) {
|
if(delay[i] > bitslip_thr) {
|
||||||
ddrphy_dly_sel_write(1 << i);
|
read_bitslip_inc(i);
|
||||||
#ifdef KUSDDRPHY
|
|
||||||
ddrphy_rdly_dq_bitslip_write(1);
|
|
||||||
#else
|
|
||||||
/* 7-series SERDES in DDR mode needs 3 pulses for 1 bitslip */
|
|
||||||
ddrphy_rdly_dq_bitslip_write(1);
|
|
||||||
ddrphy_rdly_dq_bitslip_write(1);
|
|
||||||
ddrphy_rdly_dq_bitslip_write(1);
|
|
||||||
#endif
|
|
||||||
printf("%d ", i);
|
printf("%d ", i);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_delays_scan(void)
|
static int read_level_scan(int silent)
|
||||||
{
|
{
|
||||||
unsigned int prv;
|
unsigned int prv;
|
||||||
unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
|
unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
|
||||||
int p, i, j;
|
int p, i, j;
|
||||||
int working;
|
int working;
|
||||||
|
int optimal;
|
||||||
|
|
||||||
|
if (!silent)
|
||||||
printf("Read delays scan:\n");
|
printf("Read delays scan:\n");
|
||||||
|
|
||||||
/* Generate pseudo-random sequence */
|
/* Generate pseudo-random sequence */
|
||||||
|
@ -399,7 +406,9 @@ static void read_delays_scan(void)
|
||||||
/* Calibrate each DQ in turn */
|
/* Calibrate each DQ in turn */
|
||||||
sdram_dfii_pird_address_write(0);
|
sdram_dfii_pird_address_write(0);
|
||||||
sdram_dfii_pird_baddress_write(0);
|
sdram_dfii_pird_baddress_write(0);
|
||||||
|
optimal = 1;
|
||||||
for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--) {
|
for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--) {
|
||||||
|
if (!silent)
|
||||||
printf("m%d: ", (DFII_PIX_DATA_SIZE/2-i-1));
|
printf("m%d: ", (DFII_PIX_DATA_SIZE/2-i-1));
|
||||||
ddrphy_dly_sel_write(1 << (DFII_PIX_DATA_SIZE/2-i-1));
|
ddrphy_dly_sel_write(1 << (DFII_PIX_DATA_SIZE/2-i-1));
|
||||||
ddrphy_rdly_dq_rst_write(1);
|
ddrphy_rdly_dq_rst_write(1);
|
||||||
|
@ -413,9 +422,14 @@ static void read_delays_scan(void)
|
||||||
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2])
|
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2])
|
||||||
working = 0;
|
working = 0;
|
||||||
}
|
}
|
||||||
|
if (j == 0)
|
||||||
|
/* to have an optimal scan, first tap should not be working */
|
||||||
|
optimal &= (working == 0);
|
||||||
|
if (!silent)
|
||||||
printf("%d", working);
|
printf("%d", working);
|
||||||
ddrphy_rdly_dq_inc_write(1);
|
ddrphy_rdly_dq_inc_write(1);
|
||||||
}
|
}
|
||||||
|
if (!silent)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,9 +438,11 @@ static void read_delays_scan(void)
|
||||||
sdram_dfii_pi0_baddress_write(0);
|
sdram_dfii_pi0_baddress_write(0);
|
||||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
||||||
cdelay(15);
|
cdelay(15);
|
||||||
|
|
||||||
|
return optimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_delays(void)
|
static void read_level(void)
|
||||||
{
|
{
|
||||||
unsigned int prv;
|
unsigned int prv;
|
||||||
unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
|
unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
|
||||||
|
@ -732,6 +748,7 @@ int sdrlevel(void) /* automatic */
|
||||||
{
|
{
|
||||||
int delay[DFII_PIX_DATA_SIZE/2];
|
int delay[DFII_PIX_DATA_SIZE/2];
|
||||||
int high_skew[DFII_PIX_DATA_SIZE/2];
|
int high_skew[DFII_PIX_DATA_SIZE/2];
|
||||||
|
int i;
|
||||||
|
|
||||||
#ifndef CSR_DDRPHY_WLEVEL_EN_ADDR
|
#ifndef CSR_DDRPHY_WLEVEL_EN_ADDR
|
||||||
int i;
|
int i;
|
||||||
|
@ -744,9 +761,18 @@ int sdrlevel(void) /* automatic */
|
||||||
if(!write_level(delay, high_skew))
|
if(!write_level(delay, high_skew))
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
read_bitslip(delay, high_skew);
|
/* check for optimal read leveling window */
|
||||||
read_delays_scan();
|
if (read_level_scan(1)) {
|
||||||
read_delays();
|
/* if optimal, show scan */
|
||||||
|
read_level_scan(0);
|
||||||
|
} else {
|
||||||
|
/* else increment bitslip and re-scan */
|
||||||
|
printf("Read bitslip for optimal window\n");
|
||||||
|
for(i=0; i<DFII_PIX_DATA_SIZE/2; i++)
|
||||||
|
read_bitslip_inc(i);
|
||||||
|
read_level_scan(0);
|
||||||
|
}
|
||||||
|
read_level();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue