clocks: split clock and reset operations

Some peripherals need to control clock without touching the reset.

Signed-off-by: Felipe Balbi <febalbi@microsoft.com>
This commit is contained in:
Felipe Balbi 2025-05-07 10:39:25 -07:00
parent 70e2c05205
commit 64ce271af5

View File

@ -1561,7 +1561,8 @@ pub(crate) unsafe fn init(config: ClockConfig) -> Result<(), ClockError> {
///Trait to expose perph clocks ///Trait to expose perph clocks
trait SealedSysconPeripheral { trait SealedSysconPeripheral {
fn enable_and_reset_perph_clock(); fn enable_perph_clock();
fn reset_perph();
fn disable_perph_clock(); fn disable_perph_clock();
} }
@ -1574,7 +1575,18 @@ pub trait SysconPeripheral: SealedSysconPeripheral + 'static {}
/// ///
/// Peripheral must not be in use. /// Peripheral must not be in use.
pub fn enable_and_reset<T: SysconPeripheral>() { pub fn enable_and_reset<T: SysconPeripheral>() {
T::enable_and_reset_perph_clock(); T::enable_perph_clock();
T::reset_perph();
}
/// Enables peripheral `T`.
pub fn enable<T: SysconPeripheral>() {
T::enable_perph_clock();
}
/// Reset peripheral `T`.
pub fn reset<T: SysconPeripheral>() {
T::reset_perph();
} }
/// Disables peripheral `T`. /// Disables peripheral `T`.
@ -1588,15 +1600,21 @@ pub fn disable<T: SysconPeripheral>() {
macro_rules! impl_perph_clk { macro_rules! impl_perph_clk {
($peripheral:ident, $clkctl:ident, $clkreg:ident, $rstctl:ident, $rstreg:ident, $bit:expr) => { ($peripheral:ident, $clkctl:ident, $clkreg:ident, $rstctl:ident, $rstreg:ident, $bit:expr) => {
impl SealedSysconPeripheral for crate::peripherals::$peripheral { impl SealedSysconPeripheral for crate::peripherals::$peripheral {
fn enable_and_reset_perph_clock() { fn enable_perph_clock() {
// SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1
let cc1 = unsafe { pac::$clkctl::steal() }; let cc1 = unsafe { pac::$clkctl::steal() };
let rc1 = unsafe { pac::$rstctl::steal() };
paste! { paste! {
// SAFETY: unsafe due to the use of bits() // SAFETY: unsafe due to the use of bits()
cc1.[<$clkreg _set>]().write(|w| unsafe { w.bits(1 << $bit) }); cc1.[<$clkreg _set>]().write(|w| unsafe { w.bits(1 << $bit) });
}
}
fn reset_perph() {
// SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1
let rc1 = unsafe { pac::$rstctl::steal() };
paste! {
// SAFETY: unsafe due to the use of bits() // SAFETY: unsafe due to the use of bits()
rc1.[<$rstreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); rc1.[<$rstreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) });
} }
@ -1605,12 +1623,8 @@ macro_rules! impl_perph_clk {
fn disable_perph_clock() { fn disable_perph_clock() {
// SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1
let cc1 = unsafe { pac::$clkctl::steal() }; let cc1 = unsafe { pac::$clkctl::steal() };
let rc1 = unsafe { pac::$rstctl::steal() };
paste! { paste! {
// SAFETY: unsafe due to the use of bits()
rc1.[<$rstreg _set>]().write(|w| unsafe { w.bits(1 << $bit) });
// SAFETY: unsafe due to the use of bits() // SAFETY: unsafe due to the use of bits()
cc1.[<$clkreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); cc1.[<$clkreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) });
} }