use volatile_register::{RO, WO, RW}; use crate::{register, register_bit, register_bits, register_bits_typed}; #[repr(u8)] pub enum DataBusWidth { Width32bit = 0b00, Width16bit = 0b01, } #[repr(C)] pub struct RegisterBlock { pub ddrc_ctrl: DdrcCtrl, 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, } impl RegisterBlock { pub unsafe fn new() -> &'static mut Self { &mut *(0xF8006000 as *mut _) } } register!(ddrc_ctrl, DdrcCtrl, RW, u32); register_bit!(ddrc_ctrl, /// `false` resets controller, `true` continues soft_rstb, 0); register_bit!(ddrc_ctrl, powerdown_en, 1); register_bits_typed!(ddrc_ctrl, data_bus_width, u8, DataBusWidth, 2, 3); // (ddrc_ctrl) ...