forked from M-Labs/artiq
sdram: simplify read level scan
This commit is contained in:
parent
845784c180
commit
4b3f408143
|
@ -95,7 +95,7 @@ mod ddr {
|
||||||
#[cfg(kusddrphy)] {
|
#[cfg(kusddrphy)] {
|
||||||
ddrphy_max_delay -= ddrphy::wdly_dqs_taps_read();
|
ddrphy_max_delay -= ddrphy::wdly_dqs_taps_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
for n in 0..DQS_SIGNAL_COUNT {
|
for n in 0..DQS_SIGNAL_COUNT {
|
||||||
let dq_addr = dfii::PI0_RDDATA_ADDR
|
let dq_addr = dfii::PI0_RDDATA_ADDR
|
||||||
|
@ -316,50 +316,50 @@ mod ddr {
|
||||||
for n in 0..DQS_SIGNAL_COUNT {
|
for n in 0..DQS_SIGNAL_COUNT {
|
||||||
ddrphy::dly_sel_write(1 << (DQS_SIGNAL_COUNT - n - 1));
|
ddrphy::dly_sel_write(1 << (DQS_SIGNAL_COUNT - n - 1));
|
||||||
|
|
||||||
let find_edge = |which| {
|
// Find the first (which=true) or last (which=false) tap that leads to a
|
||||||
// Find the first (which=true) or last (which=false) tap that leads to a
|
// sufficiently high number of correct reads.
|
||||||
// sufficiently high number of correct reads.
|
let mut min_delay = 0;
|
||||||
let mut last_valid = 0;
|
let mut have_min_delay = false;
|
||||||
ddrphy::rdly_dq_rst_write(1);
|
let mut max_delay = 0;
|
||||||
for delay in 0..DDRPHY_MAX_DELAY {
|
|
||||||
let mut valid = true;
|
|
||||||
for _ in 0..256 {
|
|
||||||
sdram_phy::command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|
|
|
||||||
DFII_COMMAND_RDDATA);
|
|
||||||
spin_cycles(15);
|
|
||||||
|
|
||||||
for p in 0..DFII_NPHASES {
|
ddrphy::rdly_dq_rst_write(1);
|
||||||
for &offset in [n, n + DQS_SIGNAL_COUNT].iter() {
|
|
||||||
let addr = DFII_PIX_RDDATA_ADDR[p].offset(offset as isize);
|
for delay in 0..DDRPHY_MAX_DELAY {
|
||||||
let data = prs[DFII_PIX_DATA_SIZE * p + offset];
|
let mut valid = true;
|
||||||
if ptr::read_volatile(addr) as u8 != data {
|
for _ in 0..256 {
|
||||||
valid = false;
|
sdram_phy::command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|
|
||||||
}
|
DFII_COMMAND_RDDATA);
|
||||||
|
spin_cycles(15);
|
||||||
|
|
||||||
|
for p in 0..DFII_NPHASES {
|
||||||
|
for &offset in [n, n + DQS_SIGNAL_COUNT].iter() {
|
||||||
|
let addr = DFII_PIX_RDDATA_ADDR[p].offset(offset as isize);
|
||||||
|
let data = prs[DFII_PIX_DATA_SIZE * p + offset];
|
||||||
|
if ptr::read_volatile(addr) as u8 != data {
|
||||||
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid {
|
|
||||||
last_valid = delay;
|
|
||||||
if which {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ddrphy::rdly_dq_inc_write(1);
|
|
||||||
}
|
}
|
||||||
last_valid
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find smallest working delay
|
if valid {
|
||||||
let min_delay = find_edge(true);
|
if !have_min_delay {
|
||||||
let max_delay = find_edge(false);
|
min_delay = delay;
|
||||||
|
have_min_delay = true;
|
||||||
|
}
|
||||||
|
max_delay = delay;
|
||||||
|
}
|
||||||
|
ddrphy::rdly_dq_inc_write(1);
|
||||||
|
}
|
||||||
|
|
||||||
log!(logger, "{}:{:02}-{:02} ", DQS_SIGNAL_COUNT - n - 1,
|
let mean_delay = (min_delay + max_delay) / 2;
|
||||||
min_delay, max_delay);
|
log!(logger, "{}: {} ({} wide), ",
|
||||||
|
DQS_SIGNAL_COUNT - n - 1, mean_delay,
|
||||||
|
max_delay - min_delay);
|
||||||
|
|
||||||
// Set delay to the middle
|
// Set delay to the middle
|
||||||
ddrphy::rdly_dq_rst_write(1);
|
ddrphy::rdly_dq_rst_write(1);
|
||||||
for _ in 0..(min_delay + max_delay) / 2 {
|
for _ in 0..mean_delay {
|
||||||
ddrphy::rdly_dq_inc_write(1);
|
ddrphy::rdly_dq_inc_write(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue