Skip to main content

strat9_bus_drivers/
da8xx_mstpri.rs

1use crate::{BusChild, BusDriver, BusError, PowerState, mmio::MmioRegion};
2use alloc::{string::String, vec::Vec};
3
4const DA8XX_MSTPRI0_OFFSET: usize = 0x0;
5const DA8XX_MSTPRI1_OFFSET: usize = 0x4;
6const DA8XX_MSTPRI2_OFFSET: usize = 0x8;
7
8const COMPATIBLE: &[&str] = &["ti,da850-mstpri"];
9
10#[derive(Clone, Copy)]
11pub struct MasterPriDescr {
12    pub reg: usize,
13    pub shift: u32,
14    pub mask: u32,
15}
16
17pub const MSTPRI_ARM_I: MasterPriDescr = MasterPriDescr {
18    reg: DA8XX_MSTPRI0_OFFSET,
19    shift: 0,
20    mask: 0x0000_000F,
21};
22pub const MSTPRI_ARM_D: MasterPriDescr = MasterPriDescr {
23    reg: DA8XX_MSTPRI0_OFFSET,
24    shift: 4,
25    mask: 0x0000_00F0,
26};
27pub const MSTPRI_UPP: MasterPriDescr = MasterPriDescr {
28    reg: DA8XX_MSTPRI0_OFFSET,
29    shift: 16,
30    mask: 0x000F_0000,
31};
32pub const MSTPRI_SATA: MasterPriDescr = MasterPriDescr {
33    reg: DA8XX_MSTPRI0_OFFSET,
34    shift: 20,
35    mask: 0x00F0_0000,
36};
37pub const MSTPRI_PRU0: MasterPriDescr = MasterPriDescr {
38    reg: DA8XX_MSTPRI1_OFFSET,
39    shift: 0,
40    mask: 0x0000_000F,
41};
42pub const MSTPRI_PRU1: MasterPriDescr = MasterPriDescr {
43    reg: DA8XX_MSTPRI1_OFFSET,
44    shift: 4,
45    mask: 0x0000_00F0,
46};
47pub const MSTPRI_EDMA30TC0: MasterPriDescr = MasterPriDescr {
48    reg: DA8XX_MSTPRI1_OFFSET,
49    shift: 8,
50    mask: 0x0000_0F00,
51};
52pub const MSTPRI_EDMA30TC1: MasterPriDescr = MasterPriDescr {
53    reg: DA8XX_MSTPRI1_OFFSET,
54    shift: 12,
55    mask: 0x0000_F000,
56};
57pub const MSTPRI_EDMA31TC0: MasterPriDescr = MasterPriDescr {
58    reg: DA8XX_MSTPRI1_OFFSET,
59    shift: 16,
60    mask: 0x000F_0000,
61};
62pub const MSTPRI_VPIF_DMA0: MasterPriDescr = MasterPriDescr {
63    reg: DA8XX_MSTPRI1_OFFSET,
64    shift: 24,
65    mask: 0x0F00_0000,
66};
67pub const MSTPRI_VPIF_DMA1: MasterPriDescr = MasterPriDescr {
68    reg: DA8XX_MSTPRI1_OFFSET,
69    shift: 28,
70    mask: 0xF000_0000,
71};
72pub const MSTPRI_EMAC: MasterPriDescr = MasterPriDescr {
73    reg: DA8XX_MSTPRI2_OFFSET,
74    shift: 0,
75    mask: 0x0000_000F,
76};
77pub const MSTPRI_USB0: MasterPriDescr = MasterPriDescr {
78    reg: DA8XX_MSTPRI2_OFFSET,
79    shift: 8,
80    mask: 0x0000_0F00,
81};
82pub const MSTPRI_USB1: MasterPriDescr = MasterPriDescr {
83    reg: DA8XX_MSTPRI2_OFFSET,
84    shift: 12,
85    mask: 0x0000_F000,
86};
87pub const MSTPRI_UHPI: MasterPriDescr = MasterPriDescr {
88    reg: DA8XX_MSTPRI2_OFFSET,
89    shift: 20,
90    mask: 0x00F0_0000,
91};
92pub const MSTPRI_LCDC: MasterPriDescr = MasterPriDescr {
93    reg: DA8XX_MSTPRI2_OFFSET,
94    shift: 28,
95    mask: 0xF000_0000,
96};
97
98pub struct MasterPriority {
99    pub master: MasterPriDescr,
100    pub priority: u32,
101}
102
103pub struct Da8xxMstpri {
104    regs: MmioRegion,
105    priorities: Vec<MasterPriority>,
106    power_state: PowerState,
107}
108
109impl Da8xxMstpri {
110    /// Creates a new instance.
111    pub fn new() -> Self {
112        Self {
113            regs: MmioRegion::new(),
114            priorities: Vec::new(),
115            power_state: PowerState::Off,
116        }
117    }
118
119    /// Performs the add priority operation.
120    pub fn add_priority(&mut self, master: MasterPriDescr, priority: u32) {
121        self.priorities.push(MasterPriority { master, priority });
122    }
123
124    /// Performs the apply priorities operation.
125    fn apply_priorities(&self) {
126        for p in &self.priorities {
127            let val = self.regs.read32(p.master.reg);
128            let new_val = (val & !p.master.mask) | ((p.priority << p.master.shift) & p.master.mask);
129            self.regs.write32(p.master.reg, new_val);
130        }
131    }
132}
133
134impl BusDriver for Da8xxMstpri {
135    /// Performs the name operation.
136    fn name(&self) -> &str {
137        "da8xx-mstpri"
138    }
139
140    /// Performs the compatible operation.
141    fn compatible(&self) -> &[&str] {
142        COMPATIBLE
143    }
144
145    /// Performs the init operation.
146    fn init(&mut self, base: usize) -> Result<(), BusError> {
147        self.regs.init(base, 0x10);
148        self.apply_priorities();
149        self.power_state = PowerState::On;
150        Ok(())
151    }
152
153    /// Performs the shutdown operation.
154    fn shutdown(&mut self) -> Result<(), BusError> {
155        self.power_state = PowerState::Off;
156        Ok(())
157    }
158
159    /// Reads reg.
160    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
161        if !self.regs.is_valid() {
162            return Err(BusError::InitFailed);
163        }
164        Ok(self.regs.read32(offset))
165    }
166
167    /// Writes reg.
168    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
169        if !self.regs.is_valid() {
170            return Err(BusError::InitFailed);
171        }
172        self.regs.write32(offset, value);
173        Ok(())
174    }
175}