diff --git a/libboard_zynq/src/ddr/mod.rs b/libboard_zynq/src/ddr/mod.rs index 8850d96..1ba87c4 100644 --- a/libboard_zynq/src/ddr/mod.rs +++ b/libboard_zynq/src/ddr/mod.rs @@ -1,12 +1,9 @@ use libregister::{RegisterR, RegisterW, RegisterRW}; use log::{debug, info, error}; use crate::{print, println}; -use super::slcr::{self, DdriobVrefSel}; +use super::slcr; use super::clocks::{Clocks, source::{DdrPll, ClockSource}}; -#[cfg(feature = "target_redpitaya")] -use super::ps7_init; - mod regs; #[cfg(feature = "target_zc706")] @@ -18,8 +15,8 @@ const DDR_FREQ: u32 = 666_666_666; const DDR_FREQ: u32 = 525_000_000; #[cfg(feature = "target_redpitaya")] -/// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 -const DDR_FREQ: u32 = 800_000_000; +/// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 at 533 MHz +const DDR_FREQ: u32 = 533_333_333; /// MT41K256M16HA-125 const DCI_FREQ: u32 = 10_000_000; @@ -30,23 +27,13 @@ pub struct DdrRam { impl DdrRam { pub fn ddrram() -> Self { - if cfg!(feature = "target_redpitaya") { - // We have not yet fixed red pitaya initialization yet. It seems - // that the clock configuration, iob settings and ddr settings are - // all problematic - #[cfg(feature = "target_redpitaya")] - ps7_init::apply(); - let regs = regs::RegisterBlock::ddrc(); - DdrRam { regs } - } else { - let clocks = Self::clock_setup(); - Self::configure_iob(); - Self::calibrate_iob_impedance(&clocks); - let regs = regs::RegisterBlock::ddrc(); - let mut ddr = DdrRam { regs }; - ddr.reset_ddrc(|ddr| ddr.configure()); - ddr - } + let clocks = Self::clock_setup(); + Self::configure_iob(); + Self::calibrate_iob_impedance(&clocks); + let regs = regs::RegisterBlock::ddrc(); + let mut ddr = DdrRam { regs }; + ddr.reset_ddrc(|ddr| ddr.configure()); + ddr } /// Zynq-7000 AP SoC Technical Reference Manual: @@ -237,6 +224,7 @@ impl DdrRam { .vref_int_en(false) .vref_ext_en_lower(true) .vref_ext_en_upper(false) + .refio_en(true) ); }); } @@ -249,6 +237,13 @@ impl DdrRam { .t_rfc_min(0x9e) .post_selfref_gap_x32(0x10) ); + #[cfg(feature = "target_redpitaya")] + self.regs.dram_param0.write( + regs::DramParam0::zeroed() + .t_rc(0x1b) + .t_rfc_min(0xa0) + .post_selfref_gap_x32(0x10) + ); #[cfg(feature = "target_zc706")] self.regs.dram_param0.write( regs::DramParam0::zeroed() @@ -256,6 +251,16 @@ impl DdrRam { .t_rfc_min(0x56) .post_selfref_gap_x32(0x10) ); + #[cfg(feature = "target_redpitaya")] + self.regs.dram_param1.modify( + |_, w| w + .wr2pre(0x12) + .powerdown_to_x32(6) + .t_faw(0x16) + .t_ras_max(0x24) + .t_ras_min(0x13) + .t_cke(4) + ); self.regs.dram_param2.write( regs::DramParam2::zeroed() @@ -267,6 +272,20 @@ impl DdrRam { .rd2pre(0x4) .t_rcd(0x7) ); + #[cfg(feature = "target_redpitaya")] + self.regs.dram_param3.modify( + |_, w| w + .t_ccd(4) + .t_rrd(6) + .refresh_margin(2) + .t_rp(7) + .refresh_to_x32(8) + .mobile(false) + .dfi_dram_clk_disable(false) + .read_latency(7) + .mode_ddr1_ddr2(true) + .dis_pad_pd(false) + ); self.regs.dram_emr_mr.write( regs::DramEmrMr::zeroed() @@ -275,11 +294,19 @@ impl DdrRam { ); #[cfg(feature = "target_cora_z7_10")] - self.regs.phy_config2.modify( + self.regs.phy_configs[2].modify( |_, w| w.data_slice_in_use(false) ); #[cfg(feature = "target_cora_z7_10")] - self.regs.phy_config3.modify( + self.regs.phy_configs[3].modify( + |_, w| w.data_slice_in_use(false) + ); + #[cfg(feature = "target_redpitaya")] + self.regs.phy_configs[2].modify( + |_, w| w.data_slice_in_use(false) + ); + #[cfg(feature = "target_redpitaya")] + self.regs.phy_configs[3].modify( |_, w| w.data_slice_in_use(false) ); @@ -316,7 +343,7 @@ impl DdrRam { ); #[cfg(feature = "target_zc706")] - self.regs.phy_init_ratio3.write( + self.regs.phy_init_ratios[3].write( regs::PhyInitRatio::zeroed() .wrlvl_init_ratio(0x21) .gatelvl_init_ratio(0xee) @@ -328,6 +355,18 @@ impl DdrRam { .phy_ctrl_slave_ratio(0x100) .phy_invert_clkout(true) ); + #[cfg(feature = "target_redpitaya")] + self.regs.reg_64.modify( + |_, w| w + .phy_bl2(false) + .phy_invert_clkout(true) + .phy_sel_logic(false) + .phy_ctrl_slave_ratio(0x100) + .phy_ctrl_slave_force(false) + .phy_ctrl_slave_delay(0) + .phy_lpddr(false) + .phy_cmd_latency(false) + ); self.regs.reg_65.write( regs::Reg65::zeroed() @@ -364,7 +403,7 @@ impl DdrRam { self.regs.dram_addr_map_col.write(0xFFF00000); self.regs.dram_addr_map_row.write(0x0F666666); } - #[cfg(feature = "target_cora_z7_10")] + #[cfg(any(feature = "target_cora_z7_10", feature = "target_redpitaya"))] unsafe { // row/column address bits self.regs.dram_addr_map_bank.write(0x00000666); diff --git a/libboard_zynq/src/ddr/regs.rs b/libboard_zynq/src/ddr/regs.rs index fefd827..843372a 100644 --- a/libboard_zynq/src/ddr/regs.rs +++ b/libboard_zynq/src/ddr/regs.rs @@ -60,7 +60,7 @@ pub struct RegisterBlock { pub ctrl6: RW, _unused1: [RO; 8], pub che_refresh_timer01: RW, - pub che_t_zq: RW, + pub che_t_zq: CheTZq, pub che_t_zq_short_interval: RW, pub deep_pwrdwn: RW, pub reg_2c: Reg2C, @@ -84,15 +84,9 @@ pub struct RegisterBlock { pub che_ecc_corr_bit_mask_63_32_offset: RW, _unused3: [RO; 5], pub phy_rcvr_enable: RW, - pub phy_config0: PhyConfig, - pub phy_config1: PhyConfig, - pub phy_config2: PhyConfig, - pub phy_config3: PhyConfig, + pub phy_configs: [PhyConfig; 4], _unused4: RO, - pub phy_init_ratio0: PhyInitRatio, - pub phy_init_ratio1: PhyInitRatio, - pub phy_init_ratio2: PhyInitRatio, - pub phy_init_ratio3: PhyInitRatio, + pub phy_init_ratios: [PhyInitRatio; 4], _unused5: RO, pub phy_rd_dqs_cfg0: RW, pub phy_rd_dqs_cfg1: RW, @@ -138,10 +132,7 @@ pub struct RegisterBlock { _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_wr_ports: [RW; 4], pub axi_priority_rd_ports: [AxiPriorityRd; 4], _unused15: [RO; 27], pub excl_access_cfg0: RW, @@ -222,6 +213,13 @@ register_bit!(phy_cmd_timeout_rddata_cpt, clk_stall_level, 19); register_bits!(phy_cmd_timeout_rddata_cpt, gatelvl_num_of_dq0, u8, 24, 27); register_bits!(phy_cmd_timeout_rddata_cpt, wrlvl_num_of_dq0, u8, 28, 31); +register!(che_t_zq, CheTZq, RW, u32); +register_bit!(che_t_zq, dis_auto_zq, 0); +register_bit!(che_t_zq, ddr3, 1); +register_bits!(che_t_zq, t_mod, u8, 2, 11); +register_bits!(che_t_zq, t_zq_long_nop, u16, 12, 21); +register_bits!(che_t_zq, t_zq_short_nop, u16, 22, 31); + register!(reg_2c, Reg2C, RW, u32); register_bits!(reg_2c, wrlvl_max_x1024, u16, 0, 11); register_bits!(reg_2c, rdlvl_max_x1024, u16, 12, 23);