RK3588 kernel-6.1:drivers/usb/musb 功能与实现要点
源码基准:rk3588/kernel-6.1/drivers/usb/musb/。公开板级配置头:include/linux/usb/musb.h(FIFO、模式、platform_data)。
1. 驱动定位
MUSB / MHDRC(Multipoint Highspeed Dual-Role Controller)是 Mentor Graphics Inventra 系列 USB2 OTG IP 的 Linux 驱动,模块名 commonly musb-hdrc(MUSB_DRIVER_NAME)。
- 主机:实现
usb_hcd,经musb_host.c+musb_virthub.c接入usbcore(含软件实现的 root hub)。 - 设备:实现
usb_gadget/usb_ep,见musb_gadget.c、musb_gadget_ep0.c。 - 双角色:Kconfig
USB_MUSB_DUAL_ROLE同时编进主机与 Gadget;配合DEVCTL、VBUS/ID、usb_phy/struct phy与 glue 层set_mode等在主机与外设间切换。
与 RK3588:Rockchip RK3588 片上 USB 以 DWC3 / xhci 等为主流;drivers/usb/musb 无 Rockchip glue。Arm64 defconfig 里可能出现 CONFIG_USB_MUSB_SUNXI 等其它 SoC 选项,不代表 RK3588 产品路径。分析本目录仍以 IP 与软件架构 为主。
2. 构建结构(Makefile)
| 目标 | 内容 |
|---|---|
musb_hdrc |
musb_core.o(核心 + 中断/会话)、musb_trace.o |
| Host / DRD | musb_host.o、musb_virthub.o(CONFIG_USB_MUSB_HOST 或 DUAL_ROLE) |
| Gadget / DRD | musb_gadget.o、musb_gadget_ep0.o |
| Debug | musb_debugfs.o(CONFIG_DEBUG_FS) |
| Glue(平台一块) | omap2430.o、am35x.o、musb_dsps.o、sunxi.c、mediatek.c、davinci.c、da8xx.c、tusb6010*.c、ux500*.c、jz4740.c、mpfs.c 等,二选一/多选一 与具体 SoC 绑定 |
| DMA | musbhsdma.o(Inventra)、cppi_dma.o / musb_cppi41.o(TI)、tusb6010_omap.o、ux500_dma.o;MUSB_PIO_ONLY 可强制纯 PIO(EP0 等路径仍靠 CPU) |
Kconfig 要求 PIO 与多种 DMA 方案互斥编译,运行时也可用 use_dma=n 模块参数关闭 DMA(注释见 Kconfig)。
3. 核心抽象(musb_core.h / musb_core.c)
3.1 struct musb
驱动实例的中心结构,主要包括:
- 寄存器与 IO:
mregs、ctrl_base;musb_platform_ops封装 索引式/扁平式 EP 寻址、FIFO 读写、W1C 行为差异 等。 - 硬件端点:
endpoints[MUSB_C_NUM_EPS],每项为struct musb_hw_ep(FIFO 指针、TXCSR/RXCSR、主机侧musb_qh队列首指针、Gadget 侧musb_epin/out)。 - 主机调度队列:控制、
in_bulk/out_bulk、pending_list;bulk_ep指向用于批量传输的专用 HW EP。 - DMA:
dma_controller(抽象dma_channel,见musb_dma.h)。 - PHY:
xceiv(usb_phy)与phy(Generic PHY),glue 可选phy_callback。 - 模式:
is_host、session、port_mode(来自usb_get_dr_mode的musb_get_mode)、OTG 定时器。 - 工作队列/延时工作:IRQ bottom half(
irq_work)、复位/resume/gadget 相关延后任务。
文件头部注释明确:硬件不做主机侧事务调度,需软件调度;多设备/hub 场景能力受限(批量端点占用、NAK、带宽记账不足等),调试时需心里有数。
3.2 struct musb_platform_ops(Glue 契约)
平台 glue 必须提供的能力包括:enable/disable、ep_offset/ep_select、read_fifo/write_fifo(或与默认 musb_io 组合)、可选 dma_init/dma_exit、set_mode、set_vbus、recover(babble)等。quirks 位标明 TUSB6010、indexed EP、各类 DMA 引擎 等,核心与 DMA 文件据此分支。
3.3 中断与会话
核心集中处理 USB/TX/RX 等中断标志,再分到主机或 Gadget;isr 可被 glue 先行过滤。ULPI 读写(musb_ulpi_read/write)通过 usb_phy 的 io_priv 访问 MHDRC 内 ULPI .viewport。
4. 主机路径(musb_host.c)
hcd_to_musb:hcd->hcd_priv指向struct musb *。- 调度模型:注释说明 控制走 EP0;批量占用专用 IN/OUT 硬件 EP(理论上可扩展更多批量 EP,实现仍偏保守);中断/等时动态绑定其余 EP,调度策略偏「朴素」。
- 队列头
musb_qh:挂urb,配合musb_ep_program填TXCSR/RXCSR、长度、toggle(get_toggle/set_toggle可平台定制)。 - FIFO:主机发送前可能
musb_h_tx_flush_fifo,避免 BABBLE(注释含 AM335x 等平台已知竞态)。
musb_virthub.c:实现 root hub 端口状态、复位、resume 等与 usbcore 的交互(MUSB 端口能力与标准 EHCI/xHCI 不同,由软件 hub 适配)。
5. Gadget 路径(musb_gadget*.c)
musb_ep包装usb_ep,请求为musb_request(内嵌usb_request)。- EP0 状态机:
enum musb_g_ep0_state(SETUP → DATA → STATUS),与主机侧musb_h_ep0_state对称,由核心 IRQ 与控制寄存器驱动。
6. DMA 抽象(musb_dma.h + musbhsdma.c 等)
struct dma_controller:分配通道、绑定 HW EP 与方向、处理 short packet / buffer full、在 DMA 完成中断里唤醒上层。
不同 SoC 寄存器块不同(如 Inventra HSDMA 基址 MUSB_HSDMA_BASE);Host 侧 DMA 映射由 usbcore 侧准备,Gadget 侧由 gadget 框架准备(头文件注释)。
7. 小结表
| 维度 | 说明 |
|---|---|
| 硬件 IP | Mentor Inventra USB2 OTG(多版本 HWVER) |
| 对上接口 | Host:usb_hcd;Device:usb_gadget |
| 关键软件对象 | struct musb、musb_hw_ep、musb_qh、DMA controller |
| 平台差异 | 全部由 musb_platform_ops + glue .c 吸收(FIFO 布局、中断共享、PHY、DMA) |
| RK3588 | 无 musb glue;主线 USB 以 DWC3 等为主,本目录用于理解 Inventra/MUSB 或维护 Allwinner/TI/MediaTek 等平台 |
若要对照寄存器,可结合 musb_regs.h 与具体 SoC TRM;若要跟踪一次 URB 从 musb_urb_enqueue 到 FIFO/DMA 的路径,可从 musb_host.c 中 musb_urb_submit / musb_schedule 一类符号向下追。
正在加载留言…