跳到主要内容

RK3588 USB 主机发现与设备枚举

RK3588 USB 设备可用需要经过两层发现:rdrive 根据 FDT 创建 DWC3 主机,crab-usb 在主机启动后枚举根端口和外部 hub。前者发现控制器,后者发现总线外设,不能用一次 probe 成功代替完整 USB 枚举。

主机探测对应公共探测与初始化,主机之后的枚举对应运行时与完成,二者在 USB 中连续发生但维护不同状态。

1. 控制器发现

平台绑定位于 drivers/ax-driver/src/usb/dwc.rs,注册项匹配 snps,dwc3,使用普通设备阶段和默认优先级。回调只接管明确声明 dr_mode = host 的节点。

1.1 模式与资源匹配

probe() 对其他模式以及缺失 dr_mode 的节点返回 OnProbeError::NotMatch。随后 collect_resources() 读取控制器寄存器、USB2 PHY、USBDP PHY、时钟、命名复位和 DWC 参数。

PHY 并不是由控制器地址推算出的固定伴随区域。USB2 资源经 PHY 端口和父节点查找 GRF,USBDP 资源使用多个 rockchip,*-grf phandle;依赖格式不满足时,probe 返回错误。

1.2 主机发布

USBHost::new_dwc(DwcNewParams) 构造 DWC 后端,register_usb_host() 发布 PlatformUsbHost 并记录 IRQ 来源。主机包装中存在事件 handler 与绑定信息,不等于主机已经扫描出设备。

DWC3 资源解析与主机发布

rockchip-dwc-xhci feature 只决定该回调和依赖进入镜像。实际节点的模式、PHY 拓扑和资源提供者决定能否构造主机。

2. 主机初始化

主机初始化跨越 Rockchip PHY、DWC3 和 xHCI。backend/kmod/dwc/mod.rs_init() 是当前执行顺序的依据,不能以旧调试记录或函数上方过时的顺序注释替代函数体。

2.1 PHY 与 DWC3

当前顺序为控制器复位置位、延时 1 ms、USB2 PHY setup、USBDP PHY setup、控制器复位释放、dwc3_init()dwc3_init() 分配事件缓冲并调用 core_init(),后者包含 phy_setup() 和 host 模式配置。

USB2 init() 在解除 PHY suspend 配置后延时 2000 μs。USBDP status_check() 在 USB 模式等待 PLL 的 AFC 与 LOCK 位,并根据 lane 方向等待对应 CDR 锁定;这些等待不是“尚未实现”的功能。

2.2 xHCI 与根 hub

DWC3 初始化之后调用 xhci.init(),最后打印寄存器。xhci/host.rs_init() 建立控制器运行所需寄存器与环状态;通用 Core::init() 调用后端初始化并建立 root hub。

DWC3 的 PHY 配置在当前函数体中发生于 xhci.init() 之前。这里记录实现顺序,不把历史文档中的相反建议声明为硬件规范。

3. 端口与设备枚举

backend/kmod/kcore.rsCore 保存 hub 集合、拓扑位置和已初始化设备。枚举返回连接及断开变化,而不是简单返回一份永远有效的设备指针数组。

3.1 端口连接

_probe_devices() 遍历当前 hub,取得各自端口事件。连接事件交给 connect_port();该方法先拒绝已占用拓扑位置,再构造 DeviceAddressInfo,由后端创建已寻址设备。

xHCI 后端分配 slot、填写设备上下文并使用控制端点读取描述符。root_port_idport_idport_speed 和父 hub 信息在这一步共同决定寻址输入;Route String 的计算见xHCI 拓扑路由

3.2 hub 与普通设备

HubDevice::is_hub() 根据设备及配置描述符识别 hub。hub 分支创建并初始化 HubDevice、分配 HubId、保存 child_hub;普通设备分支将对象放入 inited_devices。二者均记录 (parent_hub, port_id) 的连接位置。

新 hub 会触发后续扫描,使枚举覆盖其下游设备。不能将直接连接根端口的成功结果扩大为多级 hub 或所有 USB 速度均已验证。

4. 系统消费与事件服务

控制器事件推进与用户态枚举视图相互关联,但不处于同一执行位置。IRQ 服务必须先能交付命令和传输完成,异步枚举才能从等待中继续。

4.1 打开设备

src/host.rsUSBHost::open_device() 请求后端取得设备对象,再初始化面向调用者的 Device。描述符快照用于识别设备,不拥有任意重开次数的硬件控制权。

StarryOS 的 os/StarryOS/kernel/src/pseudofs/usbfs/manager.rs 组织主机与设备管理,tree.rs 保存对外树结构,irq.rs 连接事件处理。Linux 用户态 USBFS 行为在系统层实现,不属于 DWC3 PHY 初始化。

4.2 断开与故障定位

disconnect_port() 处理连接位置及后代,枚举结果记录 disconnected 集合。上层需要撤销对应视图和请求,不能继续把旧软件 device ID 作为当前硬件存在的证明。

现象首先对应的源码阶段需要区分的状态
未出现主机注册日志dwc.rs::probefeature、模式匹配、资源解析
卡在 PHY 初始化Usb2Phy::setupUdphy::setup时钟、复位、锁定位等待
命令等待不结束xHCI command 与 event 路径doorbell、DMA、IRQ 和完成地址
根端口有连接但无设备connect_port、xHCI address速度、EP0、上下文和描述符
外部 hub 下设备缺失hub 初始化和再次扫描hub 描述符、端口变化、拓扑深度
断开后仍出现旧设备disconnect_port 与系统视图子树撤销和上层引用

早期文档以 U-Boot 的 usb start 命令调用链解释 RK3588;该命令不是当前 TGOSKits 的主机入口。U-Boot 对照的版本与证据边界单独记录在初始化对照