#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const CCM_BASE: usize = 0x4445_0000;
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const DIRECT_OFFSET: usize = 0x00;
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const LPM_CUR_OFFSET: usize = 0x1c;
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const AUTHEN_OFFSET: usize = 0x30;
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const AUTHEN_CPULPM_EN: u32 = 1 << 2;
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const LPM_SETTING_ON: u32 = 0x4;
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const DIRECT_ON: u32 = 1 << 0;
pub const fn lpcg(name: &str) -> Option<u32> {
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
{
const TABLE: &[(&str, u32)] = &[
("LPIT1", 0x8a00),
("LPIT2", 0x8a40),
("MU1_MUA", 0x84c0),
("MU2_MUA", 0x84c0),
("MU1_MUB", 0x8500),
("MU2_MUB", 0x8500),
];
let mut i = 0;
while i < TABLE.len() {
if str_eq(TABLE[i].0, name) {
return Some(TABLE[i].1);
}
i += 1;
}
None
}
#[cfg(not(all(feature = "mimx93", not(feature = "mimx95"))))]
{
let _ = name;
None
}
}
pub fn ungate(offset: Option<u32>) {
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
if let Some(offset) = offset {
let gate = CCM_BASE + offset as usize;
unsafe {
let authen = ((gate + AUTHEN_OFFSET) as *const u32).read_volatile();
if authen & AUTHEN_CPULPM_EN != 0 {
((gate + LPM_CUR_OFFSET) as *mut u32).write_volatile(LPM_SETTING_ON);
} else {
let direct = (gate + DIRECT_OFFSET) as *mut u32;
direct.write_volatile(direct.read_volatile() | DIRECT_ON);
}
}
core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
#[cfg(target_arch = "arm")]
unsafe {
core::arch::asm!("dsb sy", options(nostack, preserves_flags));
}
}
#[cfg(not(all(feature = "mimx93", not(feature = "mimx95"))))]
let _ = offset;
}
#[cfg(all(feature = "mimx93", not(feature = "mimx95")))]
const fn str_eq(a: &str, b: &str) -> bool {
let (a, b) = (a.as_bytes(), b.as_bytes());
if a.len() != b.len() {
return false;
}
let mut i = 0;
while i < a.len() {
if a[i] != b[i] {
return false;
}
i += 1;
}
true
}
#[cfg(all(test, feature = "mimx93", not(feature = "mimx95")))]
mod tests {
use super::lpcg;
#[test]
fn bring_up_gates_match_the_vendor_table() {
assert_eq!(lpcg("LPIT1"), Some(0x8a00));
assert_eq!(lpcg("MU1_MUB"), Some(0x8500));
assert_eq!(lpcg("MU2_MUB"), Some(0x8500));
assert_eq!(lpcg("MU1_MUA"), Some(0x84c0));
}
#[test]
fn unlisted_peripherals_have_no_gate() {
assert_eq!(lpcg("LPIT"), None);
assert_eq!(lpcg("LPIT10"), None);
assert_eq!(lpcg("GPIO2"), None);
}
}