zynq::ddr, main: parameters, memtest
This commit is contained in:
parent
e61d1268ac
commit
9b4f07f37c
|
@ -87,6 +87,9 @@ const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
|
|||
fn main() {
|
||||
println!("Main.");
|
||||
|
||||
zynq::clocks::CpuClocks::enable_ddr(1_066_000_000);
|
||||
let pll_status = zynq::slcr::RegisterBlock::new().pll_status.read();
|
||||
println!("PLLs: {}", pll_status);
|
||||
let clocks = zynq::clocks::CpuClocks::get();
|
||||
println!("Clocks: {:?}", clocks);
|
||||
println!("CPU speeds: {}/{}/{}/{} MHz",
|
||||
|
@ -94,7 +97,9 @@ fn main() {
|
|||
clocks.cpu_3x2x() / 1_000_000,
|
||||
clocks.cpu_2x() / 1_000_000,
|
||||
clocks.cpu_1x() / 1_000_000);
|
||||
let ddr = zynq::ddr::DdrRam::new();
|
||||
let mut ddr = zynq::ddr::DdrRam::new();
|
||||
println!("DDR: {:?}", ddr.status());
|
||||
ddr.memtest();
|
||||
|
||||
let eth = zynq::eth::Eth::default(HWADDR.clone());
|
||||
println!("Eth on");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::regs::{RegisterR, RegisterRW};
|
||||
use crate::regs::{RegisterR, RegisterW, RegisterRW};
|
||||
use super::slcr;
|
||||
|
||||
#[cfg(feature = "target_zc706")]
|
||||
|
@ -90,19 +90,33 @@ impl CpuClocks {
|
|||
pll / u32::from(uart_clk_ctrl.divisor())
|
||||
}
|
||||
|
||||
/// Zynq-7000 AP SoC Technical Reference Manual:
|
||||
/// 25.10.4 PLLs
|
||||
pub fn enable_ddr(target_clock: u32) {
|
||||
let fdiv = (target_clock / PS_CLK).min(66) as u16;
|
||||
let regs = slcr::RegisterBlock::new();
|
||||
regs.ddr_pll_ctrl.modify(|_, w| w
|
||||
.pll_pwrdwn(false)
|
||||
.pll_reset(true)
|
||||
.pll_bypass_force(true)
|
||||
);
|
||||
let fdiv = (target_clock / PS_CLK).max(127) as u16;
|
||||
regs.ddr_pll_ctrl.modify(|_, w| w
|
||||
.pll_pwrdwn(false)
|
||||
.pll_reset(false)
|
||||
.pll_fdiv(fdiv)
|
||||
);
|
||||
let (pll_res, pll_cp, lock_cnt) = PLL_FDIV_LOCK_PARAM.iter()
|
||||
.filter(|(fdiv_max, _)| fdiv <= *fdiv_max)
|
||||
.last()
|
||||
.expect("PLL_FDIV_LOCK_PARAM")
|
||||
.1.clone();
|
||||
regs.ddr_pll_cfg.write(
|
||||
slcr::PllCfg::zeroed()
|
||||
.pll_res(pll_res)
|
||||
.pll_cp(pll_cp)
|
||||
.lock_cnt(lock_cnt)
|
||||
);
|
||||
regs.ddr_pll_ctrl.modify(|_, w| w
|
||||
.pll_reset(true)
|
||||
);
|
||||
regs.ddr_pll_ctrl.modify(|_, w| w
|
||||
.pll_reset(false)
|
||||
);
|
||||
while ! regs.pll_status.read().ddr_pll_lock() {}
|
||||
regs.ddr_pll_ctrl.modify(|_, w| w
|
||||
.pll_bypass_force(false)
|
||||
|
@ -110,3 +124,27 @@ impl CpuClocks {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// (pll_fdiv_max, (pll_cp, pll_res, lock_cnt))
|
||||
const PLL_FDIV_LOCK_PARAM: &[(u16, (u8, u8, u16))] = &[
|
||||
(13, (2, 6, 750)),
|
||||
(14, (2, 6, 700)),
|
||||
(15, (2, 6, 650)),
|
||||
(16, (2, 10, 625)),
|
||||
(17, (2, 10, 575)),
|
||||
(18, (2, 10, 550)),
|
||||
(19, (2, 10, 525)),
|
||||
(20, (2, 12, 500)),
|
||||
(21, (2, 12, 475)),
|
||||
(22, (2, 12, 450)),
|
||||
(23, (2, 12, 425)),
|
||||
(25, (2, 12, 400)),
|
||||
(26, (2, 12, 375)),
|
||||
(28, (2, 12, 350)),
|
||||
(30, (2, 12, 325)),
|
||||
(33, (2, 2, 300)),
|
||||
(36, (2, 2, 275)),
|
||||
(40, (2, 2, 250)),
|
||||
(47, (3, 12, 250)),
|
||||
(66, (2, 4, 250)),
|
||||
];
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
use crate::regs::{RegisterR, RegisterW, RegisterRW};
|
||||
use crate::println;
|
||||
use super::slcr;
|
||||
use super::clocks::CpuClocks;
|
||||
|
||||
mod regs;
|
||||
|
||||
#[cfg(feature = "target_zc706")]
|
||||
/// Micron MT41J256M8HX-15E: 667 MHz DDR3
|
||||
const DDR_FREQ: u32 = 666_666_666;
|
||||
|
||||
#[cfg(feature = "target_cora_z7_10")]
|
||||
/// Micron MT41K256M16HA-125: 800 MHz DDR3L
|
||||
const DDR_FREQ: u32 = 800_000_000;
|
||||
|
||||
/// MT41K256M16HA-125
|
||||
const DCI_FREQ: u32 = 10_000_000;
|
||||
|
||||
pub struct DdrRam {
|
||||
|
@ -131,12 +139,24 @@ impl DdrRam {
|
|||
slcr.ddriob_drive_slew_clock.write(0x00F9861C);
|
||||
}
|
||||
|
||||
// Enable internal V[REF]
|
||||
#[cfg(feature = "target_zc706")]
|
||||
let vref_sel = slcr::DdriobVrefSel::Vref0_75V;
|
||||
#[cfg(feature = "target_cora_z7_10")]
|
||||
let vref_sel = slcr::DdriobVrefSel::Vref0_675V;
|
||||
|
||||
// // Enable internal V[REF]
|
||||
// slcr.ddriob_ddr_ctrl.modify(|_, w| w
|
||||
// .vref_ext_en_lower(false)
|
||||
// .vref_ext_en_upper(false)
|
||||
// .vref_sel(vref_sel)
|
||||
// .vref_int_en(true)
|
||||
// );
|
||||
// Enable external V[REF]
|
||||
slcr.ddriob_ddr_ctrl.modify(|_, w| w
|
||||
.vref_ext_en_lower(false)
|
||||
.vref_ext_en_upper(false)
|
||||
.vref_sel(slcr::DdriobVrefSel::Vref0_75V)
|
||||
.vref_int_en(true)
|
||||
.vref_ext_en_lower(true)
|
||||
.vref_ext_en_upper(true)
|
||||
.vref_sel(vref_sel)
|
||||
.vref_int_en(false)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -158,4 +178,47 @@ impl DdrRam {
|
|||
pub fn status(&self) -> regs::ControllerStatus {
|
||||
self.regs.mode_sts_reg.read().operating_mode()
|
||||
}
|
||||
|
||||
// TODO: move into trait
|
||||
pub fn ptr(&mut self) -> *mut u8 {
|
||||
// 0x0010_0000 as *mut _
|
||||
0x0020_0000 as *mut _
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
// #[cfg(feature = "target_zc706")]
|
||||
// 1024 * 1024 * 1024
|
||||
4 * 1024 * 1024
|
||||
}
|
||||
|
||||
pub fn memtest(&mut self) {
|
||||
let slice = unsafe {
|
||||
core::slice::from_raw_parts_mut(self.ptr(), self.size())
|
||||
};
|
||||
let patterns: &'static [u8] = &[0, 0xff, 0x55, 0xaa, 0];
|
||||
let mut expected = None;
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
println!("memtest phase {} (status: {:?})", i, self.status());
|
||||
|
||||
let slice_len = slice.len();
|
||||
let mut progress = 0;
|
||||
for (j, b) in slice.iter_mut().enumerate() {
|
||||
expected.map(|expected| {
|
||||
let read: u8 = *b;
|
||||
if read != expected {
|
||||
println!("{:08X}: expected {:02X}, read {:02X}", b as *mut u8 as usize, expected, read);
|
||||
}
|
||||
});
|
||||
*b = *pattern;
|
||||
// println!("{:08X}", b as *mut u8 as usize);
|
||||
let new_progress = 100 * j / slice_len;
|
||||
if new_progress > progress {
|
||||
progress = new_progress;
|
||||
println!("{}%", progress);
|
||||
}
|
||||
}
|
||||
|
||||
expected = Some(*pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue