Compare commits
2 Commits
99a099efad
...
70eb6cfaed
Author | SHA1 | Date | |
---|---|---|---|
70eb6cfaed | |||
5c1c980ccd |
kernel
@ -60,13 +60,25 @@ struct Stmmac {
|
|||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
fn link_state(&self) -> LinkState {
|
fn link_state(&self) -> LinkState {
|
||||||
// TODO read the link state properly, i.e., read from PHY's registers, I guess? I didn't
|
let status = self.regs.lock().MAC.MACPHYCSR.extract();
|
||||||
// find a nice way to read the link state from the MAC itself, it only seems to report
|
let link = if status.matches_all(MACPHYCSR::LNKSTS::Up) {
|
||||||
// the MAC<->PHY link state (which is always up, obviously)
|
let speed = match status.read_as_enum(MACPHYCSR::LNKSPEED) {
|
||||||
LinkState::Ethernet(EthernetLinkState::Up(
|
Some(MACPHYCSR::LNKSPEED::Value::Speed2_5MHz) => EthernetSpeed::Speed10,
|
||||||
EthernetSpeed::Unknown,
|
Some(MACPHYCSR::LNKSPEED::Value::Speed25MHz) => EthernetSpeed::Speed100,
|
||||||
Duplex::Unknown,
|
Some(MACPHYCSR::LNKSPEED::Value::Speed125MHz) => EthernetSpeed::Speed1000,
|
||||||
))
|
_ => EthernetSpeed::Unknown,
|
||||||
|
};
|
||||||
|
let duplex = if status.matches_all(MACPHYCSR::LNKMOD::FullDuplex) {
|
||||||
|
Duplex::Full
|
||||||
|
} else {
|
||||||
|
Duplex::Half
|
||||||
|
};
|
||||||
|
EthernetLinkState::Up(speed, duplex)
|
||||||
|
} else {
|
||||||
|
EthernetLinkState::Down
|
||||||
|
};
|
||||||
|
|
||||||
|
LinkState::Ethernet(link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,25 +16,7 @@ use device_tree::{
|
|||||||
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIoMut};
|
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIoMut};
|
||||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||||
|
|
||||||
const CLK_OSC: usize = 0;
|
const PARENT_CLK_OSC: usize = 0;
|
||||||
|
|
||||||
// gmac0;
|
|
||||||
// 1:kernel/src/device/clock/jh7110_aoncrg.rs:69: jh7110: enable clock Some(3)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_aoncrg.rs:69: jh7110: enable clock Some(2)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(109)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_aoncrg.rs:69: jh7110: enable clock Some(6)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(111)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_aoncrg.rs:86: jh7110: deassert reset Some(0)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_aoncrg.rs:86: jh7110: deassert reset Some(1)
|
|
||||||
|
|
||||||
// gmac1:
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(98)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(97)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(102)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(106)
|
|
||||||
// 1:kernel/src/device/clock/jh7110_syscrg.rs:51: TODO: jh7110-syscrg: enable clock Some(107)
|
|
||||||
|
|
||||||
const CLK_UART0_CORE: u32 = 146;
|
|
||||||
|
|
||||||
struct Syscrg {
|
struct Syscrg {
|
||||||
base: PhysicalAddress,
|
base: PhysicalAddress,
|
||||||
@ -42,6 +24,25 @@ struct Syscrg {
|
|||||||
mapping: OneTimeInit<IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>>,
|
mapping: OneTimeInit<IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum ClockParent {
|
||||||
|
#[allow(unused)]
|
||||||
|
Int(u32),
|
||||||
|
Ext(usize),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum ClockRegister {
|
||||||
|
// Clock gate
|
||||||
|
Gate(u32, ClockParent),
|
||||||
|
// Clock inverter
|
||||||
|
Inv(u32),
|
||||||
|
// Clock delay selector (TODO)
|
||||||
|
Delay,
|
||||||
|
Unimp,
|
||||||
|
}
|
||||||
|
|
||||||
impl Syscrg {
|
impl Syscrg {
|
||||||
fn ensure_init(&self) -> Result<&IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>, Error> {
|
fn ensure_init(&self) -> Result<&IrqSafeSpinlock<DeviceMemoryIoMut<'static, [u32]>>, Error> {
|
||||||
self.mapping.or_try_init_with(move || {
|
self.mapping.or_try_init_with(move || {
|
||||||
@ -49,6 +50,38 @@ impl Syscrg {
|
|||||||
.map(IrqSafeSpinlock::new)
|
.map(IrqSafeSpinlock::new)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_clock_index(index: u32) -> Option<(&'static str, ClockRegister)> {
|
||||||
|
const CLOCKS: &[(&'static str, ClockRegister)] = &const {
|
||||||
|
use ClockParent::*;
|
||||||
|
use ClockRegister::*;
|
||||||
|
|
||||||
|
let mut t = [("", Unimp); 256];
|
||||||
|
t[0x184 / 4] = ("clk_gmac5_axi64_ahb", Gate(31, None));
|
||||||
|
t[0x188 / 4] = ("clk_gmac5_axi64_axi", Gate(31, None));
|
||||||
|
t[0x18C / 4] = ("clk_gmac_source", Unimp);
|
||||||
|
t[0x190 / 4] = ("clk_gmac1_gtx", Unimp);
|
||||||
|
t[0x194 / 4] = ("clk_gmac1_rmii_rtx", Unimp);
|
||||||
|
t[0x198 / 4] = ("clk_gmac5_axi64_ptp", Gate(31, None));
|
||||||
|
t[0x19C / 4] = ("clk_gmac5_axi64_rx", Unimp);
|
||||||
|
t[0x1A0 / 4] = ("clk_gmac5_axi64_rx_inv", Inv(30));
|
||||||
|
t[0x1A4 / 4] = ("clk_gmac5_axi64_tx", Gate(31, None));
|
||||||
|
t[0x1A8 / 4] = ("clk_gmac5_axi64_tx_inv", Inv(30));
|
||||||
|
t[0x1AC / 4] = ("clk_gmac1_gtxc", Delay);
|
||||||
|
t[0x1B0 / 4] = ("clk_gmac0_gtx", Gate(31, None));
|
||||||
|
t[0x1B4 / 4] = ("clk_gmac0_ptp", Gate(31, None));
|
||||||
|
t[0x1B8 / 4] = ("clk_gmac_phy", Gate(31, None));
|
||||||
|
t[0x1BC / 4] = ("clk_gmac0_gtxc", Delay);
|
||||||
|
|
||||||
|
t[0x244 / 4] = ("clk_u0_uart_apb", Gate(31, None));
|
||||||
|
t[0x248 / 4] = ("clk_u0_uart_core", Gate(31, Ext(PARENT_CLK_OSC)));
|
||||||
|
|
||||||
|
t
|
||||||
|
};
|
||||||
|
|
||||||
|
let index = index as usize;
|
||||||
|
CLOCKS.get(index).copied()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for Syscrg {
|
impl Device for Syscrg {
|
||||||
@ -64,15 +97,27 @@ impl Device for Syscrg {
|
|||||||
|
|
||||||
impl ClockController for Syscrg {
|
impl ClockController for Syscrg {
|
||||||
fn enable_clock(&self, clock: Option<u32>) -> Result<(), Error> {
|
fn enable_clock(&self, clock: Option<u32>) -> Result<(), Error> {
|
||||||
|
let index = clock.ok_or(Error::InvalidArgument)?;
|
||||||
|
let (name, reg) = Self::map_clock_index(index)
|
||||||
|
.ok_or(Error::InvalidArgument)
|
||||||
|
.inspect_err(|_| log::warn!("jh7110-syscrg: undefined clock {:?}", clock))?;
|
||||||
let regs = self.ensure_init()?;
|
let regs = self.ensure_init()?;
|
||||||
match clock.ok_or(Error::InvalidArgument)? {
|
let mut lock = regs.lock();
|
||||||
109 => {
|
|
||||||
regs.lock()[109] |= 1 << 31;
|
match reg {
|
||||||
|
ClockRegister::Gate(bit, _) => {
|
||||||
|
log::info!("jh7110-syscrg: enable {name:?}");
|
||||||
|
lock[index as usize] |= 1 << bit;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
111 => Ok(()),
|
ClockRegister::Inv(bit) => {
|
||||||
_ => {
|
log::info!("jh7110-syscrg: enable clk inv {name:?}");
|
||||||
log::warn!("TODO: jh7110-syscrg: enable clock {clock:?}");
|
lock[index as usize] |= 1 << bit;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
ClockRegister::Delay => Ok(()),
|
||||||
|
ClockRegister::Unimp => {
|
||||||
|
log::warn!("jh7110-syscrg: clock not implemented: {name:?}");
|
||||||
Err(Error::NotImplemented)
|
Err(Error::NotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,10 +129,25 @@ impl ClockController for Syscrg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn clock_rate(&self, clock: Option<u32>) -> Result<u64, Error> {
|
fn clock_rate(&self, clock: Option<u32>) -> Result<u64, Error> {
|
||||||
match clock.ok_or(Error::InvalidArgument)? {
|
let (name, reg) = clock
|
||||||
CLK_UART0_CORE => self.parents[CLK_OSC].rate(),
|
.and_then(Self::map_clock_index)
|
||||||
_ => {
|
.ok_or(Error::InvalidArgument)
|
||||||
log::warn!("TODO: jh7110-syscrg: read rate {:#x?}", clock);
|
.inspect_err(|_| log::warn!("jh7110-syscrg: undefined clock {:?}", clock))?;
|
||||||
|
|
||||||
|
match reg {
|
||||||
|
ClockRegister::Gate(_, parent) => match parent {
|
||||||
|
ClockParent::Ext(n) => self.parents[n].rate(),
|
||||||
|
ClockParent::Int(_) => {
|
||||||
|
log::warn!("jh7110-syscrg: todo internal clock parents: {:?}", name);
|
||||||
|
Err(Error::NotImplemented)
|
||||||
|
}
|
||||||
|
ClockParent::None => {
|
||||||
|
log::warn!("jh7110-syscrg: clock parent not specified {:?}", name);
|
||||||
|
Err(Error::NotImplemented)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ClockRegister::Unimp | ClockRegister::Delay | ClockRegister::Inv(_) => {
|
||||||
|
log::warn!("jh7110-syscrg: unimplemented clock {:?}", name);
|
||||||
Err(Error::NotImplemented)
|
Err(Error::NotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user