forked from M-Labs/zynq-rs
1
0
Fork 0

zynq::slcr: implement Display for PllStatus

This commit is contained in:
Astro 2019-10-25 20:38:10 +02:00
parent 838434cdec
commit a4d3360a70
3 changed files with 48 additions and 2 deletions

View File

@ -1,4 +1,4 @@
use crate::regs::RegisterR; use crate::regs::{RegisterR, RegisterRW};
use super::slcr; use super::slcr;
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
@ -89,4 +89,24 @@ impl CpuClocks {
}; };
pll / u32::from(uart_clk_ctrl.divisor()) pll / u32::from(uart_clk_ctrl.divisor())
} }
pub fn enable_ddr(target_clock: u32) {
let regs = slcr::RegisterBlock::new();
regs.ddr_pll_ctrl.modify(|_, w| w
.pll_pwrdwn(false)
.pll_reset(true)
.pll_bypass_force(true)
);
let fdiv = (target_clock / PS_CLK).max(127) as u16;
regs.ddr_pll_ctrl.modify(|_, w| w
.pll_pwrdwn(false)
.pll_reset(false)
.pll_fdiv(fdiv)
);
while ! regs.pll_status.read().ddr_pll_lock() {}
regs.ddr_pll_ctrl.modify(|_, w| w
.pll_bypass_force(false)
.pll_bypass_qual(false)
);
}
} }

View File

@ -28,6 +28,8 @@ impl DdrRam {
/// 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
fn clock_setup(clocks: &CpuClocks) { fn clock_setup(clocks: &CpuClocks) {
CpuClocks::enable_ddr(1_066_000_000);
let ddr3x_clk_divisor = ((clocks.ddr - 1) / DDR_FREQ + 1).min(255) as u8; let ddr3x_clk_divisor = ((clocks.ddr - 1) / DDR_FREQ + 1).min(255) as u8;
let ddr2x_clk_divisor = 3 * ddr3x_clk_divisor / 2; let ddr2x_clk_divisor = 3 * ddr3x_clk_divisor / 2;
@ -99,6 +101,7 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
slcr.ddriob_addr0.write(addr_config.clone()); slcr.ddriob_addr0.write(addr_config.clone());
slcr.ddriob_addr1.write(addr_config); slcr.ddriob_addr1.write(addr_config);
let data_config = slcr::DdriobConfig::zeroed() let data_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::VrefDifferential) .inp_type(slcr::DdriobInputType::VrefDifferential)
.term_en(true) .term_en(true)
@ -106,6 +109,7 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
slcr.ddriob_data0.write(data_config.clone()); slcr.ddriob_data0.write(data_config.clone());
slcr.ddriob_data1.write(data_config); slcr.ddriob_data1.write(data_config);
let diff_config = slcr::DdriobConfig::zeroed() let diff_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::Differential) .inp_type(slcr::DdriobInputType::Differential)
.term_en(true) .term_en(true)
@ -113,6 +117,7 @@ impl DdrRam {
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
slcr.ddriob_diff0.write(diff_config.clone()); slcr.ddriob_diff0.write(diff_config.clone());
slcr.ddriob_diff1.write(diff_config); slcr.ddriob_diff1.write(diff_config);
slcr.ddriob_clock.write( slcr.ddriob_clock.write(
slcr::DdriobConfig::zeroed() slcr::DdriobConfig::zeroed()
.output_en(slcr::DdriobOutputEn::Obuf) .output_en(slcr::DdriobOutputEn::Obuf)

View File

@ -68,7 +68,7 @@ pub struct RegisterBlock {
pub arm_pll_ctrl: PllCtrl, pub arm_pll_ctrl: PllCtrl,
pub ddr_pll_ctrl: PllCtrl, pub ddr_pll_ctrl: PllCtrl,
pub io_pll_ctrl: PllCtrl, pub io_pll_ctrl: PllCtrl,
pub pll_status: RO<u32>, pub pll_status: PllStatus,
pub arm_pll_cfg: PllCfg, pub arm_pll_cfg: PllCfg,
pub ddr_pll_cfg: PllCfg, pub ddr_pll_cfg: PllCfg,
pub io_pll_cfg: PllCfg, pub io_pll_cfg: PllCfg,
@ -293,6 +293,27 @@ register_bit!(pll_ctrl, pll_bypass_qual, 3);
register_bit!(pll_ctrl, pll_pwrdwn, 1); register_bit!(pll_ctrl, pll_pwrdwn, 1);
register_bit!(pll_ctrl, pll_reset, 0); register_bit!(pll_ctrl, pll_reset, 0);
register!(pll_status, PllStatus, RO, u32);
register_bit!(pll_status, arm_pll_lock, 0);
register_bit!(pll_status, ddr_pll_lock, 1);
register_bit!(pll_status, io_pll_lock, 2);
register_bit!(pll_status, arm_pll_stable, 3);
register_bit!(pll_status, ddr_pll_stable, 4);
register_bit!(pll_status, io_pll_stable, 5);
impl core::fmt::Display for pll_status::Read {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
write!(fmt, "ARM: {}/{} DDR: {}/{} IO: {}/{}",
if self.arm_pll_lock() { "locked" } else { "NOT locked" },
if self.arm_pll_stable() { "stable" } else { "UNSTABLE" },
if self.ddr_pll_lock() { "locked" } else { "NOT locked" },
if self.ddr_pll_stable() { "stable" } else { "UNSTABLE" },
if self.io_pll_lock() { "locked" } else { "NOT locked" },
if self.io_pll_stable() { "stable" } else { "UNSTABLE" },
)
}
}
register!(pll_cfg, PllCfg, RW, u32); register!(pll_cfg, PllCfg, RW, u32);
register_bits!(pll_cfg, pll_res, u8, 4, 7); register_bits!(pll_cfg, pll_res, u8, 4, 7);
register_bits!(pll_cfg, pll_cp, u8, 8, 11); register_bits!(pll_cfg, pll_cp, u8, 8, 11);