master WRPLL: add mmcm setup, reset and mmcmsetting

gw: allow cpu mmcm reset
This commit is contained in:
morgan 2024-02-29 16:22:11 +08:00
parent 0c8ec61527
commit 7300ecce25
2 changed files with 51 additions and 5 deletions

View File

@ -137,7 +137,7 @@ class SMA_PLL(Module, AutoCSR):
self.clock_domains.cd_ref = ClockDomain() self.clock_domains.cd_ref = ClockDomain()
self.mmcm_locked = CSRStatus() self.mmcm_locked = CSRStatus()
self.mmcm_reset = CSRStorage() #TODO for i_RST self.mmcm_reset = CSRStorage()
self.drp_addr = CSRStorage(7) self.drp_addr = CSRStorage(7)
self.drp_in = CSRStorage(16) self.drp_in = CSRStorage(16)
@ -154,10 +154,10 @@ class SMA_PLL(Module, AutoCSR):
Instance("MMCME2_ADV", Instance("MMCME2_ADV",
p_BANDWIDTH="LOW", # lower jitter p_BANDWIDTH="LOW", # lower jitter
o_LOCKED=self.mmcm_locked.status, o_LOCKED=self.mmcm_locked.status,
i_RST=self.mmcm_reset.storage,
p_CLKIN1_PERIOD=period, p_CLKIN1_PERIOD=period,
i_CLKIN1=ClockSignal("sys"), i_CLKIN1=ClockSignal("sys"),
i_RST=ResetSignal("sys"),
i_CLKINSEL=1, # 1=CLKIN1 0=CLKIN2 i_CLKINSEL=1, # 1=CLKIN1 0=CLKIN2
# VCO @ 1Ghz # VCO @ 1Ghz
@ -184,4 +184,3 @@ class SMA_PLL(Module, AutoCSR):
# debug output # debug output
Instance("OBUFDS", i_I=self.cd_ref.clk, o_O=sma_clkin.p, o_OB=sma_clkin.n) Instance("OBUFDS", i_I=self.cd_ref.clk, o_O=sma_clkin.p, o_OB=sma_clkin.n)
] ]

View File

@ -556,6 +556,20 @@ pub mod sma_pll {
use super::*; use super::*;
pub struct MmcmSetting {
pub clkout0_reg1: u16, //0x08
pub clkout0_reg2: u16, //0x09
pub clkfbout_reg1: u16, //0x14
pub clkfbout_reg2: u16, //0x15
pub div_reg: u16, //0x16
pub lock_reg1: u16, //0x18
pub lock_reg2: u16, //0x19
pub lock_reg3: u16, //0x1A
pub power_reg: u16, //0x28
pub filt_reg1: u16, //0x4E
pub filt_reg2: u16, //0x4F
}
fn one_clock_cycle(timer: &mut GlobalTimer) { fn one_clock_cycle(timer: &mut GlobalTimer) {
unsafe { unsafe {
csr::sma_pll::drp_clk_write(1); csr::sma_pll::drp_clk_write(1);
@ -600,7 +614,6 @@ pub mod sma_pll {
} }
pub fn read(timer: &mut GlobalTimer, address: u8) -> u16 { pub fn read(timer: &mut GlobalTimer, address: u8) -> u16 {
// Based on "DRP State Machine" from XAPP888
set_addr(address); set_addr(address);
set_enable(true); set_enable(true);
// Set DADDR on the MMCM and assert DEN for one clock cycle // Set DADDR on the MMCM and assert DEN for one clock cycle
@ -615,7 +628,6 @@ pub mod sma_pll {
} }
pub fn write(timer: &mut GlobalTimer, address: u8, value: u16) { pub fn write(timer: &mut GlobalTimer, address: u8, value: u16) {
// Based on "DRP State Machine" from XAPP888
set_addr(address); set_addr(address);
set_data(value); set_data(value);
set_write_enable(true); set_write_enable(true);
@ -630,6 +642,41 @@ pub mod sma_pll {
one_clock_cycle(timer); one_clock_cycle(timer);
} }
} }
pub fn reset(rst: bool) {
unsafe {
let val = if rst { 1 } else { 0 };
csr::sma_pll::mmcm_reset_write(val)
}
}
pub fn setup(timer: &mut GlobalTimer, settings: MmcmSetting) -> Result<(), &'static str> {
// Based on "DRP State Machine" from XAPP888
// hold reset HIGH during mmcm config
reset(true);
write(timer, 0x08, settings.clkout0_reg1);
write(timer, 0x09, settings.clkout0_reg2);
write(timer, 0x14, settings.clkfbout_reg1);
write(timer, 0x15, settings.clkfbout_reg2);
write(timer, 0x16, settings.div_reg);
write(timer, 0x18, settings.lock_reg1);
write(timer, 0x19, settings.lock_reg2);
write(timer, 0x1A, settings.lock_reg3);
write(timer, 0x28, settings.power_reg);
write(timer, 0x4E, settings.filt_reg1);
write(timer, 0x4F, settings.filt_reg2);
reset(false);
// wait for the mmcm to lock
timer.delay_us(100);
let locked = unsafe { csr::sma_pll::mmcm_locked_read() == 1 };
if !locked {
return Err("failed to generate 125Mhz ref clock from SMA CLKIN");
}
Ok(())
}
} }
pub fn setup(timer: &mut GlobalTimer) { pub fn setup(timer: &mut GlobalTimer) {