strat9_bus_drivers/
omap_ocp2scp.rs1use crate::{BusChild, BusDriver, BusError, PowerState, mmio::MmioRegion};
2use alloc::{string::String, vec::Vec};
3
4const OCP2SCP_TIMING: usize = 0x18;
5const SYNC2_MASK: u32 = 0xF;
6const SYNC2_SAFE_VALUE: u32 = 0x6;
7
8const COMPATIBLE: &[&str] = &["ti,omap-ocp2scp", "ti,am437x-ocp2scp"];
9
10pub struct OmapOcp2Scp {
11 regs: MmioRegion,
12 power_state: PowerState,
13 is_am437x: bool,
14 children: Vec<BusChild>,
15}
16
17impl OmapOcp2Scp {
18 pub fn new() -> Self {
20 Self {
21 regs: MmioRegion::new(),
22 power_state: PowerState::Off,
23 is_am437x: false,
24 children: Vec::new(),
25 }
26 }
27
28 pub fn set_am437x(&mut self, am437x: bool) {
30 self.is_am437x = am437x;
31 }
32
33 pub fn add_child(&mut self, child: BusChild) {
35 self.children.push(child);
36 }
37
38 fn configure_timing(&self) {
40 if self.is_am437x || !self.regs.is_valid() {
41 return;
42 }
43 let mut reg = self.regs.read32(OCP2SCP_TIMING);
44 reg &= !SYNC2_MASK;
45 reg |= SYNC2_SAFE_VALUE;
46 self.regs.write32(OCP2SCP_TIMING, reg);
47 }
48}
49
50impl BusDriver for OmapOcp2Scp {
51 fn name(&self) -> &str {
53 "omap-ocp2scp"
54 }
55
56 fn compatible(&self) -> &[&str] {
58 COMPATIBLE
59 }
60
61 fn init(&mut self, base: usize) -> Result<(), BusError> {
63 self.regs.init(base, 0x20);
64 self.configure_timing();
65 self.power_state = PowerState::On;
66 Ok(())
67 }
68
69 fn shutdown(&mut self) -> Result<(), BusError> {
71 self.power_state = PowerState::Off;
72 Ok(())
73 }
74
75 fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
77 if !self.regs.is_valid() {
78 return Err(BusError::InitFailed);
79 }
80 Ok(self.regs.read32(offset))
81 }
82
83 fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
85 if !self.regs.is_valid() {
86 return Err(BusError::InitFailed);
87 }
88 self.regs.write32(offset, value);
89 Ok(())
90 }
91
92 fn children(&self) -> Vec<BusChild> {
94 self.children.clone()
95 }
96}