1use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec, vec::Vec};
7use core::ops::{Deref, DerefMut};
8
9use dma_api::{ContiguousArray, DmaCoherency, DmaDirection};
10use event::EventBuffer;
11use futures::{FutureExt, future::BoxFuture};
12use reg::{GCTL, GEVNTSIZ, GHWPARAMS0, GHWPARAMS1, GHWPARAMS3, GHWPARAMS4, GUCTL1, GUSB2PHYCFG};
13use tock_registers::interfaces::*;
14use udphy::Udphy;
15pub use usb_if::DrMode;
16use usb_if::Speed;
17use usb2phy::Usb2Phy;
18pub use usb2phy::Usb2PhyParam;
19
20use crate::{
21 DeviceAddressInfo, KernelOp, Mmio,
22 backend::{
23 kmod::{hub::HubOp, kcore::CoreOp, xhci::Xhci},
24 ty::{DeviceOp, Event, EventHandlerOp},
25 },
26 err::{Result, USBError},
27 osal::Kernel,
28};
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
32pub enum UsbPhyInterfaceMode {
33 #[default]
35 Unknown,
36 Utmi,
38 UtmiWide,
40}
41
42pub mod grf;
43mod consts;
45mod event;
46mod reg;
47mod udphy;
48pub mod usb2phy;
49
50use consts::*;
52use reg::Dwc3Regs;
53pub use udphy::UdphyParam;
54pub trait ResetLine: Sync + Send + 'static {
57 fn assert(&self);
58 fn deassert(&self);
59}
60
61#[derive(Clone)]
62pub struct NamedResetLine {
63 name: String,
64 line: Arc<dyn ResetLine>,
65}
66
67impl NamedResetLine {
68 pub fn new(name: impl Into<String>, line: impl ResetLine) -> Self {
69 Self::from_arc(name, Arc::new(line))
70 }
71
72 pub fn from_arc(name: impl Into<String>, line: Arc<dyn ResetLine>) -> Self {
73 Self {
74 name: name.into(),
75 line,
76 }
77 }
78
79 pub fn name(&self) -> &str {
80 &self.name
81 }
82
83 pub fn line(&self) -> Arc<dyn ResetLine> {
84 self.line.clone()
85 }
86}
87
88pub struct DwcNewParams<'a> {
89 pub ctrl: Mmio,
90 pub phy: Mmio,
91 pub phy_param: UdphyParam<'a>,
92 pub usb2_phy_param: Usb2PhyParam<'a>,
93 pub rst_list: &'a [NamedResetLine],
94 pub params: DwcParams,
95 pub kernel: &'static dyn KernelOp,
96}
97
98#[derive(Debug, Default, Clone)]
99pub struct DwcParams {
100 pub dr_mode: DrMode,
101 pub max_speed: Speed,
102 pub hsphy_mode: UsbPhyInterfaceMode,
103 pub delayed_status: bool,
104 pub ep0_bounced: bool,
105 pub ep0_expect_in: bool,
106 pub has_hibernation: bool,
107 pub has_lpm_erratum: bool,
108 pub is_utmi_l1_suspend: bool,
109 pub is_selfpowered: bool,
110 pub is_fpga: bool,
111 pub needs_fifo_resize: bool,
112 pub pullups_connected: bool,
113 pub resize_fifos: bool,
114 pub setup_packet_pending: bool,
115 pub start_config_issued: bool,
116 pub three_stage_setup: bool,
117 pub disable_scramble_quirk: bool,
118 pub u2exit_lfps_quirk: bool,
119 pub u2ss_inp3_quirk: bool,
120 pub req_p1p2p3_quirk: bool,
121 pub del_p1p2p3_quirk: bool,
122 pub del_phy_power_chg_quirk: bool,
123 pub lfps_filter_quirk: bool,
124 pub rx_detect_poll_quirk: bool,
125 pub dis_u3_susphy_quirk: bool,
126 pub dis_u2_susphy_quirk: bool,
127 pub dis_u1u2_quirk: bool,
128 pub dis_enblslpm_quirk: bool,
129 pub dis_u2_freeclk_exists_quirk: bool,
130 pub tx_de_emphasis_quirk: bool,
131 pub tx_de_emphasis: u8, pub usb2_phyif_utmi_width: u8, }
134
135pub struct Dwc {
141 xhci: Xhci,
142 usb3_phy: Udphy,
143 usb2_phy: Usb2Phy,
144 dwc_regs: Dwc3Regs,
145 rsts: BTreeMap<String, Arc<dyn ResetLine>>,
146 ev_buffs: Vec<EventBuffer>,
147 revistion: u32,
148 nr_scratch: u32,
149 params: DwcParams,
150 scratchbuf: Option<ContiguousArray<u8>>,
151}
152
153impl Dwc {
154 pub fn new(mut params: DwcNewParams<'_>) -> Result<Self> {
155 let mmio_base = params.ctrl.as_ptr() as usize;
156 params.params.max_speed = Speed::Full;
157 let xhci = Xhci::new(params.ctrl, DmaCoherency::NonCoherent, params.kernel)?;
158
159 let phy = Udphy::new(params.phy, params.phy_param);
160 let usb2_phy = Usb2Phy::new(params.usb2_phy_param, xhci.kernel().clone());
161
162 let dwc_regs = unsafe { Dwc3Regs::new(mmio_base) };
163
164 let mut rsts = BTreeMap::new();
165 for reset in params.rst_list.iter() {
166 rsts.insert(reset.name.clone(), reset.line());
167 }
168
169 Ok(Self {
170 xhci,
171 dwc_regs,
172 usb3_phy: phy,
173 usb2_phy,
174 rsts,
175 ev_buffs: vec![],
176 revistion: 0,
177 nr_scratch: 0,
178 params: params.params,
179 scratchbuf: None,
180 })
181 }
182
183 async fn dwc3_init(&mut self) -> Result<()> {
184 self.alloc_event_buffers(DWC3_EVENT_BUFFERS_SIZE)?;
185 self.core_init().await?;
186 self.event_buffers_setup();
187
188 Ok(())
189 }
190
191 fn alloc_event_buffers(&mut self, len: usize) -> Result<()> {
192 let num_buffs = self
193 .dwc_regs
194 .globals()
195 .ghwparams1
196 .read(GHWPARAMS1::NUM_EVENT_BUFFERS);
197 debug!("Allocating {} event buffers", num_buffs);
198 for _ in 0..num_buffs {
199 let ev_buff = EventBuffer::new(len, self.kernel())?;
200 self.ev_buffs.push(ev_buff);
201 }
202 Ok(())
203 }
204
205 fn event_buffers_setup(&mut self) {
206 info!("DWC3: Setting up event buffers");
207
208 let regs = self.dwc_regs.globals();
209
210 for (i, ev_buff) in self.ev_buffs.iter().enumerate() {
211 if i >= regs.gevnt.len() {
212 warn!("DWC3: Invalid event buffer index {}", i);
213 break;
214 }
215
216 let dma_addr = ev_buff.dma_addr();
217 let length = ev_buff.buffer.len();
218
219 debug!(
220 "DWC3: Event buffer {} - DMA addr: {:#x}, length: {}",
221 i, dma_addr, length
222 );
223
224 regs.gevnt[i].adrlo.set((dma_addr & 0xffffffff) as u32);
226 regs.gevnt[i].adrhi.set((dma_addr >> 32) as u32);
227
228 regs.gevnt[i]
231 .size
232 .modify(GEVNTSIZ::INTMASK::Unmasked + GEVNTSIZ::SIZE.val(length as _));
233
234 regs.gevnt[i].count.set(0);
235
236 debug!(
237 "DWC3: GEVNTSIZ[{}] = {:?} (INTMASK cleared, SIZE={})",
238 i,
239 regs.gevnt[i].size.debug(),
240 length
241 );
242 }
243
244 debug!("DWC3: Event buffers setup completed");
245 }
246
247 async fn core_init(&mut self) -> Result<()> {
248 self.revistion = self.dwc_regs.read_revision() as _;
249 if self.revistion != 0x55330000 {
250 Err(anyhow!(
251 "Unsupported DWC3 revision: 0x{:08x}",
252 self.revistion
253 ))?;
254 }
255 self.revistion += self.dwc_regs.read_product_id();
256 debug!("DWC3: Detected revision 0x{:08x}", self.revistion);
257
258 if let Some(GHWPARAMS3::SSPHY_IFC::Value::Disabled) = self
259 .dwc_regs
260 .globals()
261 .ghwparams3
262 .read_as_enum(GHWPARAMS3::SSPHY_IFC)
263 && self.max_speed == Speed::SuperSpeed
264 {
265 self.max_speed = Speed::High;
266 }
267
268 debug!("DWC3: Max speed {:?}", self.max_speed);
269
270 self.dwc_regs.device_soft_reset().await;
271
272 info!("DWC3: Starting core soft reset (includes PHY soft reset)");
274 self.dwc_regs.core_soft_reset(self.kernel()).await;
275
276 let gusb3_val = self.dwc_regs.globals().gusb3pipectl0.extract();
278 let gusb2_val = self.dwc_regs.globals().gusb2phycfg0.extract();
279 info!(
280 "DWC3: After core_soft_reset - GUSB3PIPECTL={:#010x}, GUSB2PHYCFG={:#010x}",
281 gusb3_val.get(),
282 gusb2_val.get()
283 );
284
285 info!("DWC3: Clearing suspendusb20 bit (TRM requirement)");
288 self.dwc_regs
289 .globals()
290 .gusb2phycfg0
291 .modify(GUSB2PHYCFG::SUSPHY::Disable);
292 if self.revistion >= DWC3_REVISION_250A {
293 debug!("DWC3: Revision 250A or later detected");
294
295 if matches!(self.max_speed, Speed::Full | Speed::High) {
296 self.dwc_regs
297 .globals()
298 .guctl1
299 .modify(GUCTL1::DEV_FORCE_20_CLK_FOR_30_CLK::Enable);
300 }
301 }
302
303 let mut reg = self.dwc_regs.globals().gctl.extract();
304 reg.modify(GCTL::SCALEDOWN::None);
305
306 match self
307 .dwc_regs
308 .globals()
309 .ghwparams1
310 .read_as_enum(GHWPARAMS1::EN_PWROPT)
311 {
312 Some(GHWPARAMS1::EN_PWROPT::Value::Clock) => {
313 if (DWC3_REVISION_210A..=DWC3_REVISION_250A).contains(&self.revistion) {
314 reg.modify(GCTL::DSBLCLKGTNG::Enable + GCTL::SOFITPSYNC::Enable);
315 } else {
316 reg.modify(GCTL::DSBLCLKGTNG::Disable);
317 }
318 }
319 Some(GHWPARAMS1::EN_PWROPT::Value::Hibernation) => {
320 self.nr_scratch = self
321 .dwc_regs
322 .globals()
323 .ghwparams4
324 .read(GHWPARAMS4::HIBER_SCRATCHBUFS) as _;
325
326 reg.modify(GCTL::GBLHIBERNATIONEN::Enable);
327 }
328 _ => {
329 debug!("No power optimization available");
330 }
331 }
332 reg.modify(GCTL::DISSCRAMBLE::Disable);
333
334 if self.u2exit_lfps_quirk {
335 reg.modify(GCTL::U2EXIT_LFPS::Enable);
336 }
337 if self.revistion < DWC3_REVISION_190A {
342 debug!("Applying DWC3 <1.90a SuperSpeed connect workaround");
343 reg.modify(GCTL::U2RSTECN::Enable);
344 }
345
346 self.dwc_regs.globals().gctl.set(reg.get());
349
350 self.phy_setup().await?;
351
352 self.alloc_scratch_buffers()?;
353
354 self.setup_scratch_buffers();
355
356 self.core_init_mode()?;
357
358 Ok(())
359 }
360
361 fn hsphy_mode_setup(&mut self) {
367 use reg::GUSB2PHYCFG;
368
369 match self.hsphy_mode {
370 UsbPhyInterfaceMode::Utmi => {
371 self.dwc_regs.globals().gusb2phycfg0.modify(
373 GUSB2PHYCFG::PHYIF.val(0) + GUSB2PHYCFG::USBTRDTIM.val(9), );
376 debug!("DWC3: HS PHY configured as UTMI 8-bit");
377 }
378 UsbPhyInterfaceMode::UtmiWide => {
379 self.dwc_regs.globals().gusb2phycfg0.modify(
381 GUSB2PHYCFG::PHYIF.val(1) + GUSB2PHYCFG::USBTRDTIM.val(5), );
384 debug!("DWC3: HS PHY configured as UTMI 16-bit");
385 }
386 UsbPhyInterfaceMode::Unknown => {
387 debug!("DWC3: HS PHY mode unknown, using default configuration");
388 }
389 }
390 }
391
392 async fn phy_setup(&mut self) -> Result<()> {
393 use reg::{GUSB2PHYCFG, GUSB3PIPECTL};
394
395 info!("DWC3: Configuring PHY");
396
397 let is_mode_drd = matches!(
398 self.dwc_regs
399 .globals()
400 .ghwparams0
401 .read_as_enum(GHWPARAMS0::MODE),
402 Some(GHWPARAMS0::MODE::Value::DRD)
403 );
404
405 let gusb3_init = self.dwc_regs.globals().gusb3pipectl0.extract();
408 info!(
409 "DWC3: Initial GUSB3PIPECTL = {:#010x} before config",
410 gusb3_init.get()
411 );
412
413 let mut gusb3 = self.dwc_regs.globals().gusb3pipectl0.extract();
414
415 if self.revistion > DWC3_REVISION_194A {
420 gusb3.modify(GUSB3PIPECTL::SUSPHY::Enable);
421 }
422
423 if is_mode_drd {
424 gusb3.modify(GUSB3PIPECTL::SUSPHY::Disable);
425 }
426
427 if self.u2ss_inp3_quirk {
428 gusb3.modify(GUSB3PIPECTL::U2SSINP3OK::Enable);
429 }
430
431 if self.req_p1p2p3_quirk {
432 gusb3.modify(GUSB3PIPECTL::REQP0P1P2P3::Yes);
433 }
434
435 if self.del_p1p2p3_quirk {
436 gusb3.modify(GUSB3PIPECTL::DEP1P2P3::Enable);
437 }
438
439 if self.del_phy_power_chg_quirk {
440 gusb3.modify(GUSB3PIPECTL::DEPOCHANGE::Enable);
441 }
442
443 if self.lfps_filter_quirk {
444 gusb3.modify(GUSB3PIPECTL::LFPSFILT::Enable);
445 }
446
447 if self.rx_detect_poll_quirk {
448 gusb3.modify(GUSB3PIPECTL::RX_DETOPOLL::Enable);
449 }
450
451 if self.tx_de_emphasis_quirk {
452 gusb3.modify(GUSB3PIPECTL::TX_DEEPH.val(self.tx_de_emphasis as u32));
453 }
454
455 const IS_ROCKCHIP: bool = true;
456 if self.dis_u3_susphy_quirk || IS_ROCKCHIP {
460 gusb3.modify(GUSB3PIPECTL::SUSPHY::Disable);
461 }
462
463 self.dwc_regs.globals().gusb3pipectl0.set(gusb3.get());
464
465 self.hsphy_mode_setup();
467
468 self.kernel().delay(core::time::Duration::from_millis(100));
469
470 let gusb2_init = self.dwc_regs.globals().gusb2phycfg0.extract();
473 info!(
474 "DWC3: Initial GUSB2PHYCFG = {:#010x} before config",
475 gusb2_init.get()
476 );
477
478 let mut gusb2 = self.dwc_regs.globals().gusb2phycfg0.extract();
479
480 if self.revistion > DWC3_REVISION_194A {
485 gusb2.modify(GUSB2PHYCFG::SUSPHY::Enable);
486 }
487
488 if is_mode_drd {
489 gusb2.modify(GUSB2PHYCFG::SUSPHY::Disable);
490 }
491
492 if self.dis_u2_susphy_quirk {
493 gusb2.modify(GUSB2PHYCFG::SUSPHY::Disable);
494 }
495
496 if self.dis_enblslpm_quirk {
497 gusb2.modify(GUSB2PHYCFG::ENBLSLPM::Disable);
498 } else {
499 gusb2.modify(GUSB2PHYCFG::ENBLSLPM::Enable);
500 }
501
502 if self.dis_u2_freeclk_exists_quirk {
503 gusb2.modify(GUSB2PHYCFG::U2_FREECLK_EXISTS::No);
504 }
505
506 self.dwc_regs.globals().gusb2phycfg0.set(gusb2.get());
510
511 self.kernel().delay(core::time::Duration::from_millis(100));
512
513 debug!("DWC3: PHY configuration completed");
514
515 Ok(())
516 }
517
518 fn alloc_scratch_buffers(&mut self) -> Result<()> {
519 if !self.has_hibernation {
520 return Ok(());
521 }
522
523 if self.nr_scratch == 0 {
524 return Ok(());
525 }
526
527 let scratch_size = (self.nr_scratch as usize) * DWC3_SCRATCHBUF_SIZE;
528
529 let scratchbuf = self
530 .kernel()
531 .contiguous_array_zero_with_align(
532 scratch_size,
533 self.kernel().page_size(),
534 DmaDirection::Bidirectional,
535 )
536 .map_err(|_| USBError::NoMemory)?;
537 scratchbuf.prepare_for_device(0..scratchbuf.bytes_len());
538
539 self.scratchbuf = Some(scratchbuf);
540 debug!(
541 "DWC3: Allocated {} scratch buffers (total {} bytes)",
542 self.nr_scratch, scratch_size
543 );
544
545 Ok(())
546 }
547
548 fn setup_scratch_buffers(&mut self) {
549 if let Some(_scratchbuf) = &self.scratchbuf {
550 todo!()
551 }
552 }
553
554 fn core_init_mode(&mut self) -> Result<()> {
555 match self.dr_mode {
556 DrMode::Host => {
557 info!("DWC3: Initializing in HOST mode");
558 self.dwc_regs.globals().gctl.modify(GCTL::PRTCAPDIR::Host);
559 }
560 DrMode::Otg => {
561 todo!()
562 }
563 DrMode::Peripheral => todo!(),
564 }
565
566 Ok(())
567 }
568
569 fn dump_registers(&self) {
571 use reg::*;
572
573 let regs = self.dwc_regs.globals();
574
575 info!("=== DWC3 寄存器状态 ===");
576
577 let gctl = regs.gctl.extract();
579 let gctl_val = gctl.get();
580 info!("GCTL = {:#010x}", gctl_val);
581 let prtcapdir_val = gctl.read(GCTL::PRTCAPDIR);
582 let prtcapdir_str = match prtcapdir_val {
583 0 => "Device",
584 1 => "Host",
585 2 => "OTG",
586 3 => "Reserved",
587 _ => "Unknown",
588 };
589 info!(" PRTCAPDIR = {} ({})", prtcapdir_str, prtcapdir_val);
590
591 let gusb3 = regs.gusb3pipectl0.extract();
593 let gusb3_val = gusb3.get();
594 info!("GUSB3PIPECTL = {:#010x}", gusb3_val);
595 info!(" SUSPHY = {}", gusb3.is_set(GUSB3PIPECTL::SUSPHY));
596 info!(" U2SSINP3OK = {}", gusb3.is_set(GUSB3PIPECTL::U2SSINP3OK));
597 info!(
598 " REQP0P1P2P3 = {}",
599 gusb3.is_set(GUSB3PIPECTL::REQP0P1P2P3)
600 );
601 info!(" DEP1P2P3 = {}", gusb3.is_set(GUSB3PIPECTL::DEP1P2P3));
602
603 let gusb2 = regs.gusb2phycfg0.extract();
605 let gusb2_val = gusb2.get();
606 info!("GUSB2PHYCFG = {:#010x}", gusb2_val);
607 info!(" SUSPHY = {}", gusb2.is_set(GUSB2PHYCFG::SUSPHY));
608 info!(" ENBLSLPM = {}", gusb2.is_set(GUSB2PHYCFG::ENBLSLPM));
609 let phyif = gusb2.read(GUSB2PHYCFG::PHYIF);
610 info!(
611 " PHYIF = {} ({}-bit)",
612 phyif,
613 if phyif == 0 { 8 } else { 16 }
614 );
615 let usbtrdtim = gusb2.read(GUSB2PHYCFG::USBTRDTIM);
616 info!(" USBTRDTIM = {}", usbtrdtim);
617
618 let hwparams0 = regs.ghwparams0.extract();
620 info!("GHWPARAMS0 = {:#010x}", hwparams0.get());
621 let mode_val = hwparams0.read(GHWPARAMS0::MODE);
622 let mode_str = match mode_val {
623 0 => "Gadget",
624 1 => "Host",
625 2 => "DRD",
626 3 => "Reserved",
627 _ => "Unknown",
628 };
629 info!(" MODE = {} ({})", mode_str, mode_val);
630
631 let hwparams1 = regs.ghwparams1.extract();
632 let num_event_buffers = hwparams1.read(GHWPARAMS1::NUM_EVENT_BUFFERS);
633 info!("GHWPARAMS1 = {:#010x}", hwparams1.get());
634 info!(" NUM_EVENT_BUFFERS = {}", num_event_buffers);
635
636 info!("======================");
637 }
638 async fn _init(&mut self) -> Result {
651 info!("DWC3: Starting controller initialization");
652
653 for reset in self.rsts.values() {
656 reset.assert();
657 }
658
659 self.kernel().delay(core::time::Duration::from_millis(1));
660 self.usb2_phy.setup().await?;
662
663 let kernel = self.kernel().clone();
664 self.usb3_phy.setup(&kernel).await?;
665
666 for reset in self.rsts.values() {
667 reset.deassert();
668 }
669
670 self.dwc3_init().await?;
671
672 self.xhci.init().await?;
673
674 self.dump_registers();
676
677 Ok(())
678 }
679}
680
681impl CoreOp for Dwc {
708 fn init(&mut self) -> BoxFuture<'_, Result<()>> {
709 self._init().boxed()
710 }
711
712 fn root_hub(&mut self) -> Box<dyn HubOp> {
713 self.xhci.root_hub()
714 }
715
716 fn create_event_handler(&mut self) -> Box<dyn EventHandlerOp> {
717 Box::new(DwcEventHandler {
718 xhci: self.xhci.create_event_handler(),
719 _dwc: self.dwc_regs.clone(),
720 })
721 }
722
723 fn enable_irq(&mut self) -> Result<()> {
724 self.xhci.enable_irq();
725 Ok(())
726 }
727
728 fn disable_irq(&mut self) -> Result<()> {
729 self.xhci.disable_irq();
730 Ok(())
731 }
732
733 fn new_addressed_device<'a>(
734 &'a mut self,
735 addr: DeviceAddressInfo,
736 ) -> BoxFuture<'a, Result<Box<dyn DeviceOp>>> {
737 self.xhci.new_addressed_device(addr)
738 }
739
740 fn kernel(&self) -> &Kernel {
741 self.xhci.kernel()
742 }
743}
744
745impl Deref for Dwc {
746 type Target = DwcParams;
747
748 fn deref(&self) -> &Self::Target {
749 &self.params
750 }
751}
752
753impl DerefMut for Dwc {
754 fn deref_mut(&mut self) -> &mut Self::Target {
755 &mut self.params
756 }
757}
758
759pub struct DwcEventHandler {
760 xhci: Box<dyn EventHandlerOp>,
761 _dwc: Dwc3Regs,
762}
763impl EventHandlerOp for DwcEventHandler {
764 fn handle_event(&self) -> Event {
765 self.xhci.handle_event()
770 }
771}