Skip to content

Commit

Permalink
ccu: split FactorN into PeriFactorN and AxiFactorN according to D1 ma…
Browse files Browse the repository at this point in the history
…nual

Signed-off-by: Zhouqi Jiang <[email protected]>
  • Loading branch information
luojia65 committed Nov 9, 2024
1 parent 75fd1a8 commit 288d829
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 65 deletions.
110 changes: 58 additions & 52 deletions allwinner-hal/src/ccu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
mod divide;

pub(crate) use divide::calculate_best_factors_nm;
pub use divide::{FactorN, FactorP};
pub use divide::{AxiFactorN, FactorP, PeriFactorN};

use crate::ccu;
use embedded_time::rate::Hertz;
Expand Down Expand Up @@ -471,12 +471,17 @@ impl CpuAxiConfig {
}
/// Get AXI CPU clock divide factor N.
#[inline]
pub const fn factor_n(self) -> u8 {
((self.0 & Self::FACTOR_N) >> 8) as u8
pub const fn factor_n(self) -> AxiFactorN {
match (self.0 & Self::FACTOR_N) >> 8 {
0x1 => AxiFactorN::N2,
0x2 => AxiFactorN::N3,
0x3 => AxiFactorN::N4,
_ => unreachable!(),
}
}
/// Set AXI CPU clock divide factor N.
#[inline]
pub const fn set_factor_n(self, val: u8) -> Self {
pub const fn set_factor_n(self, val: AxiFactorN) -> Self {
Self((self.0 & !Self::FACTOR_N) | ((val as u32) << 8))
}
/// Get AXI CPU clock divide factor M.
Expand Down Expand Up @@ -573,18 +578,18 @@ impl DramClock {
}
/// Get factor n.
#[inline]
pub const fn factor_n(self) -> FactorN {
pub const fn factor_n(self) -> PeriFactorN {
match ((self.0 & Self::DRAM_N) >> 8) as u8 {
0x0 => FactorN::N1,
0x1 => FactorN::N2,
0x2 => FactorN::N4,
0x3 => FactorN::N8,
0x0 => PeriFactorN::N1,
0x1 => PeriFactorN::N2,
0x2 => PeriFactorN::N4,
0x3 => PeriFactorN::N8,
_ => unreachable!(),
}
}
/// Set factor n.
#[inline]
pub const fn set_factor_n(self, val: FactorN) -> Self {
pub const fn set_factor_n(self, val: PeriFactorN) -> Self {
Self((self.0 & !Self::DRAM_N) | ((val as u32) << 8))
}
/// Get factor m (from 0 to 3).
Expand Down Expand Up @@ -693,23 +698,23 @@ impl SpiClock {
}
/// Get SPI clock divide factor N.
#[inline]
pub const fn factor_n(self) -> FactorN {
pub const fn factor_n(self) -> PeriFactorN {
match (self.0 & Self::FACTOR_N) >> 8 {
0 => FactorN::N1,
1 => FactorN::N2,
2 => FactorN::N4,
3 => FactorN::N8,
0 => PeriFactorN::N1,
1 => PeriFactorN::N2,
2 => PeriFactorN::N4,
3 => PeriFactorN::N8,
_ => unreachable!(),
}
}
/// Set SPI clock divide factor N.
#[inline]
pub const fn set_factor_n(self, val: FactorN) -> Self {
pub const fn set_factor_n(self, val: PeriFactorN) -> Self {
let val = match val {
FactorN::N1 => 0,
FactorN::N2 => 1,
FactorN::N4 => 2,
FactorN::N8 => 3,
PeriFactorN::N1 => 0,
PeriFactorN::N2 => 1,
PeriFactorN::N4 => 2,
PeriFactorN::N8 => 3,
};
Self((self.0 & !Self::FACTOR_N) | (val << 8))
}
Expand Down Expand Up @@ -805,23 +810,23 @@ impl SmhcClock {
}
/// Get SMHC clock divide factor N.
#[inline]
pub const fn factor_n(self) -> FactorN {
pub const fn factor_n(self) -> PeriFactorN {
match (self.0 & Self::FACTOR_N) >> 8 {
0 => FactorN::N1,
1 => FactorN::N2,
2 => FactorN::N4,
3 => FactorN::N8,
0 => PeriFactorN::N1,
1 => PeriFactorN::N2,
2 => PeriFactorN::N4,
3 => PeriFactorN::N8,
_ => unreachable!(),
}
}
/// Set SMHC clock divide factor N.
#[inline]
pub const fn set_factor_n(self, val: FactorN) -> Self {
pub const fn set_factor_n(self, val: PeriFactorN) -> Self {
let val = match val {
FactorN::N1 => 0,
FactorN::N2 => 1,
FactorN::N4 => 2,
FactorN::N8 => 3,
PeriFactorN::N1 => 0,
PeriFactorN::N2 => 1,
PeriFactorN::N4 => 2,
PeriFactorN::N8 => 3,
};
Self((self.0 & !Self::FACTOR_N) | (val << 8))
}
Expand Down Expand Up @@ -939,15 +944,15 @@ pub trait ClockConfig {
ccu: &ccu::RegisterBlock,
source: Self::Source,
factor_m: u8,
factor_n: FactorN,
factor_n: PeriFactorN,
);
/// Reconfigure peripheral clock by applying clock parameters while asserting reset.
#[inline]
unsafe fn reconfigure(
ccu: &ccu::RegisterBlock,
source: Self::Source,
factor_m: u8,
factor_n: FactorN,
factor_n: PeriFactorN,
) where
Self: ClockGate,
{
Expand All @@ -964,7 +969,7 @@ pub trait ClockConfig {
after_configure: G,
) where
Self: ClockGate,
F: FnOnce(&ccu::RegisterBlock) -> (Self::Source, u8, FactorN),
F: FnOnce(&ccu::RegisterBlock) -> (Self::Source, u8, PeriFactorN),
G: FnOnce(&ccu::RegisterBlock),
{
let _ = dependency; // does not use value, the type T is used instead
Expand Down Expand Up @@ -1022,7 +1027,7 @@ impl ClockConfig for DRAM {
ccu: &ccu::RegisterBlock,
source: Self::Source,
factor_m: u8,
factor_n: FactorN,
factor_n: PeriFactorN,
) {
let dram_clk = ccu.dram_clock.read();
ccu.dram_clock.write(
Expand Down Expand Up @@ -1129,7 +1134,7 @@ impl<const I: usize> ClockConfig for SPI<I> {
ccu: &ccu::RegisterBlock,
source: Self::Source,
factor_m: u8,
factor_n: FactorN,
factor_n: PeriFactorN,
) {
let spi_clk = ccu.spi_clk[I].read();
ccu.spi_clk[I].write(
Expand All @@ -1144,8 +1149,9 @@ impl<const I: usize> ClockConfig for SPI<I> {
#[cfg(test)]
mod tests {
use super::{
CpuAxiConfig, CpuClockSource, DramBusGating, DramClock, DramClockSource, FactorN, FactorP,
MbusClock, PllCpuControl, PllDdrControl, PllPeri0Control, RegisterBlock,
AxiFactorN, CpuAxiConfig, CpuClockSource, DramBusGating, DramClock, DramClockSource,
FactorP, MbusClock, PeriFactorN, PllCpuControl, PllDdrControl, PllPeri0Control,
RegisterBlock,
};
use memoffset::offset_of;
#[test]
Expand Down Expand Up @@ -1428,20 +1434,20 @@ mod tests {
assert_eq!(val.0, 0x00000000);
assert_eq!(val.factor_p(), FactorP::P1);

val = val.set_factor_n(0x03);
val = val.set_factor_n(AxiFactorN::N4);
assert_eq!(val.0, 0x00000300);
assert_eq!(val.factor_n(), 0x03);
assert_eq!(val.factor_n(), AxiFactorN::N4);

val = val.set_factor_n(0x0);
assert_eq!(val.0, 0x00000000);
assert_eq!(val.factor_n(), 0x0);
val = val.set_factor_n(AxiFactorN::N2);
assert_eq!(val.0, 0x00000100);
assert_eq!(val.factor_n(), AxiFactorN::N2);

val = val.set_factor_m(0x03);
assert_eq!(val.0, 0x00000003);
assert_eq!(val.0, 0x00000103);
assert_eq!(val.factor_m(), 0x03);

val = val.set_factor_m(0x0);
assert_eq!(val.0, 0x00000000);
assert_eq!(val.0, 0x00000100);
assert_eq!(val.factor_m(), 0x0);
}

Expand Down Expand Up @@ -1496,10 +1502,10 @@ mod tests {

for i in 0..4 as u8 {
let fn_tmp = match i {
0x0 => FactorN::N1,
0x1 => FactorN::N2,
0x2 => FactorN::N4,
0x3 => FactorN::N8,
0x0 => PeriFactorN::N1,
0x1 => PeriFactorN::N2,
0x2 => PeriFactorN::N4,
0x3 => PeriFactorN::N8,
_ => unreachable!(),
};

Expand Down Expand Up @@ -1600,10 +1606,10 @@ mod tests {

for i in 0..4 as u8 {
let fn_tmp = match i {
0x0 => FactorN::N1,
0x1 => FactorN::N2,
0x2 => FactorN::N4,
0x3 => FactorN::N8,
0x0 => PeriFactorN::N1,
0x1 => PeriFactorN::N2,
0x2 => PeriFactorN::N4,
0x3 => PeriFactorN::N8,
_ => unreachable!(),
};

Expand Down
34 changes: 23 additions & 11 deletions allwinner-hal/src/ccu/divide.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
/// Clock divide factor N.
/// Peripheral clock divide factor N.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum FactorN {
pub enum PeriFactorN {
/// Don't divide.
N1,
N1 = 0,
/// Divide frequency by 2.
N2,
N2 = 1,
/// Divide frequency by 4.
N4,
N4 = 2,
/// Divide frequency by 8.
N8,
N8 = 3,
}

/// CPU and RISC-V coprocessor AXI clock divide factor N.
// TODO: use this on CpuAxiConfig
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AxiFactorN {
/// Divide frequency by 2.
N2 = 1,
/// Divide frequency by 3.
N3 = 2,
/// Divide frequency by 4.
N4 = 3,
}

/// Clock divide factor P.
Expand All @@ -24,7 +36,7 @@ pub enum FactorP {

/// Calculate the best N-M divide factors from `f_src` and `f_dst` parameters.
#[inline]
pub fn calculate_best_factors_nm(f_src: u32, f_dst: u32) -> (FactorN, u8) {
pub fn calculate_best_factors_nm(f_src: u32, f_dst: u32) -> (PeriFactorN, u8) {
let mut err = f_src;
let (mut best_n, mut best_m) = (0, 0);
for m in 1u8..=16 {
Expand All @@ -37,10 +49,10 @@ pub fn calculate_best_factors_nm(f_src: u32, f_dst: u32) -> (FactorN, u8) {
}
}
let factor_n = match best_n {
1 => FactorN::N1,
2 => FactorN::N2,
4 => FactorN::N4,
8 => FactorN::N8,
1 => PeriFactorN::N1,
2 => PeriFactorN::N2,
4 => PeriFactorN::N4,
8 => PeriFactorN::N8,
_ => unreachable!(),
};
let factor_m = best_m - 1;
Expand Down
4 changes: 2 additions & 2 deletions allwinner-rt/src/mctl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::soc::d1::{CCU, PHY};
use allwinner_hal::ccu::{DramClockSource, FactorN};
use allwinner_hal::ccu::{DramClockSource, PeriFactorN};
use core::ptr::{read_volatile, write_volatile};

// for verbose prints
Expand Down Expand Up @@ -435,7 +435,7 @@ fn ccm_set_pll_ddr_clk(
ccu.dram_clock.modify(|val| {
val.set_clock_source(DramClockSource::PllDdr)
.set_factor_m(0)
.set_factor_n(FactorN::N1)
.set_factor_n(PeriFactorN::N1)
.unmask_clock()
});
}
Expand Down

0 comments on commit 288d829

Please sign in to comment.