forked from M-Labs/zynq-rs
ddr: improve dci divisors calculation
This commit is contained in:
parent
0aa75d3544
commit
ef4fb598fb
|
@ -56,14 +56,35 @@ impl DdrRam {
|
|||
clocks
|
||||
}
|
||||
|
||||
fn calculate_dci_divisors(clocks: &Clocks) -> (u8, u8) {
|
||||
let target = (DCI_FREQ - 1 + clocks.ddr) / DCI_FREQ;
|
||||
|
||||
let mut best = None;
|
||||
let mut best_error = 0;
|
||||
for divisor0 in 1..63 {
|
||||
for divisor1 in 1..63 {
|
||||
let current = (divisor0 as u32) * (divisor1 as u32);
|
||||
let error = if current > target {
|
||||
current - target
|
||||
} else {
|
||||
target - current
|
||||
};
|
||||
if best.is_none() || best_error > error {
|
||||
best = Some((divisor0, divisor1));
|
||||
best_error = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
best.unwrap()
|
||||
}
|
||||
|
||||
/// Zynq-7000 AP SoC Technical Reference Manual:
|
||||
/// 10.6.2 DDR IOB Impedance Calibration
|
||||
fn calibrate_iob_impedance(clocks: &Clocks) {
|
||||
let divisor0 = ((DCI_FREQ - 1 + clocks.ddr) / DCI_FREQ)
|
||||
.max(1).min(63) as u8;
|
||||
let divisor1 = ((DCI_FREQ - 1 + clocks.ddr) / DCI_FREQ / u32::from(divisor0))
|
||||
.max(1).min(63) as u8;
|
||||
debug!("DDR DCI clock: {} Hz", clocks.ddr / u32::from(divisor0) / u32::from(divisor1));
|
||||
let (divisor0, divisor1) = Self::calculate_dci_divisors(clocks);
|
||||
debug!("DDR DCI clock: {} Hz (divisors={}*{})",
|
||||
clocks.ddr / u32::from(divisor0) / u32::from(divisor1),
|
||||
divisor0, divisor1);
|
||||
|
||||
slcr::RegisterBlock::unlocked(|slcr| {
|
||||
// Step 1.
|
||||
|
|
Loading…
Reference in New Issue