Skip to main content

strat9_bus_drivers/
sunxi_rsb.rs

1use crate::{BusChild, BusDriver, BusError, PowerState, mmio::MmioRegion};
2use alloc::{string::String, vec::Vec};
3
4const RSB_CTRL: usize = 0x00;
5const RSB_CCR: usize = 0x04;
6const RSB_INTE: usize = 0x08;
7const RSB_INTS: usize = 0x0C;
8const RSB_ADDR: usize = 0x10;
9const RSB_DATA: usize = 0x1C;
10const RSB_LCR: usize = 0x24;
11const RSB_DMCR: usize = 0x28;
12const RSB_CMD: usize = 0x2C;
13const RSB_DAR: usize = 0x30;
14
15const RSB_CTRL_START_TRANS: u32 = 1 << 7;
16const RSB_CTRL_ABORT_TRANS: u32 = 1 << 6;
17const RSB_CTRL_GLOBAL_INT_ENB: u32 = 1 << 1;
18const RSB_CTRL_SOFT_RST: u32 = 1 << 0;
19
20const RSB_INTS_TRANS_ERR_ACK: u32 = 1 << 16;
21const RSB_INTS_TRANS_ERR_DATA_MASK: u32 = 0xF << 8;
22const RSB_INTS_LOAD_BSY: u32 = 1 << 2;
23const RSB_INTS_TRANS_ERR: u32 = 1 << 1;
24const RSB_INTS_TRANS_OVER: u32 = 1 << 0;
25
26const RSB_DMCR_DEVICE_START: u32 = 1 << 31;
27const RSB_DMCR_MODE_DATA: u32 = 0x7C << 16;
28const RSB_DMCR_MODE_REG: u32 = 0x3E << 8;
29
30const RSB_CMD_RD8: u32 = 0x8B;
31const RSB_CMD_RD16: u32 = 0x9C;
32const RSB_CMD_RD32: u32 = 0xA6;
33const RSB_CMD_WR8: u32 = 0x4E;
34const RSB_CMD_WR16: u32 = 0x59;
35const RSB_CMD_WR32: u32 = 0x63;
36const RSB_CMD_STRA: u32 = 0xE8;
37
38const MAX_POLL: u32 = 10000;
39
40const COMPATIBLE: &[&str] = &["allwinner,sun8i-a23-rsb"];
41
42/// Performs the ccr sda out delay operation.
43fn ccr_sda_out_delay(v: u32) -> u32 {
44    (v & 0x7) << 8
45}
46/// Performs the ccr clk div operation.
47fn ccr_clk_div(v: u32) -> u32 {
48    v & 0xFF
49}
50/// Performs the dar rta operation.
51fn dar_rta(v: u32) -> u32 {
52    (v & 0xFF) << 16
53}
54/// Performs the dar da operation.
55fn dar_da(v: u32) -> u32 {
56    v & 0xFFFF
57}
58
59pub struct RsbAddrMap {
60    pub hwaddr: u16,
61    pub rtaddr: u8,
62}
63
64pub const DEFAULT_ADDR_MAP: &[RsbAddrMap] = &[
65    RsbAddrMap {
66        hwaddr: 0x3A3,
67        rtaddr: 0x2D,
68    },
69    RsbAddrMap {
70        hwaddr: 0x745,
71        rtaddr: 0x3A,
72    },
73    RsbAddrMap {
74        hwaddr: 0xE89,
75        rtaddr: 0x4E,
76    },
77];
78
79pub struct SunxiRsb {
80    regs: MmioRegion,
81    clock_freq: u32,
82    power_state: PowerState,
83    children: Vec<BusChild>,
84}
85
86impl SunxiRsb {
87    /// Creates a new instance.
88    pub fn new() -> Self {
89        Self {
90            regs: MmioRegion::new(),
91            clock_freq: 3_000_000,
92            power_state: PowerState::Off,
93            children: Vec::new(),
94        }
95    }
96
97    /// Sets clock freq.
98    pub fn set_clock_freq(&mut self, freq: u32) {
99        self.clock_freq = freq;
100    }
101
102    /// Performs the soft reset operation.
103    fn soft_reset(&self) {
104        self.regs.write32(RSB_CTRL, RSB_CTRL_SOFT_RST);
105        for _ in 0..MAX_POLL {
106            if self.regs.read32(RSB_CTRL) & RSB_CTRL_SOFT_RST == 0 {
107                return;
108            }
109        }
110    }
111
112    /// Performs the wait transfer complete operation.
113    fn wait_transfer_complete(&self) -> Result<u32, BusError> {
114        for _ in 0..MAX_POLL {
115            let status = self.regs.read32(RSB_INTS);
116            if status & RSB_INTS_LOAD_BSY != 0 {
117                self.regs.write32(RSB_INTS, status);
118                return Err(BusError::Timeout);
119            }
120            if status & RSB_INTS_TRANS_ERR != 0 {
121                self.regs.write32(RSB_INTS, status);
122                return Err(BusError::ProtocolError);
123            }
124            if status & RSB_INTS_TRANS_OVER != 0 {
125                self.regs.write32(RSB_INTS, status);
126                return Ok(status);
127            }
128        }
129        Err(BusError::Timeout)
130    }
131
132    /// Starts transfer.
133    fn start_transfer(&self) {
134        self.regs
135            .write32(RSB_CTRL, RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB);
136    }
137
138    /// Sets runtime address.
139    pub fn set_runtime_address(&self, hwaddr: u16, rtaddr: u8) -> Result<(), BusError> {
140        self.regs.write32(RSB_CMD, RSB_CMD_STRA);
141        self.regs
142            .write32(RSB_DAR, dar_rta(rtaddr as u32) | dar_da(hwaddr as u32));
143        self.start_transfer();
144        self.wait_transfer_complete()?;
145        Ok(())
146    }
147
148    /// Initializes device mode.
149    pub fn init_device_mode(&self) -> Result<(), BusError> {
150        self.regs.write32(
151            RSB_DMCR,
152            RSB_DMCR_DEVICE_START | RSB_DMCR_MODE_DATA | RSB_DMCR_MODE_REG,
153        );
154        for _ in 0..MAX_POLL {
155            if self.regs.read32(RSB_DMCR) & RSB_DMCR_DEVICE_START == 0 {
156                return Ok(());
157            }
158        }
159        Err(BusError::Timeout)
160    }
161
162    /// Performs the read8 operation.
163    pub fn read8(&self, rtaddr: u8, reg: u8) -> Result<u8, BusError> {
164        self.regs.write32(RSB_CMD, RSB_CMD_RD8);
165        self.regs.write32(RSB_DAR, dar_rta(rtaddr as u32));
166        self.regs.write32(RSB_ADDR, reg as u32);
167        self.start_transfer();
168        self.wait_transfer_complete()?;
169        Ok(self.regs.read32(RSB_DATA) as u8)
170    }
171
172    /// Performs the write8 operation.
173    pub fn write8(&self, rtaddr: u8, reg: u8, val: u8) -> Result<(), BusError> {
174        self.regs.write32(RSB_CMD, RSB_CMD_WR8);
175        self.regs.write32(RSB_DAR, dar_rta(rtaddr as u32));
176        self.regs.write32(RSB_ADDR, reg as u32);
177        self.regs.write32(RSB_DATA, val as u32);
178        self.start_transfer();
179        self.wait_transfer_complete()?;
180        Ok(())
181    }
182
183    /// Performs the read16 operation.
184    pub fn read16(&self, rtaddr: u8, reg: u8) -> Result<u16, BusError> {
185        self.regs.write32(RSB_CMD, RSB_CMD_RD16);
186        self.regs.write32(RSB_DAR, dar_rta(rtaddr as u32));
187        self.regs.write32(RSB_ADDR, reg as u32);
188        self.start_transfer();
189        self.wait_transfer_complete()?;
190        Ok(self.regs.read32(RSB_DATA) as u16)
191    }
192
193    /// Performs the write16 operation.
194    pub fn write16(&self, rtaddr: u8, reg: u8, val: u16) -> Result<(), BusError> {
195        self.regs.write32(RSB_CMD, RSB_CMD_WR16);
196        self.regs.write32(RSB_DAR, dar_rta(rtaddr as u32));
197        self.regs.write32(RSB_ADDR, reg as u32);
198        self.regs.write32(RSB_DATA, val as u32);
199        self.start_transfer();
200        self.wait_transfer_complete()?;
201        Ok(())
202    }
203
204    /// Performs the add child operation.
205    pub fn add_child(&mut self, child: BusChild) {
206        self.children.push(child);
207    }
208}
209
210impl BusDriver for SunxiRsb {
211    /// Performs the name operation.
212    fn name(&self) -> &str {
213        "sunxi-rsb"
214    }
215
216    /// Performs the compatible operation.
217    fn compatible(&self) -> &[&str] {
218        COMPATIBLE
219    }
220
221    /// Performs the init operation.
222    fn init(&mut self, base: usize) -> Result<(), BusError> {
223        self.regs.init(base, 0x40);
224        self.soft_reset();
225        self.regs
226            .write32(RSB_CCR, ccr_sda_out_delay(1) | ccr_clk_div(3));
227        self.init_device_mode()?;
228        self.power_state = PowerState::On;
229        Ok(())
230    }
231
232    /// Performs the shutdown operation.
233    fn shutdown(&mut self) -> Result<(), BusError> {
234        self.soft_reset();
235        self.power_state = PowerState::Off;
236        Ok(())
237    }
238
239    /// Reads reg.
240    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
241        if !self.regs.is_valid() {
242            return Err(BusError::InitFailed);
243        }
244        Ok(self.regs.read32(offset))
245    }
246
247    /// Writes reg.
248    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
249        if !self.regs.is_valid() {
250            return Err(BusError::InitFailed);
251        }
252        self.regs.write32(offset, value);
253        Ok(())
254    }
255
256    /// Performs the children operation.
257    fn children(&self) -> Vec<BusChild> {
258        self.children.clone()
259    }
260}