RK3588 kernel-6.1 drivers/usb/dwc3 详细分析:与 USB 3.0 协议的关系及实现方式

RK3588 kernel-6.1 drivers/usb/dwc3 详细分析:与 USB 3.0 协议的关系及实现方式

1. 文档范围

  • 目录rk3588/kernel-6.1/drivers/usb/dwc3/
  • 配置CONFIG_USB_DWC3(模块化时常为 dwc3.ko
  • 硬件:Synopsys DesignWare USB3 Dual-Role Device(DWC_usb3 / DWC_usb31 等) IP。

本文说明:该目录代码如何实现「接上一套 USB3 主机/设备」,以及 USB 3.0 / SuperSpeed 协议内核分工——这一点与 dwc2(自带完整 USB2 HCD显著不同


2. 关键结论:USB 3.0「协议」主要由谁实现?

2.1 主机模式(SuperSpeed Host)

drivers/usb/dwc3 在主机模式下不是另一套 USB3 协议栈,而是:

  1. 配置 DWC3 IP:端口能力 Host、PHY、时钟、全局寄存器、部分 errata。
  2. 把片上 xHCI 寄存器窗口 作为子设备资源交给内核标准 xHCI 主机驱动

host.c 文件头即为 Host Glue,实现 dwc3_host_init():创建 platform_device 名称 "xhci-hcd",填入 MMIO + IRQ,并挂上 xhci_plat_priv 等数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int dwc3_host_init(struct dwc3 *dwc)
{
...
xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
...
xhci->dev.parent = dwc->dev;

dwc->xhci = xhci;

ret = platform_device_add_resources(xhci, dwc->xhci_resources,
DWC3_XHCI_RESOURCES_NUM);
...
props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-sg-trb-cache-size-quirk");

if (dwc->usb3_lpm_capable)
props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable");
...
if (DWC3_VER_IS_WITHIN(DWC3, ANY, 300A))
props[prop_idx++] = PROPERTY_ENTRY_BOOL("quirk-broken-port-ped");
...
ret = platform_device_add_data(xhci, &dwc3_xhci_plat_quirk,
sizeof(struct xhci_plat_priv));
...
ret = platform_device_add(xhci);

因此:链路训练(LTSSM)、SuperSpeed 端点上下文、TRB 环、U1/U2/U3 等,主要由 drivers/usb/host/xhci*.c + 片内 xHCI 逻辑 完成;dwc3/host.c 负责 集成与 quirk 属性,而非重写规范全文。

2.2 设备模式(SuperSpeed Device / Gadget)

gadget.cep0.c 实现 struct usb_gadget,通过 设备寄存器区core.hDWC3_DEVICE_REGS_*)下发 DEPCMD(如 STARTTRANSFER)、构造 TRB,处理 事件缓冲(Event Buffer) 中的 CONNECT / RESET / LINK STATUS 等事件。

这里更接近 USB 3.0 设备控制器编程模型(SuperSpeed 链路状态控制传输阶段批量/中断/同步 TRB),但仍与 linux/usb/gadget、复合设备上层协作,而不是在用户态单独实现完整协议栈。

2.3 USB 2.0 兼容路径(主机)

DWC3 + xHCI 集成方案中,USB2 Root Hub 端口同样由 xHCI 调度(含 HS/FS/LS 分裂事务等),dwc3 侧主要通过 PHY(USB2/UTMI)GUSB2PHYCFG 等与电气层协作。


3. 寄存器内存布局(理解 Host/Device 分界)

core.h 定义(节选):

1
2
3
4
5
6
7
8
#define DWC3_XHCI_REGS_START		0x0
#define DWC3_XHCI_REGS_END 0x7fff
#define DWC3_GLOBALS_REGS_START 0xc100
#define DWC3_GLOBALS_REGS_END 0xc6ff
#define DWC3_DEVICE_REGS_START 0xc700
#define DWC3_DEVICE_REGS_END 0xcbff
#define DWC3_OTG_REGS_START 0xcc00
#define DWC3_OTG_REGS_END 0xccff
偏移区间 典型用途
0x00000x7fff xHCI MMIO(由 xhci-hcd 映射)
0xc100 全局控制GCTL、FIFO、事件缓冲地址、PHY 配置等)
0xc700 设备模式端点命令与状态
0xcc00 OTG(双角色、会话等)

core.cdwc3_probe 刻意 不把整段 MEM 都 map 给 dwc3,而是:

  • xhci_resources[0]:整段物理内存资源里 低地址部分 交给子设备 xHCI
  • dwc_res.start += DWC3_GLOBALS_REGS_START仅从全局寄存器起始 ioremap,供 dwc3 读写 非 xHCI 区域。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
dwc->xhci_resources[0].start = res->start;
dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
DWC3_XHCI_REGS_END;
dwc->xhci_resources[0].flags = res->flags;
dwc->xhci_resources[0].name = res->name;

/*
* Request memory region but exclude xHCI regs,
* since it will be requested by the xhci-plat driver.
*/
dwc_res = *res;
dwc_res.start += DWC3_GLOBALS_REGS_START;

regs = devm_ioremap_resource(dev, &dwc_res);

这样避免 父驱动与子 xHCI 重复映射同一 MMIO


4. core.c — DRD 核心初始化与模式切换

4.1 dwc3_core_init()

典型步骤包括:GUIDPHY(USB2/USB3 + generic phy)软复位全局控制 dwc3_core_setup_global_control端点数量 dwc3_core_num_epsScratch Buffer帧长/参考时钟burst 类型事件缓冲 dwc3_event_buffers_setup 等。

Gadget 与部分全局特性依赖 事件缓冲;主机侧 xHCI 由子驱动自行初始化。

4.2 dwc3_core_init_mode() / dwc3_set_prtcap() / __dwc3_set_mode

根据 dr_mode(或 OTG)选择 DWC3_GCTL_PRTCAP_HOST / DEVICE / OTG

  • Hostdwc3_host_init(),设置 PHY PHY_MODE_USB_HOST,可选 GUCTL3_SPLITDISABLE 等 quirk。
  • Device:软复位设备侧、dwc3_event_buffers_setup()PHY Devicedwc3_gadget_init()
  • OTGdwc3_otg_init()(见 drd.c)。

dwc3_set_mode() 在 OTG 下通过 workqueue 异步切换到期望角色,必要时 CoreSoftReset(代码针对不同 IP 版本有时间等待说明)。


5. 各源文件职责一览

文件 作用
core.c Probe/remove、时钟/复位、xHCI 资源拆分dwc3_core_*Rockchip RK3588 utmi/pipe 时钟、电源/runtime、与 drd/gadget/host 衔接。
core.h / io.h 寄存器与位域、内联读写。
host.c 注册 xhci-hcd platform 设备、IRQ 名字 fallback、plat_startdwc3_enable_susphy、向 xHCI 注入 software node properties(quirk/LPM)
gadget.c Gadget 主体:端点启用/停用、TRB链路状态、ISO/批量队列、事件处理与会 usb_gadget API 对接。
ep0.c EP0 控制传输:SETUP/DATA/STATUSdwc3_ep0_prepare_one_trbSTARTTRANSFER
gadget.h Gadget 内部结构与声明。
drd.c OTGOEVT 中断、extcon、与 dwc3_set_mode 协作;OTGRELATED 注释说明避免 xHCI HCRST 误伤 PHY/OTG(OCFG_SFTRSTMASK)。
ulpi.c ULPI PHY 路径(可选 USB_DWC3_ULPI)。
debugfs.c 调试。
trace.c / trace.h tracepoint(CONFIG_TRACING)。
dwc3-*.c 板级 glue:时钟树、供电、wrapper 节点差异(如 dwc3-of-simple.crockchip,rk3399-dwc3 的 reset 顺序等)。

6. Gadget 侧与 USB 3.0 设备的对应关系(精简)

  • 链路dwc3_gadget_get_link_state / set_link_state 对应 DSTS 中的 USB LINK STATE(规范中的 U0/U1/U2/U3 等),用于电源管理与恢复。
  • 传输:非 EP0 端点在 gadget.c 中构造 TRB,通过 dwc3_send_gadget_ep_cmd 提交 端点命令;SuperSpeed 大包默认 burst 等与 DWC3_DEPCFG 建立的端点属性一致。
  • EP0ep0.c 使用专用 ep0_trb,与 Chapter 9 控制传输 三阶段对齐。

core.h 中的 设备事件类型(如 CONNECT_DONE、LINK_STATUS_CHANGE、WAKEUP、Suspend)对应 DWC3 事件缓冲解析(SuperSpeed 连接完成复位后的速度协商结果等由硬件上报,驱动转成交互)。


7. RK3588 / Rockchip 相关代码位置

  • dwc3_get_clocks():注释 「specific to Rockchip RK3588」,增加 utmipipe 可选时钟。
  • dwc3_probe 末尾:对 Rockchip OTG 兼容字符串(rockchip,rk3399-dwc3rockchip,rk3576-dwc3)有 runtime / extcon 特殊路径(RK3588 常与类似 glue 共用策略,需结合具体 DTS)。
  • dwc3-of-simple.crockchip,rk3399-dwc3PHY 初始化前 可能需要 usb3-otg reset

板级仍以 snps,dwc3 子节点 + dwc3-of-simple(或厂商 wrapper)为准。


8. 与 dwc2usbcore 的对比记忆

项目 DWC3(主机) DWC2(主机)
USB3 SuperSpeed xHCI 驱动 + IP 内 xHCI 不适用(USB2-only IP)
drivers/usb/dwc3 主机代码量 glue(host.c)为主 完整 hcd*.c 队列/通道
枚举 / Hub / URB(逻辑) drivers/usb/core 同左

9. 延伸阅读(本仓库)

文档
drivers-usb-dwc2详细分析.md
drivers-usb-core详细分析.md
USB总线枚举匹配与数据传输分析.md

内核主线中与 SuperSpeed 主机强相关的另一目录:drivers/usb/host/xhci*.c)。


基于 rk3588/kernel-6.1/drivers/usb/dwc3core.h/host.c/core.c 整理;IP 级细节以 Synopsys DWC_usb3 编程手册与 SoC TRM 为准。

文章互动

阅读 --

留言

0 条留言

正在加载留言…