continue with FSBL
Some checks failed
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
Some checks failed
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled
This commit is contained in:
@@ -17,6 +17,7 @@ embedded-io = "0.6"
|
|||||||
embedded-hal = "1"
|
embedded-hal = "1"
|
||||||
fugit = "0.3"
|
fugit = "0.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
arbitrary-int = "1.3"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
@@ -2,15 +2,14 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
use arbitrary_int::u6;
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use cortex_ar::asm::nop;
|
use cortex_ar::asm::nop;
|
||||||
use log::error;
|
use log::error;
|
||||||
use zynq7000_hal::{
|
use zynq7000_hal::{
|
||||||
BootMode,
|
BootMode,
|
||||||
clocks::pll::{
|
clocks::pll::{PllConfig, configure_arm_pll, configure_ddr_pll, configure_io_pll},
|
||||||
PllConfig, PllConfigCtorError, configure_arm_pll, configure_ddr_pll, configure_io_pll,
|
ddr::configure_dci,
|
||||||
},
|
|
||||||
gpio::{Output, PinState, mio},
|
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
};
|
};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
@@ -20,14 +19,15 @@ const PS_CLK: Hertz = Hertz::from_raw(33_333_333);
|
|||||||
|
|
||||||
/// 1600 MHz.
|
/// 1600 MHz.
|
||||||
const ARM_CLK: Hertz = Hertz::from_raw(1_600_000_000);
|
const ARM_CLK: Hertz = Hertz::from_raw(1_600_000_000);
|
||||||
/// 1067 MHz.
|
|
||||||
//const DDR_CLK: Hertz = Hertz::from_raw(1_067_000_000);
|
|
||||||
/// 1000 MHz.
|
/// 1000 MHz.
|
||||||
const IO_CLK: Hertz = Hertz::from_raw(1_000_000_000);
|
const IO_CLK: Hertz = Hertz::from_raw(1_000_000_000);
|
||||||
|
|
||||||
/// DDR frequency for the MT41K128M16JT-125 device.
|
/// DDR frequency for the MT41K128M16JT-125 device.
|
||||||
const DDR_FREQUENCY: Hertz = Hertz::from_raw(533_333_333);
|
const DDR_FREQUENCY: Hertz = Hertz::from_raw(533_333_333);
|
||||||
|
|
||||||
|
/// 1067 MHz.
|
||||||
|
const DDR_CLK: Hertz = Hertz::from_raw(2 * DDR_FREQUENCY.raw());
|
||||||
|
|
||||||
/// Entry point (not called like a normal main function)
|
/// Entry point (not called like a normal main function)
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
||||||
@@ -42,10 +42,26 @@ pub fn main() -> ! {
|
|||||||
let boot_mode = BootMode::new_from_regs();
|
let boot_mode = BootMode::new_from_regs();
|
||||||
// The unwraps are okay here, the provided clock frequencies are standard values also used
|
// The unwraps are okay here, the provided clock frequencies are standard values also used
|
||||||
// by other Xilinx tools.
|
// by other Xilinx tools.
|
||||||
configure_arm_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, ARM_CLK).unwrap());
|
configure_arm_pll(
|
||||||
configure_io_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, IO_CLK).unwrap());
|
boot_mode,
|
||||||
|
PllConfig::new_from_target_clock(PS_CLK, ARM_CLK).unwrap(),
|
||||||
|
);
|
||||||
|
configure_io_pll(
|
||||||
|
boot_mode,
|
||||||
|
PllConfig::new_from_target_clock(PS_CLK, IO_CLK).unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
configure_ddr_pll(boot_mode, PllConfig::new_from_target_clock(PS_CLK, 2 * DDR_FREQUENCY).unwrap());
|
// Set the DDR PLL output frequency to an even multiple of the operating frequency,
|
||||||
|
// as recommended by the DDR documentation.
|
||||||
|
configure_ddr_pll(
|
||||||
|
boot_mode,
|
||||||
|
PllConfig::new_from_target_clock(PS_CLK, DDR_CLK).unwrap(),
|
||||||
|
);
|
||||||
|
// Safety: Only done once here during start-up.
|
||||||
|
let ddr_clk = unsafe {
|
||||||
|
zynq7000_hal::clocks::DdrClocks::new_with_2x_3x_init(DDR_CLK, u6::new(2), u6::new(3))
|
||||||
|
};
|
||||||
|
configure_dci(&ddr_clk);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
cortex_ar::asm::nop();
|
cortex_ar::asm::nop();
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
//! Clock module.
|
//! Clock module.
|
||||||
use arbitrary_int::Number;
|
use arbitrary_int::{Number, u6};
|
||||||
|
|
||||||
pub mod pll;
|
pub mod pll;
|
||||||
|
|
||||||
@@ -47,21 +47,67 @@ impl ArmClocks {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DdrClocks {
|
pub struct DdrClocks {
|
||||||
|
/// DDR reference clock generated by the DDR PLL.
|
||||||
ref_clk: Hertz,
|
ref_clk: Hertz,
|
||||||
ddr_3x_clk: Hertz,
|
ddr_3x_clk: Hertz,
|
||||||
ddr_2x_clk: Hertz,
|
ddr_2x_clk: Hertz,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DdrClocks {
|
impl DdrClocks {
|
||||||
|
/// Update the DDR 3x and 2x clocks in the SLCR.
|
||||||
|
///
|
||||||
|
/// Usually, the DDR PLL output clock will be set to an even multiple of the DDR operating
|
||||||
|
/// frequency. In that case, the multiplicator should be used as the DDR 3x clock divisor.
|
||||||
|
/// The DDR 2x clock divisor should be set so that the resulting clock is 2/3 of the DDR
|
||||||
|
/// operating frequency.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This should only be called once during start-up. It accesses the SLCR register.
|
||||||
|
pub unsafe fn configure_2x_3x_clk(ddr_3x_div: u6, ddr_2x_div: u6) {
|
||||||
|
// Safety: The DDR clock structure is a singleton.
|
||||||
|
unsafe {
|
||||||
|
crate::slcr::Slcr::with(|slcr| {
|
||||||
|
slcr.clk_ctrl().modify_ddr_clk_ctrl(|mut val| {
|
||||||
|
val.set_div_3x_clk(ddr_3x_div);
|
||||||
|
val.set_div_2x_clk(ddr_2x_div);
|
||||||
|
val
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the DDR 3x and 2x clocks in the SLCR and creates a DDR clock information structure.
|
||||||
|
///
|
||||||
|
/// Usually, the DDR PLL output clock will be set to an even multiple of the DDR operating
|
||||||
|
/// frequency. In that case, the multiplicator should be used as the DDR 3x clock divisor.
|
||||||
|
/// The DDR 2x clock divisor should be set so that the resulting clock is 2/3 of the DDR
|
||||||
|
/// operating frequency.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This should only be called once during start-up. It accesses the SLCR register.
|
||||||
|
pub unsafe fn new_with_2x_3x_init(ref_clk: Hertz, ddr_3x_div: u6, ddr_2x_div: u6) -> Self {
|
||||||
|
unsafe { Self::configure_2x_3x_clk(ddr_3x_div, ddr_2x_div) };
|
||||||
|
Self {
|
||||||
|
ref_clk,
|
||||||
|
ddr_3x_clk: ref_clk / ddr_3x_div.as_u32(),
|
||||||
|
ddr_2x_clk: ref_clk / ddr_2x_div.as_u32(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reference clock provided by DDR PLL which is used to calculate all other clock frequencies.
|
/// Reference clock provided by DDR PLL which is used to calculate all other clock frequencies.
|
||||||
pub const fn ref_clk(&self) -> Hertz {
|
pub const fn ref_clk(&self) -> Hertz {
|
||||||
self.ref_clk
|
self.ref_clk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// DDR 3x clock which is used by the DRAM and must be set to the operating frequency.
|
||||||
pub fn ddr_3x_clk(&self) -> Hertz {
|
pub fn ddr_3x_clk(&self) -> Hertz {
|
||||||
self.ddr_3x_clk
|
self.ddr_3x_clk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// DDR 2x clock is used by the interconnect and is typically set to 2/3 of the operating
|
||||||
|
/// frequency.
|
||||||
pub fn ddr_2x_clk(&self) -> Hertz {
|
pub fn ddr_2x_clk(&self) -> Hertz {
|
||||||
self.ddr_2x_clk
|
self.ddr_2x_clk
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
use arbitrary_int::u6;
|
||||||
|
use zynq7000::slcr::clocks::DciClkCtrl;
|
||||||
|
|
||||||
|
use crate::{clocks::DdrClocks, time::Hertz};
|
||||||
|
|
||||||
|
const DCI_MAX_FREQ: Hertz = Hertz::from_raw(10_000_000);
|
||||||
|
|
||||||
|
pub fn calculate_dci_divisors(ddr_clk: Hertz) -> (u6, u6) {
|
||||||
|
let target_div = ddr_clk.raw().div_ceil(DCI_MAX_FREQ.raw());
|
||||||
|
|
||||||
|
let mut best = None;
|
||||||
|
let mut best_error = 0;
|
||||||
|
for divisor0 in 1..63 {
|
||||||
|
for divisor1 in 1..63 {
|
||||||
|
let current_div = (divisor0 as u32) * (divisor1 as u32);
|
||||||
|
let error = current_div.abs_diff(target_div);
|
||||||
|
if best.is_none() || best_error > error {
|
||||||
|
best = Some((divisor0, divisor1));
|
||||||
|
best_error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
best.map(|(div0, div1)| (u6::new(div0), u6::new(div1)))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn configure_dci(ddr_clk: &DdrClocks) {
|
||||||
|
let (divisor0, divisor1) = calculate_dci_divisors(ddr_clk.ref_clk());
|
||||||
|
// Safety: Only done once here during start-up.
|
||||||
|
unsafe {
|
||||||
|
crate::Slcr::with(|slcr| {
|
||||||
|
slcr.clk_ctrl().write_dci_clk_ctrl(
|
||||||
|
DciClkCtrl::builder()
|
||||||
|
.with_divisor_1(divisor1)
|
||||||
|
.with_divisor_0(divisor0)
|
||||||
|
.with_clk_act(true)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -14,6 +14,7 @@ use zynq7000::slcr::{BootModeRegister, BootPllConfig, LevelShifterReg};
|
|||||||
|
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod clocks;
|
pub mod clocks;
|
||||||
|
pub mod ddr;
|
||||||
pub mod eth;
|
pub mod eth;
|
||||||
pub mod gic;
|
pub mod gic;
|
||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use arbitrary_int::{u11, u12, u3, u4, u5, u6, u7};
|
use arbitrary_int::{u2, u3, u4, u5, u6, u7, u11, u12};
|
||||||
|
|
||||||
pub const DDRC_BASE_ADDR: usize = 0xF800_6000;
|
pub const DDRC_BASE_ADDR: usize = 0xF800_6000;
|
||||||
|
|
||||||
@@ -39,6 +39,9 @@ pub struct DdrcControl {
|
|||||||
pub struct TwoRankConfig {
|
pub struct TwoRankConfig {
|
||||||
#[bits(14..=18, rw)]
|
#[bits(14..=18, rw)]
|
||||||
addrmap_cs_bit0: u5,
|
addrmap_cs_bit0: u5,
|
||||||
|
/// Reserved register, but for some reason, Xilinx tooling writes a 1 here?
|
||||||
|
#[bits(12..=13, rw)]
|
||||||
|
ddrc_active_ranks: u2,
|
||||||
/// tREFI - Average time between refreshes, in multiples of 32 clocks.
|
/// tREFI - Average time between refreshes, in multiples of 32 clocks.
|
||||||
#[bits(0..=11, rw)]
|
#[bits(0..=11, rw)]
|
||||||
rfc_nom_x32: u12,
|
rfc_nom_x32: u12,
|
||||||
@@ -137,9 +140,38 @@ pub struct DramParamReg3 {
|
|||||||
#[bits(5..=7, rw)]
|
#[bits(5..=7, rw)]
|
||||||
t_rrd: u3,
|
t_rrd: u3,
|
||||||
#[bits(2..=4, rw)]
|
#[bits(2..=4, rw)]
|
||||||
t_ccd: u3
|
t_ccd: u3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
|
pub struct DramParamReg4 {
|
||||||
|
#[bit(27, rw)]
|
||||||
|
mr_rdata_valid: bool,
|
||||||
|
#[bit(26, rw)]
|
||||||
|
mr_type: bool,
|
||||||
|
#[bit(25, rw)]
|
||||||
|
mr_wr_busy: bool,
|
||||||
|
#[bits(9..=24, rw)]
|
||||||
|
mr_data: u16,
|
||||||
|
#[bits(7..=8, rw)]
|
||||||
|
mr_addr: u2,
|
||||||
|
#[bit(6, rw)]
|
||||||
|
mr_wr: bool,
|
||||||
|
#[bit(1, rw)]
|
||||||
|
prefer_write: bool,
|
||||||
|
#[bit(0, rw)]
|
||||||
|
enable_2t_timing_mode: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
|
pub struct DramInitParam {
|
||||||
|
#[bits(11..=13, rw)]
|
||||||
|
t_mrd: u3,
|
||||||
|
#[bits(7..=10, rw)]
|
||||||
|
pre_ocd_x32: u4,
|
||||||
|
#[bits(0..=6, rw)]
|
||||||
|
final_wait_x32: u7,
|
||||||
|
}
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DdrController {
|
pub struct DdrController {
|
||||||
@@ -149,13 +181,13 @@ pub struct DdrController {
|
|||||||
lpr_queue_ctrl: LprHprQueueControl,
|
lpr_queue_ctrl: LprHprQueueControl,
|
||||||
wr_reg: WriteQueueControl,
|
wr_reg: WriteQueueControl,
|
||||||
dram_param_reg0: DramParamReg0,
|
dram_param_reg0: DramParamReg0,
|
||||||
dram_param_reg1: u32,
|
dram_param_reg1: DramParamReg1,
|
||||||
dram_param_reg2: u32,
|
dram_param_reg2: DramParamReg2,
|
||||||
dram_param_reg3: u32,
|
dram_param_reg3: DramParamReg3,
|
||||||
dram_param_reg4: u32,
|
dram_param_reg4: DramParamReg4,
|
||||||
dram_init_param: u32,
|
dram_init_param: DramInitParam,
|
||||||
dram_emr_reg: u32,
|
dram_emr: u32,
|
||||||
dram_emr_mr_reg: u32,
|
dram_emr_mr: u32,
|
||||||
dram_burst8_rdwr: u32,
|
dram_burst8_rdwr: u32,
|
||||||
dram_disable_dq: u32,
|
dram_disable_dq: u32,
|
||||||
dram_addr_map_bank: u32,
|
dram_addr_map_bank: u32,
|
||||||
@@ -164,7 +196,8 @@ pub struct DdrController {
|
|||||||
dram_odt_reg: u32,
|
dram_odt_reg: u32,
|
||||||
phy_debug_reg: u32,
|
phy_debug_reg: u32,
|
||||||
phy_cmd_timeout_rddata_cpt: u32,
|
phy_cmd_timeout_rddata_cpt: u32,
|
||||||
mode_status_reg: u32,
|
#[mmio(PureRead)]
|
||||||
|
mode_status: u32,
|
||||||
dll_calib: u32,
|
dll_calib: u32,
|
||||||
odt_delay_hold: u32,
|
odt_delay_hold: u32,
|
||||||
ctrl_reg1: u32,
|
ctrl_reg1: u32,
|
||||||
@@ -186,16 +219,28 @@ pub struct DdrController {
|
|||||||
dfi_timing: u32,
|
dfi_timing: u32,
|
||||||
_reserved2: [u32; 0x2],
|
_reserved2: [u32; 0x2],
|
||||||
che_corr_control: u32,
|
che_corr_control: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_corr_ecc_log: u32,
|
che_corr_ecc_log: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_corr_ecc_addr: u32,
|
che_corr_ecc_addr: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_corr_ecc_data_31_0: u32,
|
che_corr_ecc_data_31_0: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_corr_ecc_data_63_32: u32,
|
che_corr_ecc_data_63_32: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_corr_ecc_data_71_64: u32,
|
che_corr_ecc_data_71_64: u32,
|
||||||
|
/// Clear on write, but the write is performed on another register.
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_uncorr_ecc_log: u32,
|
che_uncorr_ecc_log: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_uncorr_ecc_addr: u32,
|
che_uncorr_ecc_addr: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_uncorr_ecc_data_31_0: u32,
|
che_uncorr_ecc_data_31_0: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_uncorr_ecc_data_63_32: u32,
|
che_uncorr_ecc_data_63_32: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_uncorr_ecc_data_71_64: u32,
|
che_uncorr_ecc_data_71_64: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
che_ecc_stats: u32,
|
che_ecc_stats: u32,
|
||||||
ecc_scrub: u32,
|
ecc_scrub: u32,
|
||||||
che_ecc_corr_bit_mask_31_0: u32,
|
che_ecc_corr_bit_mask_31_0: u32,
|
||||||
@@ -221,44 +266,47 @@ pub struct DdrController {
|
|||||||
reg_64: u32,
|
reg_64: u32,
|
||||||
reg_65: u32,
|
reg_65: u32,
|
||||||
_reserved10: [u32; 3],
|
_reserved10: [u32; 3],
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg69_6a0: u32,
|
reg69_6a0: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg69_6a1: u32,
|
reg69_6a1: u32,
|
||||||
_reserved11: u32,
|
_reserved11: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg69_6d2: u32,
|
reg69_6d2: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg69_6d3: u32,
|
reg69_6d3: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg69_710: u32,
|
reg69_710: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg6e_711: u32,
|
reg6e_711: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg6e_712: u32,
|
reg6e_712: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
reg6e_713: u32,
|
reg6e_713: u32,
|
||||||
_reserved12: u32,
|
_reserved12: u32,
|
||||||
phy_dll_status_0: u32,
|
#[mmio(PureRead)]
|
||||||
phy_dll_status_1: u32,
|
phy_dll_status: [u32; 4],
|
||||||
phy_dll_status_2: u32,
|
|
||||||
phy_dll_status_3: u32,
|
|
||||||
_reserved13: u32,
|
_reserved13: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
dll_lock_status: u32,
|
dll_lock_status: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
phy_control_status: u32,
|
phy_control_status: u32,
|
||||||
|
#[mmio(PureRead)]
|
||||||
phy_control_status_2: u32,
|
phy_control_status_2: u32,
|
||||||
|
|
||||||
_reserved14: [u32; 0x5],
|
_reserved14: [u32; 0x5],
|
||||||
|
|
||||||
|
// DDRI registers.
|
||||||
|
#[mmio(PureRead)]
|
||||||
axi_id: u32,
|
axi_id: u32,
|
||||||
page_mask: u32,
|
page_mask: u32,
|
||||||
axi_priority_wr_port_0: u32,
|
axi_priority_wr_port: [u32; 4],
|
||||||
axi_priority_wr_port_1: u32,
|
axi_priority_rd_port: [u32; 4],
|
||||||
axi_priority_wr_port_2: u32,
|
|
||||||
axi_priority_wr_port_3: u32,
|
|
||||||
axi_priority_rd_port_0: u32,
|
|
||||||
axi_priority_rd_port_1: u32,
|
|
||||||
axi_priority_rd_port_2: u32,
|
|
||||||
axi_priority_rd_port_3: u32,
|
|
||||||
|
|
||||||
_reserved15: [u32; 0x1B],
|
_reserved15: [u32; 0x1B],
|
||||||
|
|
||||||
excl_access_cfg_0: u32,
|
excl_access_cfg: [u32; 4],
|
||||||
excl_access_cfg_1: u32,
|
#[mmio(PureRead)]
|
||||||
excl_access_cfg_2: u32,
|
|
||||||
excl_access_cfg_3: u32,
|
|
||||||
mode_reg_read: u32,
|
mode_reg_read: u32,
|
||||||
lpddr_ctrl_0: u32,
|
lpddr_ctrl_0: u32,
|
||||||
lpddr_ctrl_1: u32,
|
lpddr_ctrl_1: u32,
|
||||||
|
@@ -17,6 +17,7 @@ extern crate std;
|
|||||||
|
|
||||||
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
|
pub const MPCORE_BASE_ADDR: usize = 0xF8F0_0000;
|
||||||
|
|
||||||
|
pub mod ddrc;
|
||||||
pub mod eth;
|
pub mod eth;
|
||||||
pub mod gic;
|
pub mod gic;
|
||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
@@ -28,7 +29,6 @@ pub mod slcr;
|
|||||||
pub mod spi;
|
pub mod spi;
|
||||||
pub mod ttc;
|
pub mod ttc;
|
||||||
pub mod uart;
|
pub mod uart;
|
||||||
pub mod ddrc;
|
|
||||||
|
|
||||||
static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
@@ -169,7 +169,7 @@ pub struct DdrClkCtrl {
|
|||||||
ddr_3x_clk_act: bool,
|
ddr_3x_clk_act: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitbybit::bitfield(u32)]
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
pub struct DciClkCtrl {
|
pub struct DciClkCtrl {
|
||||||
/// Second cascade divider. Reset value: 0x1E
|
/// Second cascade divider. Reset value: 0x1E
|
||||||
#[bits(20..=25, rw)]
|
#[bits(20..=25, rw)]
|
||||||
|
Reference in New Issue
Block a user