From f0697c3ec3a40736aabb8ab7d7cf57e8ee52978f Mon Sep 17 00:00:00 2001 From: Astro Date: Fri, 3 Jul 2020 02:19:42 +0200 Subject: [PATCH] ddr: implement additional configuration --- libboard_zynq/src/ddr/mod.rs | 77 ++++++++++++++++++++++++++++++++ libboard_zynq/src/ddr/regs.rs | 84 +++++++++++++++++++++++++++++------ 2 files changed, 148 insertions(+), 13 deletions(-) diff --git a/libboard_zynq/src/ddr/mod.rs b/libboard_zynq/src/ddr/mod.rs index 4060d76..8842140 100644 --- a/libboard_zynq/src/ddr/mod.rs +++ b/libboard_zynq/src/ddr/mod.rs @@ -29,6 +29,7 @@ impl DdrRam { let regs = unsafe { regs::RegisterBlock::new() }; let mut ddr = DdrRam { regs }; + ddr.configure(); ddr.reset_ddrc(); ddr } @@ -181,6 +182,82 @@ impl DdrRam { }); } + fn configure(&mut self) { + self.regs.dram_param0.write( + regs::DramParam0::zeroed() + .t_rc(0x1b) + .t_rfc_min(0x56) + .post_selfref_gap_x32(0x10) + ); + + self.regs.dram_param2.write( + regs::DramParam2::zeroed() + .write_latency(0x5) + .rd2wr(0x7) + .wr2rd(0xe) + .t_xp(0x4) + .pad_pd(0x0) + .rd2pre(0x4) + .t_rcd(0x7) + ); + + self.regs.dram_emr_mr.write( + regs::DramEmrMr::zeroed() + .mr(0x930) + .emr(0x4) + ); + + self.regs.phy_cmd_timeout_rddata_cpt.modify( + |_, w| w + .rd_cmd_to_data(0x0) + .wr_cmd_to_data(0x0) + .we_to_re_delay(0x8) + .rdc_fifo_rst_disable(false) + .use_fixed_re(true) + .rdc_fifo_rst_err_cnt_clr(false) + .dis_phy_ctrl_rstn(false) + .clk_stall_level(false) + .gatelvl_num_of_dq0(0x7) + .wrlvl_num_of_dq0(0x7) + ); + + self.regs.reg_2c.write( + regs::Reg2C::zeroed() + .wrlvl_max_x1024(0xfff) + .rdlvl_max_x1024(0xfff) + .twrlvl_max_error(false) + .trdlvl_max_error(false) + .dfi_wr_level_en(true) + .dfi_rd_dqs_gate_level(true) + .dfi_rd_data_eye_train(true) + ); + + self.regs.dfi_timing.write( + regs::DfiTiming::zeroed() + .rddata_en(0x6) + .ctrlup_min(0x3) + .ctrlup_max(0x4) + ); + + self.regs.phy_init_ratio3.write( + regs::PhyInitRatio::zeroed() + .wrlvl_init_ratio(0x21) + .gatelvl_init_ratio(0xee) + ); + + self.regs.reg_65.write( + regs::Reg65::zeroed() + .wr_rl_delay(0x2) + .rd_rl_delay(0x4) + .dll_lock_diff(0xf) + .use_wr_level(true) + .use_rd_dqs_gate_level(true) + .use_rd_data_eye_level(true) + .dis_calib_rst(false) + .ctrl_slave_delay(0x0) + ); + } + /// Reset DDR controller fn reset_ddrc(&mut self) { #[cfg(feature = "target_zc706")] diff --git a/libboard_zynq/src/ddr/regs.rs b/libboard_zynq/src/ddr/regs.rs index 34e0e9e..53f67cb 100644 --- a/libboard_zynq/src/ddr/regs.rs +++ b/libboard_zynq/src/ddr/regs.rs @@ -1,6 +1,6 @@ use volatile_register::{RO, RW}; -use libregister::{register, register_bit, register_bits_typed}; +use libregister::{register, register_bit, register_bits, register_bits_typed}; #[allow(unused)] #[derive(Clone, Copy)] @@ -32,14 +32,14 @@ pub struct RegisterBlock { pub hpr: RW, pub lpr: RW, pub wr: RW, - pub dram_param0: RW, + pub dram_param0: DramParam0, pub dram_param1: RW, - pub dram_param2: RW, + pub dram_param2: DramParam2, pub dram_param3: RW, pub dram_param4: RW, pub dram_init_param: RW, pub dram_emr: RW, - pub dram_emr_mr: RW, + pub dram_emr_mr: DramEmrMr, pub dram_burst8_rdwr: RW, pub dram_disable_dq: RW, pub dram_addr_map_bank: RW, @@ -47,7 +47,7 @@ pub struct RegisterBlock { pub dram_addr_map_row: RW, pub dram_odt: RW, pub phy_dbg: RW, - pub phy_cmd_timeout_rddata_cpt: RW, + pub phy_cmd_timeout_rddata_cpt: PhyCmdTimeoutRddataCpt, pub mode_sts: ModeStsReg, pub dll_calib: RW, pub odt_delay_hold: RW, @@ -63,9 +63,9 @@ pub struct RegisterBlock { pub che_t_zq: RW, pub che_t_zq_short_interval: RW, pub deep_pwrdwn: RW, - pub reg_2c: RW, + pub reg_2c: Reg2C, pub reg_2d: RW, - pub dfi_timing: RW, + pub dfi_timing: DfiTiming, _unused2: [RO; 2], pub che_ecc_control_offset: RW, pub che_corr_ecc_log_offset: RW, @@ -89,10 +89,10 @@ pub struct RegisterBlock { 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, + pub phy_init_ratio0: PhyInitRatio, + pub phy_init_ratio1: PhyInitRatio, + pub phy_init_ratio2: PhyInitRatio, + pub phy_init_ratio3: PhyInitRatio, _unused5: RO, pub phy_rd_dqs_cfg0: RW, pub phy_rd_dqs_cfg1: RW, @@ -115,7 +115,7 @@ pub struct RegisterBlock { pub wr_data_slv3: RW, _unused9: RO, pub reg_64: RW, - pub reg_65: RW, + pub reg_65: Reg65, _unused10: [RO; 3], pub reg69_6a0: RW, pub reg69_6a1: RW, @@ -151,7 +151,7 @@ pub struct RegisterBlock { pub excl_access_cfg1: RW, pub excl_access_cfg2: RW, pub excl_access_cfg3: RW, - pub mode_read: RW, + pub mode_reg_read: RW, pub lpddr_ctrl0: RW, pub lpddr_ctrl1: RW, pub lpddr_ctrl2: RW, @@ -172,6 +172,64 @@ register_bit!(ddrc_ctrl, powerdown_en, 1); register_bits_typed!(ddrc_ctrl, data_bus_width, u8, DataBusWidth, 2, 3); // (ddrc_ctrl) ... +register!(dram_param0, DramParam0, RW, u32); +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_param2, DramParam2, RW, u32); +register_bits!(dram_param2, write_latency, u8, 0, 4); +register_bits!(dram_param2, rd2wr, u8, 5, 9); +register_bits!(dram_param2, wr2rd, u8, 10, 14); +register_bits!(dram_param2, t_xp, u8, 15, 19); +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_emr_mr, DramEmrMr, RW, u32); +register_bits!(dram_emr_mr, mr, u16, 0, 15); +register_bits!(dram_emr_mr, emr, u16, 16, 31); + +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); +register_bits!(phy_cmd_timeout_rddata_cpt, we_to_re_delay, u8, 8, 11); +register_bit!(phy_cmd_timeout_rddata_cpt, rdc_fifo_rst_disable, 15); +register_bit!(phy_cmd_timeout_rddata_cpt, use_fixed_re, 16); +register_bit!(phy_cmd_timeout_rddata_cpt, rdc_fifo_rst_err_cnt_clr, 17); +register_bit!(phy_cmd_timeout_rddata_cpt, dis_phy_ctrl_rstn, 18); +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!(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); +register_bit!(reg_2c, twrlvl_max_error, 24); +register_bit!(reg_2c, trdlvl_max_error, 25); +register_bit!(reg_2c, dfi_wr_level_en, 26); +register_bit!(reg_2c, dfi_rd_dqs_gate_level, 27); +register_bit!(reg_2c, dfi_rd_data_eye_train, 28); + +register!(dfi_timing, DfiTiming, RW, u32); +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_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_65, Reg65, RW, u32); +register_bits!(reg_65, wr_rl_delay, u8, 0, 4); +register_bits!(reg_65, rd_rl_delay, u8, 5, 9); +register_bits!(reg_65, dll_lock_diff, u8, 10, 13); +register_bit!(reg_65, use_wr_level, 14); +register_bit!(reg_65, use_rd_dqs_gate_level, 15); +register_bit!(reg_65, use_rd_data_eye_level, 16); +register_bit!(reg_65, dis_calib_rst, 17); +register_bits!(reg_65, ctrl_slave_delay, u8, 18, 19); + // Controller operation mode status register!(mode_sts_reg, ModeStsReg, RO, u32);