From 9d725bcf0f7587fa26665697b391aa9a344a81f0 Mon Sep 17 00:00:00 2001 From: Astro Date: Mon, 21 Oct 2019 22:12:10 +0200 Subject: [PATCH] zynq::ddr: init with clock setup --- src/zynq/ddr/mod.rs | 39 ++++++++++++ src/zynq/ddr/regs.rs | 137 +++++++++++++++++++++++++++++++++++++++++++ src/zynq/mod.rs | 1 + 3 files changed, 177 insertions(+) create mode 100644 src/zynq/ddr/mod.rs create mode 100644 src/zynq/ddr/regs.rs diff --git a/src/zynq/ddr/mod.rs b/src/zynq/ddr/mod.rs new file mode 100644 index 00000000..1d99ceca --- /dev/null +++ b/src/zynq/ddr/mod.rs @@ -0,0 +1,39 @@ +use crate::regs::RegisterW; +use crate::slcr; +use crate::clocks::CpuClocks; + +/// Micron MT41J256M8HX-15E: 667 MHz +const DDR_FREQ: u32 = 666_666_666; + +pub struct DdrRam { +} + +impl DdrRam { + pub fn new() -> Self { + Self::clock_setup(); + + let ram = DdrRam {}; + // TODO: ram. + ram + } + + fn clock_setup() { + let clocks = CpuClocks::get(); + let ddr3x_clk_divisor = ((clocks.ddr - 1) / DDR_FREQ + 1).min(255) as u8; + let ddr2x_clk_divisor = 3 * ddr3x_clk_divisor / 2; + + slcr::RegisterBlock::unlocked(|slcr| { + slcr.ddr_pll_ctrl.write( + slcr::PllCtrl::zeroed() + ); + + slcr.ddr_clk_ctrl.write( + slcr::DdrClkCtrl::zeroed() + .ddr_2xclkact(true) + .ddr_3xclkact(true) + .ddr_2xclk_divisor(ddr2x_clk_divisor) + .ddr_3xclk_divisor(ddr3x_clk_divisor) + ); + }); + } +} diff --git a/src/zynq/ddr/regs.rs b/src/zynq/ddr/regs.rs new file mode 100644 index 00000000..77bb5914 --- /dev/null +++ b/src/zynq/ddr/regs.rs @@ -0,0 +1,137 @@ +use volatile_register::{RO, WO, RW}; + +use crate::{register, register_bit, register_bits, register_bits_typed}; + +#[repr(C)] +pub struct RegisterBlock { + pub ddrc_ctrl: RW, + pub two_rank_cfg: RW, + pub hpr_reg: RW, + pub lpr_reg: RW, + pub wr_reg: RW, + pub dram_param_reg0: RW, + pub dram_param_reg1: RW, + pub dram_param_reg2: RW, + pub dram_param_reg3: RW, + pub dram_param_reg4: RW, + pub dram_init_param: RW, + pub dram_emr_reg: RW, + pub dram_emr_mr_reg: RW, + pub dram_burst8_rdwr: RW, + pub dram_disable_dq: RW, + pub dram_addr_map_bank: RW, + pub dram_addr_map_col: RW, + pub dram_addr_map_row: RW, + pub dram_odt_reg: RW, + pub phy_dbg_reg: RW, + pub phy_cmd_timeout_rddata_cpt: RW, + pub mode_sts_reg: RW, + pub dll_calib: RW, + pub odt_delay_hold: RW, + pub ctrl_reg1: RW, + pub ctrl_reg2: RW, + pub ctrl_reg3: RW, + pub ctrl_reg4: RW, + _unused0: [RO; 2], + pub ctrl_reg5: RW, + pub ctrl_reg6: RW, + _unused1: [RO; 8], + pub che_refresh_timer01: RW, + pub che_t_zq: RW, + pub che_t_zq_short_interval_reg: RW, + pub deep_pwrdwn_reg: RW, + pub reg_2c: RW, + pub reg_2d: RW, + pub dfi_timing: RW, + _unused2: [RO; 2], + pub che_ecc_control_reg_offset: RW, + pub che_corr_ecc_log_reg_offset: RW, + pub che_corr_ecc_addr_reg_offset: RW, + pub che_corr_ecc_data_31_0_reg_offset: RW, + pub che_corr_ecc_data_63_32_reg_offset: RW, + pub che_corr_ecc_data_71_64_reg_offset: RW, + pub che_uncorr_ecc_log_reg_offset: RW, + pub che_uncorr_ecc_addr_reg_offset: RW, + pub che_uncorr_ecc_data_31_0_reg_offset: RW, + pub che_uncorr_ecc_data_63_32_reg_offset: RW, + pub che_uncorr_ecc_data_71_64_reg_offset: RW, + pub che_ecc_stats_reg_offset: RW, + pub ecc_scrub: RW, + pub che_ecc_corr_bit_mask_31_0_reg_offset: RW, + pub che_ecc_corr_bit_mask_63_32_reg_offset: RW, + _unused3: [RO; 5], + pub phy_rcvr_enable: RW, + pub phy_config0: RW, + pub phy_config1: RW, + pub phy_config2: RW, + pub phy_config3: RW, + _unused4: RO, + pub phy_init_ratio0: RW, + pub phy_init_ratio1: RW, + pub phy_init_ratio2: RW, + pub phy_init_ratio3: RW, + _unused5: RO, + pub phy_rd_dqs_cfg0: RW, + pub phy_rd_dqs_cfg1: RW, + pub phy_rd_dqs_cfg2: RW, + pub phy_rd_dqs_cfg3: RW, + _unused6: RO, + pub phy_wr_dqs_cfg0: RW, + pub phy_wr_dqs_cfg1: RW, + pub phy_wr_dqs_cfg2: RW, + pub phy_wr_dqs_cfg3: RW, + _unused7: RO, + pub phy_we_cfg0: RW, + pub phy_we_cfg1: RW, + pub phy_we_cfg2: RW, + pub phy_we_cfg3: RW, + _unused8: RO, + pub wr_data_slv0: RW, + pub wr_data_slv1: RW, + pub wr_data_slv2: RW, + pub wr_data_slv3: RW, + _unused9: RO, + pub reg_64: RW, + pub reg_65: RW, + _unused10: [RO; 3], + pub reg69_6a0: RW, + pub reg69_6a1: RW, + _unused11: RO, + pub reg6c_6d2: RW, + pub reg6c_6d3: RW, + pub reg6e_710: RW, + pub reg6e_711: RW, + pub reg6e_712: RW, + pub reg6e_713: RW, + pub phy_dll_sts0: RW, + _unused12: RO, + pub phy_dll_sts1: RW, + pub phy_dll_sts2: RW, + pub phy_dll_sts3: RW, + _unused13: RO, + pub dll_lock_sts: RW, + pub phy_ctrl_sts: RW, + pub phy_ctrl_sts_reg2: RW, + _unused14: [RO; 5], + pub axi_id: RW, + pub page_mask: RW, + pub axi_priority_wr_port0: RW, + pub axi_priority_wr_port1: RW, + pub axi_priority_wr_port2: RW, + pub axi_priority_wr_port3: RW, + pub axi_priority_rd_port0: RW, + pub axi_priority_rd_port1: RW, + pub axi_priority_rd_port2: RW, + pub axi_priority_rd_port3: RW, + _unused15: [RO; 27], + pub excl_access_cfg0: RW, + pub excl_access_cfg1: RW, + pub excl_access_cfg2: RW, + pub excl_access_cfg3: RW, + pub mode_reg_read: RW, + pub lpddr_ctrl0: RW, + pub lpddr_ctrl1: RW, + pub lpddr_ctrl2: RW, + pub lpddr_ctrl3: RW, +} + diff --git a/src/zynq/mod.rs b/src/zynq/mod.rs index d05f5d91..5a3bfd14 100644 --- a/src/zynq/mod.rs +++ b/src/zynq/mod.rs @@ -1,2 +1,3 @@ pub mod axi_hp; pub mod axi_gp; +pub mod ddr;