From 6be08c439bbaf2f0e34fce3e3d7b16acfee8c893 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Jul 2025 10:17:36 +0200 Subject: [PATCH] wow, DDR init is complex --- fsbl/src/main.rs | 8 ++- zynq7000-hal/src/ddr.rs | 0 zynq7000/src/ddrc.rs | 118 ++++++++++++++++++++++++++++++++++++++++ zynq7000/src/lib.rs | 1 + 4 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 zynq7000-hal/src/ddr.rs create mode 100644 zynq7000/src/ddrc.rs diff --git a/fsbl/src/main.rs b/fsbl/src/main.rs index 2c75d89..39f5d64 100644 --- a/fsbl/src/main.rs +++ b/fsbl/src/main.rs @@ -21,10 +21,13 @@ const PS_CLK: Hertz = Hertz::from_raw(33_333_333); /// 1600 MHz. const ARM_CLK: Hertz = Hertz::from_raw(1_600_000_000); /// 1067 MHz. -const DDR_CLK: Hertz = Hertz::from_raw(1_067_000_000); +//const DDR_CLK: Hertz = Hertz::from_raw(1_067_000_000); /// 1000 MHz. const IO_CLK: Hertz = Hertz::from_raw(1_000_000_000); +/// DDR frequency for the MT41K128M16JT-125 device. +const DDR_FREQUENCY: Hertz = Hertz::from_raw(533_333_333); + /// Entry point (not called like a normal main function) #[unsafe(no_mangle)] pub extern "C" fn boot_core(cpu_id: u32) -> ! { @@ -41,7 +44,8 @@ pub fn main() -> ! { // by other Xilinx tools. configure_arm_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, ARM_CLK).unwrap()); configure_io_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, IO_CLK).unwrap()); - configure_ddr_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, DDR_CLK).unwrap()); + + configure_ddr_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, 2 * DDR_FREQUENCY).unwrap()); loop { cortex_ar::asm::nop(); diff --git a/zynq7000-hal/src/ddr.rs b/zynq7000-hal/src/ddr.rs new file mode 100644 index 0000000..e69de29 diff --git a/zynq7000/src/ddrc.rs b/zynq7000/src/ddrc.rs new file mode 100644 index 0000000..b0c6272 --- /dev/null +++ b/zynq7000/src/ddrc.rs @@ -0,0 +1,118 @@ +#[derive(derive_mmio::Mmio)] +#[repr(C)] +pub struct DdrController { + ddrc_ctrl: u32, + two_rank_cfg: u32, + hpr_reg: u32, + lpr_reg: u32, + wr_reg: u32, + dram_param_reg0: u32, + dram_param_reg1: u32, + dram_param_reg2: u32, + dram_param_reg3: u32, + dram_param_reg4: u32, + dram_init_param: u32, + dram_emr_reg: u32, + dram_emr_mr_reg: u32, + dram_burst8_rdwr: u32, + dram_disable_dq: u32, + dram_addr_map_bank: u32, + dram_addr_map_col: u32, + dram_addr_map_row: u32, + dram_odt_reg: u32, + phy_debug_reg: u32, + phy_cmd_timeout_rddata_cpt: u32, + mode_status_reg: u32, + dll_calib: u32, + odt_delay_hold: u32, + ctrl_reg1: u32, + ctrl_reg2: u32, + ctrl_reg3: u32, + ctrl_reg4: u32, + ctrl_reg5: u32, + ctrl_reg6: u32, + che_refresh_timer_01: u32, + che_t_zq: u32, + che_t_zq_short_interval_reg: u32, + deep_powerdown_reg: u32, + reg_2c: u32, + reg_2d: u32, + dfi_timing: u32, + che_corr_control: u32, + che_corr_ecc_addr: u32, + che_corr_ecc_data_31_0: u32, + che_corr_ecc_data_63_32: u32, + che_corr_ecc_data_71_64: u32, + che_uncorr_ecc_log: u32, + che_uncorr_ecc_addr: u32, + che_uncorr_ecc_data_31_0: u32, + che_uncorr_ecc_data_63_32: u32, + che_uncorr_ecc_data_71_64: u32, + che_ecc_stats_reg: u32, + ecc_scrub: u32, + che_ecc_corr_bit_mask_31_0: u32, + che_ecc_corr_bit_mask_63_32: u32, + phy_receiver_enable: u32, + phy_config_0: u32, + phy_config_1: u32, + phy_config_2: u32, + phy_config_3: u32, + phy_init_ratio_0: u32, + phy_init_ratio_1: u32, + phy_init_ratio_2: u32, + phy_init_ratio_3: u32, + phy_rd_dqs_cfg_0: u32, + phy_rd_dqs_cfg_1: u32, + phy_rd_dqs_cfg_2: u32, + phy_rd_dqs_cfg_3: u32, + phy_wr_dqs_cfg_0: u32, + phy_wr_dqs_cfg_1: u32, + phy_wr_dqs_cfg_2: u32, + phy_wr_dqs_cfg_3: u32, + phy_we_cfg_1: u32, + phy_we_cfg_2: u32, + phy_we_cfg_3: u32, + wr_data_slave_0: u32, + wr_data_slave_1: u32, + wr_data_slave_2: u32, + wr_data_slave_3: u32, + reg_64: u32, + reg_65: u32, + reg69_6a0: u32, + reg69_6a1: u32, + reg69_6d2: u32, + reg69_6d3: u32, + reg69_710: u32, + reg6e_711: u32, + reg6e_712: u32, + reg6e_713: u32, + phy_dll_status_0: u32, + phy_dll_status_1: u32, + phy_dll_status_2: u32, + phy_dll_status_3: u32, + dll_lock_status: u32, + phy_control_status: u32, + phy_control_status_2: u32, + axi_id: u32, + page_mask: u32, + axi_priority_wr_port_0: u32, + axi_priority_wr_port_1: u32, + axi_priority_wr_port_2: u32, + axi_priority_wr_port_3: u32, + axi_priority_rd_port_0: u32, + axi_priority_rd_port_1: u32, + axi_priority_rd_port_2: u32, + axi_priority_rd_port_3: u32, + excl_access_cfg_0: u32, + excl_access_cfg_1: u32, + excl_access_cfg_2: u32, + excl_access_cfg_3: u32, + mode_reg_read: u32, + lpddr_ctrl_0: u32, + lpddr_ctrl_1: u32, + lpddr_ctrl_2: u32, + lpddr_ctrl_3: u32, +} + + +static_assertions::const_assert_eq!(core::mem::size_of::(), 0x2B8); diff --git a/zynq7000/src/lib.rs b/zynq7000/src/lib.rs index a9df228..fd58efd 100644 --- a/zynq7000/src/lib.rs +++ b/zynq7000/src/lib.rs @@ -28,6 +28,7 @@ pub mod slcr; pub mod spi; pub mod ttc; pub mod uart; +pub mod ddrc; static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);