From b9323653bbe84ea198c486241a8ba551d65694cf Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 10 Nov 2020 14:33:31 +0100 Subject: [PATCH] libboard_zynq: complete ddr without ps7_init for cora_z7_10 --- experiments/src/main.rs | 2 - libboard_zynq/src/ddr/mod.rs | 88 ++++++++++++++++++++++-- libboard_zynq/src/ddr/regs.rs | 72 +++++++++++++++---- libboard_zynq/src/ps7_init/cora_z7_10.rs | 5 +- 4 files changed, 144 insertions(+), 23 deletions(-) diff --git a/experiments/src/main.rs b/experiments/src/main.rs index 5289ece..39a7179 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -93,8 +93,6 @@ pub fn main_core0() { println!("\nZynq experiments"); let mut interrupt_controller = gic::InterruptController::gic(mpcore::RegisterBlock::mpcore()); interrupt_controller.enable_interrupts(); - // ps7_init::apply(); - libboard_zynq::stdio::drop_uart(); libboard_zynq::logger::init().unwrap(); log::set_max_level(log::LevelFilter::Trace); diff --git a/libboard_zynq/src/ddr/mod.rs b/libboard_zynq/src/ddr/mod.rs index 1a1afcb..e97dca3 100644 --- a/libboard_zynq/src/ddr/mod.rs +++ b/libboard_zynq/src/ddr/mod.rs @@ -4,7 +4,7 @@ use crate::{print, println}; use super::slcr::{self, DdriobVrefSel}; use super::clocks::{Clocks, source::{DdrPll, ClockSource}}; -#[cfg(any(feature = "target_redpitaya", feature = "target_cora_z7_10"))] +#[cfg(feature = "target_redpitaya")] use super::ps7_init; mod regs; @@ -30,18 +30,18 @@ pub struct DdrRam { impl DdrRam { pub fn ddrram() -> Self { - if cfg!(any(feature = "target_redpitaya", feature = "target_cora_z7_10")) { + 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(any(feature = "target_redpitaya", feature = "target_cora_z7_10"))] + #[cfg(feature = "target_redpitaya")] ps7_init::apply(); let regs = regs::RegisterBlock::ddrc(); DdrRam { regs } } else { let clocks = Self::clock_setup(); - Self::calibrate_iob_impedance(&clocks); Self::configure_iob(); + Self::calibrate_iob_impedance(&clocks); let regs = regs::RegisterBlock::ddrc(); let mut ddr = DdrRam { regs }; ddr.reset_ddrc(|ddr| ddr.configure()); @@ -218,12 +218,12 @@ impl DdrRam { slcr.ddriob_drive_slew_clock.write(0x00F9861C); } - // Enable external V[REF] #[cfg(feature = "target_cora_z7_10")] slcr.ddriob_ddr_ctrl.modify(|_, w| w .vref_int_en(false) .vref_ext_en_lower(true) .vref_ext_en_upper(false) + .refio_en(true) ); #[cfg(feature = "target_zc706")] slcr.ddriob_ddr_ctrl.modify(|_, w| w @@ -242,6 +242,14 @@ impl DdrRam { } fn configure(&mut self) { + #[cfg(feature = "target_cora_z7_10")] + self.regs.dram_param0.write( + regs::DramParam0::zeroed() + .t_rc(0x1a) + .t_rfc_min(0x9e) + .post_selfref_gap_x32(0x10) + ); + #[cfg(feature = "target_zc706")] self.regs.dram_param0.write( regs::DramParam0::zeroed() .t_rc(0x1b) @@ -249,6 +257,17 @@ impl DdrRam { .post_selfref_gap_x32(0x10) ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.dram_param1.write( + regs::DramParam1::zeroed() + .wr2pre(0x12) + .powerdown_to_x32(0x6) + .t_faw(0x15) + .t_ras_max(0x23) + .t_ras_min(0x13) + .t_cke(0x4) + ); + self.regs.dram_param2.write( regs::DramParam2::zeroed() .write_latency(0x5) @@ -260,12 +279,43 @@ impl DdrRam { .t_rcd(0x7) ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.dram_param3.write( + regs::DramParam3::zeroed() + .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() .mr(0x930) .emr(0x4) ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.dram_burst8_rdwr.write( + regs::Burst8Rdwr::zeroed() + .burst_rdwr(4) + .pre_cke_x1024(0x167) + .post_cke_x1024(0x1) + ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.phy_config2.modify( + |_, w| w.data_slice_in_use(false) + ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.phy_config3.modify( + |_, w| w.data_slice_in_use(false) + ); + self.regs.phy_cmd_timeout_rddata_cpt.modify( |_, w| w .rd_cmd_to_data(0x0) @@ -298,12 +348,26 @@ impl DdrRam { .ctrlup_max(0x40) ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.phy_init_ratio3.write( + regs::PhyInitRatio::zeroed() + .wrlvl_init_ratio(0x0) + .gatelvl_init_ratio(0x76) + ); + #[cfg(feature = "target_zc706")] self.regs.phy_init_ratio3.write( regs::PhyInitRatio::zeroed() .wrlvl_init_ratio(0x21) .gatelvl_init_ratio(0xee) ); + #[cfg(feature = "target_cora_z7_10")] + self.regs.reg_64.modify( + |_, w| w + .phy_ctrl_slave_ratio(0x100) + .phy_invert_clkout(true) + ); + self.regs.reg_65.write( regs::Reg65::zeroed() .wr_rl_delay(0x2) @@ -315,6 +379,18 @@ impl DdrRam { .dis_calib_rst(false) .ctrl_slave_delay(0x0) ); + + #[cfg(feature = "target_cora_z7_10")] + for axi_priority_rd_port in &mut self.regs.axi_priority_rd_ports { + axi_priority_rd_port.modify( + |_, w| w + .arb_pri_rd_portn(0x3ff) + .arb_disable_aging_rd_portn(false) + .arb_disable_urgent_rd_portn(false) + .arb_disable_page_match_rd_portn(false) + .arb_set_hpr_rd_portn(false) + ); + } } /// Reset DDR controller @@ -370,7 +446,7 @@ impl DdrRam { #[cfg(feature = "target_zc706")] let megabytes = 1023; #[cfg(feature = "target_cora_z7_10")] - let megabytes = 511; + let megabytes = 512; #[cfg(feature = "target_redpitaya")] let megabytes = 511; diff --git a/libboard_zynq/src/ddr/regs.rs b/libboard_zynq/src/ddr/regs.rs index 3213ceb..fefd827 100644 --- a/libboard_zynq/src/ddr/regs.rs +++ b/libboard_zynq/src/ddr/regs.rs @@ -33,14 +33,14 @@ pub struct RegisterBlock { pub lpr: RW, pub wr: RW, pub dram_param0: DramParam0, - pub dram_param1: RW, + pub dram_param1: DramParam1, pub dram_param2: DramParam2, - pub dram_param3: RW, + pub dram_param3: DramParam3, pub dram_param4: RW, pub dram_init_param: RW, pub dram_emr: RW, pub dram_emr_mr: DramEmrMr, - pub dram_burst8_rdwr: RW, + pub dram_burst8_rdwr: Burst8Rdwr, pub dram_disable_dq: RW, pub dram_addr_map_bank: RW, pub dram_addr_map_col: RW, @@ -84,10 +84,10 @@ pub struct RegisterBlock { pub che_ecc_corr_bit_mask_63_32_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, + pub phy_config0: PhyConfig, + pub phy_config1: PhyConfig, + pub phy_config2: PhyConfig, + pub phy_config3: PhyConfig, _unused4: RO, pub phy_init_ratio0: PhyInitRatio, pub phy_init_ratio1: PhyInitRatio, @@ -114,7 +114,7 @@ pub struct RegisterBlock { pub wr_data_slv2: RW, pub wr_data_slv3: RW, _unused9: RO, - pub reg_64: RW, + pub reg_64: Reg64, pub reg_65: Reg65, _unused10: [RO; 3], pub reg69_6a0: RW, @@ -142,10 +142,7 @@ pub struct RegisterBlock { 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, + pub axi_priority_rd_ports: [AxiPriorityRd; 4], _unused15: [RO; 27], pub excl_access_cfg0: RW, pub excl_access_cfg1: RW, @@ -173,6 +170,14 @@ register_bits!(dram_param0, t_rc, u8, 0, 5); register_bits!(dram_param0, t_rfc_min, u8, 6, 13); register_bits!(dram_param0, post_selfref_gap_x32, u8, 14, 20); +register!(dram_param1, DramParam1, RW, u32); +register_bits!(dram_param1, wr2pre, u8, 0, 4); +register_bits!(dram_param1, powerdown_to_x32, u8, 5, 9); +register_bits!(dram_param1, t_faw, u8, 10, 15); +register_bits!(dram_param1, t_ras_max, u8, 16, 21); +register_bits!(dram_param1, t_ras_min, u8, 22, 26); +register_bits!(dram_param1, t_cke, u8, 28, 31); + register!(dram_param2, DramParam2, RW, u32); register_bits!(dram_param2, write_latency, u8, 0, 4); register_bits!(dram_param2, rd2wr, u8, 5, 9); @@ -182,10 +187,29 @@ register_bits!(dram_param2, pad_pd, u8, 20, 22); register_bits!(dram_param2, rd2pre, u8, 23, 27); register_bits!(dram_param2, t_rcd, u8, 28, 31); +register!(dram_param3, DramParam3, RW, u32); +register_bits!(dram_param3, t_ccd, u8, 2, 4); +register_bits!(dram_param3, t_rrd, u8, 5, 7); +register_bits!(dram_param3, refresh_margin, u8, 8, 11); +register_bits!(dram_param3, t_rp, u8, 12, 15); +register_bits!(dram_param3, refresh_to_x32, u8, 16, 20); +register_bit!(dram_param3, sdram, 21); +register_bit!(dram_param3, mobile, 22); +register_bit!(dram_param3, dfi_dram_clk_disable, 23); +register_bits!(dram_param3, read_latency, u8, 24, 28); +register_bit!(dram_param3, mode_ddr1_ddr2, 29); +register_bit!(dram_param3, dis_pad_pd, 30); + register!(dram_emr_mr, DramEmrMr, RW, u32); register_bits!(dram_emr_mr, mr, u16, 0, 15); register_bits!(dram_emr_mr, emr, u16, 16, 31); +register!(burst8_rdwr, Burst8Rdwr, RW, u32); +register_bits!(burst8_rdwr, burst_rdwr, u8, 0, 3); +register_bits!(burst8_rdwr, pre_cke_x1024, u16, 4, 13); +register_bits!(burst8_rdwr, post_cke_x1024, u16, 16, 25); +register_bit!(burst8_rdwr, burstchop, 28); + register!(phy_cmd_timeout_rddata_cpt, PhyCmdTimeoutRddataCpt, RW, u32); register_bits!(phy_cmd_timeout_rddata_cpt, rd_cmd_to_data, u8, 0, 3); register_bits!(phy_cmd_timeout_rddata_cpt, wr_cmd_to_data, u8, 4, 7); @@ -212,10 +236,27 @@ register_bits!(dfi_timing, rddata_en, u8, 0, 4); register_bits!(dfi_timing, ctrlup_min, u16, 5, 14); register_bits!(dfi_timing, ctrlup_max, u16, 15, 24); +register!(phy_config, PhyConfig, RW, u32); +register_bit!(phy_config, data_slice_in_use, 0); +register_bit!(phy_config, rdlvl_inc_mode, 1); +register_bit!(phy_config, gatelvl_inc_mode, 2); +register_bit!(phy_config, wrlvl_inc_mode, 3); +register_bits!(phy_config, dq_offset, u8, 24, 30); + register!(phy_init_ratio, PhyInitRatio, RW, u32); register_bits!(phy_init_ratio, wrlvl_init_ratio, u16, 0, 9); register_bits!(phy_init_ratio, gatelvl_init_ratio, u16, 10, 19); +register!(reg_64, Reg64, RW, u32); +register_bit!(reg_64, phy_bl2, 1); +register_bit!(reg_64, phy_invert_clkout, 7); +register_bit!(reg_64, phy_sel_logic, 9); +register_bits!(reg_64, phy_ctrl_slave_ratio, u16, 10, 19); +register_bit!(reg_64, phy_ctrl_slave_force, 20); +register_bits!(reg_64, phy_ctrl_slave_delay, u8, 21, 27); +register_bit!(reg_64, phy_lpddr, 29); +register_bit!(reg_64, phy_cmd_latency, 30); + register!(reg_65, Reg65, RW, u32); register_bits!(reg_65, wr_rl_delay, u8, 0, 4); register_bits!(reg_65, rd_rl_delay, u8, 5, 9); @@ -231,3 +272,10 @@ register!(mode_sts_reg, ModeStsReg, RO, u32); register_bits_typed!(mode_sts_reg, operating_mode, u8, ControllerStatus, 0, 2); // (mode_sts_reg) ... + +register!(axi_priority_rd, AxiPriorityRd, RW, u32); +register_bits!(axi_priority_rd, arb_pri_rd_portn, u16, 0, 9); +register_bit!(axi_priority_rd, arb_disable_aging_rd_portn, 16); +register_bit!(axi_priority_rd, arb_disable_urgent_rd_portn, 17); +register_bit!(axi_priority_rd, arb_disable_page_match_rd_portn, 18); +register_bit!(axi_priority_rd, arb_set_hpr_rd_portn, 19); diff --git a/libboard_zynq/src/ps7_init/cora_z7_10.rs b/libboard_zynq/src/ps7_init/cora_z7_10.rs index 15788e0..e8b7c2e 100644 --- a/libboard_zynq/src/ps7_init/cora_z7_10.rs +++ b/libboard_zynq/src/ps7_init/cora_z7_10.rs @@ -427,7 +427,7 @@ pub const INIT_DATA: &'static [InitOp] = &[ // .. DisableRcvr = 0 // .. ==> 0xF8000700[13:13] = 0x00000000U // .. ==> MASK : 0x00002000U VAL : 0x00000000U - // .. + // .. MaskWrite(0xF8000700, 0x00003FFF, 0x00001600), // .. TRI_ENABLE = 0 // .. ==> 0xF8000704[0:0] = 0x00000000U @@ -3522,7 +3522,7 @@ pub const INIT_DATA: &'static [InitOp] = &[ // .. .. FINISH: CHECK DDR STATUS // .. FINISH: DDR INITIALIZATION // FINISH: top - + // *** ps7_peripherals_init_data_3_0 *** // START: top // .. START: SLCR SETTINGS @@ -3978,5 +3978,4 @@ pub const INIT_DATA: &'static [InitOp] = &[ // .. .. FINISH: NOR CHIP SELECT // .. FINISH: SMC TIMING CALCULATION REGISTER UPDATE // FINISH: top - ];