跳到主要内容

RK3588 DWC3 与 PHY 初始化

RK3588 的 DWC3 host 路径由平台资源绑定、USB2 PHY、USBDP PHY、DWC3 全局配置和 xHCI 主机组成。drivers/ax-driver/src/usb/dwc.rs 解析平台资源,drivers/usb/usb-host/src/backend/kmod/dwc/ 执行控制器与 PHY 初始化。两处代码分别负责资源来源与硬件操作。

该平台实例对应公共平台资源的 provider 与映射边界,初始化返回和安全停止由生命周期区分。

1. 控制器组成

DWC3 的主机能力通过 xHCI 后端提供,PHY 初始化保留 Rockchip 配置。USB2 和 USB3 使用不同 PHY 对象,不是同一个寄存器块的两种速度配置。

1.1 资源对象

DwcResources 汇总控制器寄存器、时钟、控制器复位、USB2 资源、USBDP 资源和 DwcParams。构造 DwcNewParams 时将映射地址与能力对象交给 crab-usb

RK3588 控制器、PHY 与资源提供者

图中 GRF、PHY MMIO 和 DWC3 MMIO 是不同区域。一个区域可读写不证明其他区域已经具备时钟、复位和映射条件。

1.2 控制器选择

probe 匹配 snps,dwc3 并要求 host 模式。USBDP 编号优先由 usbdpN alias 与节点路径匹配,随后才使用节点名中的 fed80000fed90000 作为 0、1 的回退识别。

usb@fc400000 是仓库 RK3588 guest DTS 中的一个具体实例,不是所有平台必须使用的固定路径。资源实例见节点依赖

2. 资源准备

资源准备先解决节点关系和资源提供者,再映射寄存器与构造核心对象。设备树声明、绑定解析和硬件执行是三个不同证据层次。

2.1 时钟与复位

collect_resources() 处理父控制器节点的 assigned clocks,收集父节点、控制器节点及两个 PHY 的时钟。enable_clocks() 跳过原始 ID 为 0 的条目,对其余条目调用 enable();缺失资源或提供者调用错误通过 probe 返回。

parse_resets() 要求每条 reset 有名字,再包装成 NamedResetLineUsbResetLineassert()deassert() 接口不返回错误,底层复位操作失败时记录警告;不能把后续函数返回 Ok 当作每条 reset 操作都成功的证明。

2.2 PHY 与 GRF

USB2 端口先定位父 PHY,再定位 GRF 父节点;USBDP 使用 rockchip,u2phy-grfrockchip,usb-grfrockchip,usbdpphy-grfrockchip,vo-grfrockchip,dp-lane-mux 作为 lane 配置输入,缺失时使用空向量。

parse_phys() 当前按属性单元顺序取得前两项作为 USB2 和 USB3 phandle,并不按 phy-names 动态重新排序。该假设是当前绑定约束,不能描述为通用任意 PHY specifier 解析器。

3. PHY 硬件操作

USB2 和 USBDP 分别实现端口解除挂起、模拟参数、复位与链路状态等待。配置函数中的等待方式影响启动失败能否及时返回。

3.1 USB2 PHY

usb2phy.rssetup() 先调用配置表中的 tuning,再执行 init()power_on()init() 根据 Usb2PhyPortId 选择端口配置,解除 phy_sus 后延时 2000 μs;当前 power_on() 为空函数,不能描述为已经实现完整供电或 VBUS 稳定状态机。

property_enable() 将配置值与高 16 位写掩码组合后写 GRF。reset() 使用名字为 phy 的复位线,并带有 20 μs、100 μs 的阶段延时;具体是否经过该 helper 需沿 tuning 调用链判断,而不是看到函数存在就认为所有端口都执行。

3.2 USBDP PHY

udphy/mod.rssetup() 先置位配置表中的复位,设置 USB 模式相关 RX LFPS 与低功耗控制,释放 APB 复位,应用初始化序列和 lane 配置,再释放工作模式所需复位。

status_check() 在 USB 模式下等待 PLL 的 AFC_DONELOCK_DONE,随后根据 flip 选择 lane 0 或 lane 2 的 CDR 锁定位。它使用 SpinWhile,其 poll() 在条件仍成立时自唤醒并返回 Pending,没有在这里设置超时。

4. DWC3 与 xHCI 启动

当前 _init() 的函数体是顺序依据。历史分析曾把 PHY 配置安排在 xHCI HCRST 之后,但当前调用链并非如此,不能以旧建议解释现有实现。

4.1 当前顺序

Dwc::_init() 先置位控制器复位并延时 1 ms,执行 USB2、USBDP setup,然后释放控制器复位,调用 dwc3_init(),再调用 xhci.init(),最后打印寄存器状态。

dwc3_init() 分配事件缓冲,执行 core_init() 并设置事件缓冲寄存器。DWC3 事件缓冲与 xHCI Event Ring 不应仅因都称作 event buffer 就视为同一个对象。

4.2 参数与模式

core_init() 读取并校验 DWC3 标识,执行软件复位,处理全局配置、PHY 参数和 host 模式。parse_dwc_params()phy_typeutmiutmi_wide 转为接口模式,并读取代码明确支持的 quirk 属性。

DTS 中出现一个 quirk 不代表当前解析器已经应用它。寄存器读值和源代码注释也不是完整 TRM 的替代资料;访问诊断见PHY 寄存器

5. 初始化结果的边界

初始化返回值、寄存器快照、端口连接和数据传输是逐层增强的证据,不能互相替代。

5.1 可确认结果

probe 成功确认主机对象已构建和发布,PHY setup 返回确认相应代码执行到了返回点,xHCI 初始化完成确认控制器启动流程结束。设备描述符读取与持续传输还依赖 DMA、事件服务和端点状态。

5.2 剩余限制

SpinWhile 等待没有在当前 PHY 状态检查内提供截止时间,复位适配中的错误以警告记录,USB2 power_on() 为空。这些行为分别影响初始化的等待上限、错误传播和供电能力,不能以统一的成功返回覆盖。

2025 年 12 月 30 日的调试记录包含“PHY 寄存器始终为零”等特定实验观察,但缺少与当前代码和完整板卡配置绑定的证据,不能据此宣称 RK3588 所有 PHY 接口寄存器不可访问或当前初始化已完成全部板卡验证。