From 838434cdeced7ca5c78b9bd49ac40244947bffe3 Mon Sep 17 00:00:00 2001 From: Astro Date: Fri, 25 Oct 2019 19:09:54 +0200 Subject: [PATCH] zynq::ddr: wait for init --- src/zynq/ddr/mod.rs | 23 ++++++++++++++++------- src/zynq/ddr/regs.rs | 22 +++++++++++++++++++++- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/zynq/ddr/mod.rs b/src/zynq/ddr/mod.rs index 6cc4b0fc..57237fae 100644 --- a/src/zynq/ddr/mod.rs +++ b/src/zynq/ddr/mod.rs @@ -8,7 +8,9 @@ mod regs; const DDR_FREQ: u32 = 666_666_666; const DCI_FREQ: u32 = 10_000_000; -pub struct DdrRam; +pub struct DdrRam { + regs: &'static mut regs::RegisterBlock, +} impl DdrRam { pub fn new() -> Self { @@ -16,9 +18,11 @@ impl DdrRam { Self::clock_setup(&clocks); Self::calibrate_iob_impedance(&clocks); Self::configure_iob(); - Self::reset_ddrc(); - DdrRam + let regs = unsafe { regs::RegisterBlock::new() }; + let mut ddr = DdrRam { regs }; + ddr.reset_ddrc(); + ddr } /// Zynq-7000 AP SoC Technical Reference Manual: @@ -133,15 +137,20 @@ impl DdrRam { } /// Reset DDR controller - fn reset_ddrc() { - let regs = unsafe { regs::RegisterBlock::new() }; - regs.ddrc_ctrl.modify(|_, w| w + fn reset_ddrc(&mut self) { + self.regs.ddrc_ctrl.modify(|_, w| w .soft_rstb(false) ); - regs.ddrc_ctrl.modify(|_, w| w + self.regs.ddrc_ctrl.modify(|_, w| w .soft_rstb(true) .powerdown_en(false) .data_bus_width(regs::DataBusWidth::Width32bit) ); + + while self.status() == regs::ControllerStatus::Init {} + } + + pub fn status(&self) -> regs::ControllerStatus { + self.regs.mode_sts_reg.read().operating_mode() } } diff --git a/src/zynq/ddr/regs.rs b/src/zynq/ddr/regs.rs index 753af76d..6dfbaa62 100644 --- a/src/zynq/ddr/regs.rs +++ b/src/zynq/ddr/regs.rs @@ -8,6 +8,21 @@ pub enum DataBusWidth { Width16bit = 0b01, } +#[derive(Debug, Clone, PartialEq)] +#[repr(u8)] +pub enum ControllerStatus { + Init = 0, + Normal = 1, + Powerdown = 2, + SelfRefresh = 3, + Powerdown1 = 4, + Powerdown2 = 5, + Powerdown3 = 6, + Powerdown4 = 7, +} + + + #[repr(C)] pub struct RegisterBlock { pub ddrc_ctrl: DdrcCtrl, @@ -31,7 +46,7 @@ pub struct RegisterBlock { pub dram_odt_reg: RW, pub phy_dbg_reg: RW, pub phy_cmd_timeout_rddata_cpt: RW, - pub mode_sts_reg: RW, + pub mode_sts_reg: ModeStsReg, pub dll_calib: RW, pub odt_delay_hold: RW, pub ctrl_reg1: RW, @@ -154,3 +169,8 @@ register_bit!(ddrc_ctrl, register_bit!(ddrc_ctrl, powerdown_en, 1); register_bits_typed!(ddrc_ctrl, data_bus_width, u8, DataBusWidth, 2, 3); // (ddrc_ctrl) ... + +/// Controller operation mode status +register!(mode_sts_reg, ModeStsReg, RO, u32); +register_bits_typed!(mode_sts_reg, operating_mode, u8, ControllerStatus, 0, 2); +// (mode_sts_reg) ...