jh7110: syscrg/aoncrg map memory in probe
This commit is contained in:
parent
41944890b6
commit
99f5ad0987
@ -13,7 +13,7 @@ use device_tree::{
|
||||
DeviceTreePropertyRead, TProp,
|
||||
};
|
||||
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIo};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
use tock_registers::{
|
||||
interfaces::{Readable, Writeable},
|
||||
register_structs,
|
||||
@ -58,28 +58,21 @@ enum ClockParent {
|
||||
pub struct Aoncrg {
|
||||
base: PhysicalAddress,
|
||||
clock_parents: [ClockHandle; 7],
|
||||
mapping: OneTimeInit<IrqSafeSpinlock<DeviceMemoryIo<'static, Regs>>>,
|
||||
mapping: IrqSafeSpinlock<DeviceMemoryIo<'static, Regs>>,
|
||||
}
|
||||
|
||||
impl Aoncrg {
|
||||
fn ensure_init(&self) -> Result<&IrqSafeSpinlock<DeviceMemoryIo<'static, Regs>>, Error> {
|
||||
self.mapping.or_try_init_with(|| {
|
||||
unsafe { DeviceMemoryIo::map(self.base, Default::default()) }.map(IrqSafeSpinlock::new)
|
||||
})
|
||||
}
|
||||
|
||||
fn clk_enable_int(&self, index: u32) -> Result<(), Error> {
|
||||
let (name, reg) = Self::map_clock_index(index)
|
||||
.ok_or(Error::InvalidArgument)
|
||||
.inspect_err(|_| log::warn!("jh7110-syscrg: undefined clock {:?}", index))?;
|
||||
let regs = self.ensure_init()?;
|
||||
|
||||
match reg {
|
||||
ClockRegister::Fixed => Ok(()),
|
||||
ClockRegister::Gate(bit, parent) => {
|
||||
self.clk_enable_parent(parent)?;
|
||||
log::info!("jh7110-aoncrg: enable {name:?} @ {index}");
|
||||
let lock = regs.lock();
|
||||
let lock = self.mapping.lock();
|
||||
lock.CLOCKS[index as usize].set(lock.CLOCKS[index as usize].get() | (1 << bit));
|
||||
Ok(())
|
||||
}
|
||||
@ -145,8 +138,7 @@ impl ClockController for Aoncrg {
|
||||
impl ResetController for Aoncrg {
|
||||
fn assert_reset(&self, reset: Option<u32>) -> Result<(), Error> {
|
||||
let reset = reset.ok_or(Error::InvalidArgument)?;
|
||||
let mapping = self.ensure_init()?;
|
||||
let regs = mapping.lock();
|
||||
let regs = self.mapping.lock();
|
||||
let val = regs.RESETS.get();
|
||||
regs.RESETS.set(val | (1 << reset));
|
||||
Ok(())
|
||||
@ -154,8 +146,7 @@ impl ResetController for Aoncrg {
|
||||
|
||||
fn deassert_reset(&self, reset: Option<u32>) -> Result<(), Error> {
|
||||
let reset = reset.ok_or(Error::InvalidArgument)?;
|
||||
let mapping = self.ensure_init()?;
|
||||
let regs = mapping.lock();
|
||||
let regs = self.mapping.lock();
|
||||
let val = regs.RESETS.get();
|
||||
regs.RESETS.set(val & !(1 << reset));
|
||||
Ok(())
|
||||
@ -204,11 +195,14 @@ device_tree_driver! {
|
||||
node.named_clock("rtc_osc")?,
|
||||
];
|
||||
|
||||
let mapping = unsafe { DeviceMemoryIo::map(base, Default::default()) }.ok()?;
|
||||
|
||||
let aoncrg = Arc::new(Aoncrg {
|
||||
base,
|
||||
clock_parents,
|
||||
mapping: OneTimeInit::new()
|
||||
mapping: IrqSafeSpinlock::new(mapping)
|
||||
});
|
||||
|
||||
node.make_reset_controller(aoncrg.clone());
|
||||
node.make_clock_controller(aoncrg.clone());
|
||||
Some(aoncrg)
|
||||
|
@ -14,14 +14,14 @@ use device_tree::{
|
||||
DeviceTreePropertyRead, TProp,
|
||||
};
|
||||
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIoMut};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
|
||||
const PARENT_CLK_OSC: usize = 0;
|
||||
|
||||
struct Syscrg {
|
||||
base: PhysicalAddress,
|
||||
parents: [ClockHandle; 1],
|
||||
mapping: OneTimeInit<IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>>,
|
||||
mapping: IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@ -43,31 +43,23 @@ enum ClockRegister {
|
||||
}
|
||||
|
||||
impl Syscrg {
|
||||
fn ensure_init(&self) -> Result<&IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>, Error> {
|
||||
self.mapping.or_try_init_with(move || {
|
||||
unsafe { DeviceMemoryIoMut::map_slice(self.base, 256, Default::default()) }
|
||||
.map(IrqSafeSpinlock::new)
|
||||
})
|
||||
}
|
||||
|
||||
fn clk_enable_int(&self, index: u32, depth: u32) -> Result<(), Error> {
|
||||
let (name, reg) = Self::map_clock_index(index)
|
||||
.ok_or(Error::InvalidArgument)
|
||||
.inspect_err(|_| log::warn!("jh7110-syscrg: undefined clock {:?}", index))?;
|
||||
let regs = self.ensure_init()?;
|
||||
|
||||
match reg {
|
||||
ClockRegister::Gate(bit, parent) => {
|
||||
log::info!("jh7110-syscrg: enable {name:?} @ {index} /{depth}");
|
||||
self.clk_enable_parent(parent, depth)?;
|
||||
let mut lock = regs.lock();
|
||||
let mut lock = self.mapping.lock();
|
||||
lock[index as usize] |= 1 << bit;
|
||||
Ok(())
|
||||
}
|
||||
ClockRegister::Inv(bit, parent) => {
|
||||
log::info!("jh7110-syscrg: enable clk inv {name:?} @ {index}");
|
||||
self.clk_enable_parent(parent, depth)?;
|
||||
let mut lock = regs.lock();
|
||||
let mut lock = self.mapping.lock();
|
||||
lock[index as usize] |= 1 << bit;
|
||||
Ok(())
|
||||
}
|
||||
@ -182,8 +174,7 @@ impl Syscrg {
|
||||
fn rst_trigger(&self, reset: u32, assert: bool) -> Result<(), Error> {
|
||||
let reg = (190 + reset / 32) as usize;
|
||||
let bit = reset % 32;
|
||||
let regs = self.ensure_init()?;
|
||||
let mut regs = regs.lock();
|
||||
let mut regs = self.mapping.lock();
|
||||
|
||||
let expect = if assert {
|
||||
regs[reg] |= 1 << bit;
|
||||
@ -246,17 +237,23 @@ impl DeviceTreeResetController for Syscrg {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for Syscrg {}
|
||||
unsafe impl Send for Syscrg {}
|
||||
|
||||
device_tree_driver! {
|
||||
compatible: ["starfive,jh7110-syscrg"],
|
||||
driver: {
|
||||
fn probe(&self, node: &Arc<Node>, context: &mut ProbeContext) -> Option<Arc<dyn Device>> {
|
||||
let base = node.map_base(context, 0)?;
|
||||
let osc = node.named_clock("osc")?;
|
||||
let mapping = unsafe { DeviceMemoryIoMut::map_slice(base, 256, Default::default()) }
|
||||
.inspect_err(|error| log::error!("jh7110-syscrg: {error:?}"))
|
||||
.ok()?;
|
||||
|
||||
let syscrg = Arc::new(Syscrg {
|
||||
base,
|
||||
parents: [osc],
|
||||
mapping: OneTimeInit::new(),
|
||||
mapping: IrqSafeSpinlock::new(mapping),
|
||||
});
|
||||
node.make_reset_controller(syscrg.clone());
|
||||
node.make_clock_controller(syscrg.clone());
|
||||
|
Loading…
x
Reference in New Issue
Block a user