forked from M-Labs/artiq-zynq
Set fclk0 for ebaz4205
This commit is contained in:
parent
9ce3aadb15
commit
7bb74f83ee
|
@ -15,6 +15,8 @@ use libconfig::Config;
|
||||||
#[cfg(not(feature = "target_ebaz4205"))]
|
#[cfg(not(feature = "target_ebaz4205"))]
|
||||||
use log::info;
|
use log::info;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
#[cfg(feature = "target_ebaz4205")]
|
||||||
|
use {libboard_zynq::slcr, libregister::RegisterRW};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -410,6 +412,55 @@ fn get_si549_setting(clk: RtioClock) -> si549::FrequencySetting {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "target_ebaz4205")]
|
||||||
|
fn set_fclk0_freq(clk: RtioClock, cfg: &Config) {
|
||||||
|
let io_pll_freq: u32 = 1_000_000_000; // Hardcoded in zynq-rs
|
||||||
|
let mut target_freq = 0;
|
||||||
|
|
||||||
|
match clk {
|
||||||
|
RtioClock::Int_100 => {
|
||||||
|
target_freq = 100_000_000;
|
||||||
|
}
|
||||||
|
RtioClock::Int_125 => {
|
||||||
|
target_freq = 125_000_000;
|
||||||
|
}
|
||||||
|
RtioClock::Int_150 => {
|
||||||
|
target_freq = 150_000_000;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
let mut divisor0 = 1u8; // Start with divisor0 at 1
|
||||||
|
let mut divisor1 = 1u8; // Default value for divisor1
|
||||||
|
|
||||||
|
// Calculate the smallest valid divisor0 and divisor1 pair
|
||||||
|
while divisor0 < 64 && io_pll_freq / u32::from(divisor0) > target_freq {
|
||||||
|
divisor0 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If divisor0 alone isn't enough, adjust divisor1 as well
|
||||||
|
if io_pll_freq / (u32::from(divisor0) * u32::from(divisor1)) > target_freq {
|
||||||
|
divisor1 += 1;
|
||||||
|
divisor0 = 1;
|
||||||
|
|
||||||
|
while divisor1 < 64 && io_pll_freq / (u32::from(divisor0) * u32::from(divisor1)) > target_freq {
|
||||||
|
divisor1 += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the calculated divisors achieve the target frequency
|
||||||
|
if io_pll_freq / (u32::from(divisor0) * u32::from(divisor1)) == target_freq {
|
||||||
|
slcr::RegisterBlock::unlocked(|slcr| {
|
||||||
|
slcr.fpga0_clk_ctrl
|
||||||
|
.modify(|_, w| w.divisor0(divisor0).divisor1(divisor1));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Could not set fclk0 for target frequency of '{:?}' with available divisors",
|
||||||
|
target_freq
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||||
let clk = get_rtio_clock_cfg(cfg);
|
let clk = get_rtio_clock_cfg(cfg);
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
|
@ -436,6 +487,17 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) {
|
||||||
#[cfg(not(any(has_drtio, feature = "target_ebaz4205")))]
|
#[cfg(not(any(has_drtio, feature = "target_ebaz4205")))]
|
||||||
init_rtio(timer);
|
init_rtio(timer);
|
||||||
|
|
||||||
|
#[cfg(feature = "target_ebaz4205")]
|
||||||
|
{
|
||||||
|
// Set FPGA0_FCLK
|
||||||
|
match clk {
|
||||||
|
RtioClock::Int_100 | RtioClock::Int_125 | RtioClock::Int_150 => {
|
||||||
|
set_fclk0_freq(clk, cfg);
|
||||||
|
}
|
||||||
|
_ => {} // Not set for external clocks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(all(has_si549, has_wrpll))]
|
#[cfg(all(has_si549, has_wrpll))]
|
||||||
{
|
{
|
||||||
// SYS CLK switch will reset CSRs that are used by WRPLL
|
// SYS CLK switch will reset CSRs that are used by WRPLL
|
||||||
|
|
Loading…
Reference in New Issue