1
0
Fork 0

libboard_zynq: complete ddr without ps7_init for redpitaya

This commit is contained in:
Astro 2020-11-13 00:10:34 +01:00
parent 8fd317d580
commit 990fa56d6a
2 changed files with 77 additions and 40 deletions

View File

@ -1,12 +1,9 @@
use libregister::{RegisterR, RegisterW, RegisterRW}; use libregister::{RegisterR, RegisterW, RegisterRW};
use log::{debug, info, error}; use log::{debug, info, error};
use crate::{print, println}; use crate::{print, println};
use super::slcr::{self, DdriobVrefSel}; use super::slcr;
use super::clocks::{Clocks, source::{DdrPll, ClockSource}}; use super::clocks::{Clocks, source::{DdrPll, ClockSource}};
#[cfg(feature = "target_redpitaya")]
use super::ps7_init;
mod regs; mod regs;
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
@ -18,8 +15,8 @@ const DDR_FREQ: u32 = 666_666_666;
const DDR_FREQ: u32 = 525_000_000; const DDR_FREQ: u32 = 525_000_000;
#[cfg(feature = "target_redpitaya")] #[cfg(feature = "target_redpitaya")]
/// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 /// Alliance Memory AS4C256M16D3B: 800 MHz DDR3 at 533 MHz
const DDR_FREQ: u32 = 800_000_000; const DDR_FREQ: u32 = 533_333_333;
/// MT41K256M16HA-125 /// MT41K256M16HA-125
const DCI_FREQ: u32 = 10_000_000; const DCI_FREQ: u32 = 10_000_000;
@ -30,15 +27,6 @@ pub struct DdrRam {
impl DdrRam { impl DdrRam {
pub fn ddrram() -> Self { 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(); let clocks = Self::clock_setup();
Self::configure_iob(); Self::configure_iob();
Self::calibrate_iob_impedance(&clocks); Self::calibrate_iob_impedance(&clocks);
@ -47,7 +35,6 @@ impl DdrRam {
ddr.reset_ddrc(|ddr| ddr.configure()); ddr.reset_ddrc(|ddr| ddr.configure());
ddr ddr
} }
}
/// Zynq-7000 AP SoC Technical Reference Manual: /// Zynq-7000 AP SoC Technical Reference Manual:
/// 10.6.1 DDR Clock Initialization /// 10.6.1 DDR Clock Initialization
@ -237,6 +224,7 @@ impl DdrRam {
.vref_int_en(false) .vref_int_en(false)
.vref_ext_en_lower(true) .vref_ext_en_lower(true)
.vref_ext_en_upper(false) .vref_ext_en_upper(false)
.refio_en(true)
); );
}); });
} }
@ -249,6 +237,13 @@ impl DdrRam {
.t_rfc_min(0x9e) .t_rfc_min(0x9e)
.post_selfref_gap_x32(0x10) .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")] #[cfg(feature = "target_zc706")]
self.regs.dram_param0.write( self.regs.dram_param0.write(
regs::DramParam0::zeroed() regs::DramParam0::zeroed()
@ -256,6 +251,16 @@ impl DdrRam {
.t_rfc_min(0x56) .t_rfc_min(0x56)
.post_selfref_gap_x32(0x10) .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( self.regs.dram_param2.write(
regs::DramParam2::zeroed() regs::DramParam2::zeroed()
@ -267,6 +272,20 @@ impl DdrRam {
.rd2pre(0x4) .rd2pre(0x4)
.t_rcd(0x7) .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( self.regs.dram_emr_mr.write(
regs::DramEmrMr::zeroed() regs::DramEmrMr::zeroed()
@ -275,11 +294,19 @@ impl DdrRam {
); );
#[cfg(feature = "target_cora_z7_10")] #[cfg(feature = "target_cora_z7_10")]
self.regs.phy_config2.modify( self.regs.phy_configs[2].modify(
|_, w| w.data_slice_in_use(false) |_, w| w.data_slice_in_use(false)
); );
#[cfg(feature = "target_cora_z7_10")] #[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) |_, w| w.data_slice_in_use(false)
); );
@ -316,7 +343,7 @@ impl DdrRam {
); );
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
self.regs.phy_init_ratio3.write( self.regs.phy_init_ratios[3].write(
regs::PhyInitRatio::zeroed() regs::PhyInitRatio::zeroed()
.wrlvl_init_ratio(0x21) .wrlvl_init_ratio(0x21)
.gatelvl_init_ratio(0xee) .gatelvl_init_ratio(0xee)
@ -328,6 +355,18 @@ impl DdrRam {
.phy_ctrl_slave_ratio(0x100) .phy_ctrl_slave_ratio(0x100)
.phy_invert_clkout(true) .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( self.regs.reg_65.write(
regs::Reg65::zeroed() regs::Reg65::zeroed()
@ -364,7 +403,7 @@ impl DdrRam {
self.regs.dram_addr_map_col.write(0xFFF00000); self.regs.dram_addr_map_col.write(0xFFF00000);
self.regs.dram_addr_map_row.write(0x0F666666); 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 { unsafe {
// row/column address bits // row/column address bits
self.regs.dram_addr_map_bank.write(0x00000666); self.regs.dram_addr_map_bank.write(0x00000666);

View File

@ -60,7 +60,7 @@ pub struct RegisterBlock {
pub ctrl6: RW<u32>, pub ctrl6: RW<u32>,
_unused1: [RO<u32>; 8], _unused1: [RO<u32>; 8],
pub che_refresh_timer01: RW<u32>, pub che_refresh_timer01: RW<u32>,
pub che_t_zq: RW<u32>, pub che_t_zq: CheTZq,
pub che_t_zq_short_interval: RW<u32>, pub che_t_zq_short_interval: RW<u32>,
pub deep_pwrdwn: RW<u32>, pub deep_pwrdwn: RW<u32>,
pub reg_2c: Reg2C, pub reg_2c: Reg2C,
@ -84,15 +84,9 @@ pub struct RegisterBlock {
pub che_ecc_corr_bit_mask_63_32_offset: RW<u32>, pub che_ecc_corr_bit_mask_63_32_offset: RW<u32>,
_unused3: [RO<u32>; 5], _unused3: [RO<u32>; 5],
pub phy_rcvr_enable: RW<u32>, pub phy_rcvr_enable: RW<u32>,
pub phy_config0: PhyConfig, pub phy_configs: [PhyConfig; 4],
pub phy_config1: PhyConfig,
pub phy_config2: PhyConfig,
pub phy_config3: PhyConfig,
_unused4: RO<u32>, _unused4: RO<u32>,
pub phy_init_ratio0: PhyInitRatio, pub phy_init_ratios: [PhyInitRatio; 4],
pub phy_init_ratio1: PhyInitRatio,
pub phy_init_ratio2: PhyInitRatio,
pub phy_init_ratio3: PhyInitRatio,
_unused5: RO<u32>, _unused5: RO<u32>,
pub phy_rd_dqs_cfg0: RW<u32>, pub phy_rd_dqs_cfg0: RW<u32>,
pub phy_rd_dqs_cfg1: RW<u32>, pub phy_rd_dqs_cfg1: RW<u32>,
@ -138,10 +132,7 @@ pub struct RegisterBlock {
_unused14: [RO<u32>; 5], _unused14: [RO<u32>; 5],
pub axi_id: RW<u32>, pub axi_id: RW<u32>,
pub page_mask: RW<u32>, pub page_mask: RW<u32>,
pub axi_priority_wr_port0: RW<u32>, pub axi_priority_wr_ports: [RW<u32>; 4],
pub axi_priority_wr_port1: RW<u32>,
pub axi_priority_wr_port2: RW<u32>,
pub axi_priority_wr_port3: RW<u32>,
pub axi_priority_rd_ports: [AxiPriorityRd; 4], pub axi_priority_rd_ports: [AxiPriorityRd; 4],
_unused15: [RO<u32>; 27], _unused15: [RO<u32>; 27],
pub excl_access_cfg0: RW<u32>, pub excl_access_cfg0: RW<u32>,
@ -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, gatelvl_num_of_dq0, u8, 24, 27);
register_bits!(phy_cmd_timeout_rddata_cpt, wrlvl_num_of_dq0, u8, 28, 31); 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!(reg_2c, Reg2C, RW, u32);
register_bits!(reg_2c, wrlvl_max_x1024, u16, 0, 11); register_bits!(reg_2c, wrlvl_max_x1024, u16, 0, 11);
register_bits!(reg_2c, rdlvl_max_x1024, u16, 12, 23); register_bits!(reg_2c, rdlvl_max_x1024, u16, 12, 23);