RK3588 kernel-6.1:drivers/usb/renesas_usbhs 功能与实现要点
源码基准:rk3588/kernel-6.1/drivers/usb/renesas_usbhs/。
1. 驱动定位与适用平台
Renesas USBHS 是瑞萨 SoC 上常见的 USB 2.0 全速/高速 控制器 IP,可在同一硬件上工作在 主机(Host) 或 设备(Gadget/Peripheral) 角色(典型 OTG/DRD 用法由平台与 extcon/ID/VBUS 逻辑配合)。
CONFIG_USB_RENESAS_USBHS:核心框架(依赖USB_GADGET,平台依赖ARCH_RENESAS || SUPERH || COMPILE_TEST)。CONFIG_USB_RENESAS_USBHS_HCD:在drivers/usb/host/Kconfig中启用 HCD,编译进同一目标renesas_usbhs.o时追加mod_host.o。CONFIG_USB_RENESAS_USBHS_UDC:在drivers/usb/gadget/udc/Kconfig中启用 UDC,追加mod_gadget.o。
与 RK3588 的关系:RK3588 为 Rockchip,通常使用 DWC3/xHCI 等控制器;本目录代码 不会作为 RK3588 默认 USB 栈,仅在分析内核树或 COMPILE_TEST 时会被编译到。文档沿用仓库「kernel-6.1 源码索引」的命名习惯。
2. 源码模块划分(Makefile)
| 对象 | 职责概要 |
|---|---|
common.c |
platform 驱动入口、usbhs_priv、MMIO 读写、SYSCFG/总线/VBUS、设备地址寄存器、extcon + 延迟 work 热插拔、时钟/复位/pm_runtime |
mod.c |
Host/Gadget 模块注册、usbhs_mod_info、共享 IRQ usbhs_interrupt、irq 回调屏蔽与分发;autonomy(无平台 notify_hotplug 时用 VBINT 自行调度热插拔) |
pipe.c / pipe.h |
**Pipe(硬件管道)**抽象:类型、方向、运行状态、与 FIFO 绑定、DATA0/1 序列、stall、maxpacket 等 |
fifo.c / fifo.h |
**FIFO / 包(usbhs_pkt)**队列:PIO/DMA 路径、prepare/try_run、done 回调 |
mod_host.c |
usb_hcd 适配:URB ↔ pipe、usbhsh_* 结构与 pipe 复用策略 |
mod_gadget.c |
usb_gadget / usb_ep 适配、setup 与各 recipient 控制传输 |
rcar2.c / rcar3.c |
R-Car Gen2/Gen3 等平台:phy、DMAC 能力、driver_param(pipe 配置等) |
rza.c / rza2.c |
RZ/A 系列差异化 |
common.c 开头的示意图概括了 mod_* ↔ pipe ↔ fifo 的数据通路。
3. 分层与数据路径(实现原理)
3.1 硬件抽象:usbhs_priv + 平台回调
公开头文件 include/linux/usb/renesas_usbhs.h 定义 renesas_usbhs_platform_callback:
hardware_init/hardware_exit、power_ctrl、phy_resetget_id:返回USBHS_HOST或USBHS_GADGETget_vbus:VBUS 是否有效set_vbus(主机供电)、可选notifier(extcon 相关)
以及 renesas_usbhs_driver_param(pipe 个数、是否 USB-DMAC、runtime_pwctrl、detection_delay 等),由各 SoC 的 *_plat_info 填入。
3.2 Pipe 与 FIFO
struct usbhs_pipe:对应控制器里的逻辑管道(非 Linux URB 一对一);带handler(包处理)、fifo指针、mod_private(host/gadget 私有)。usbhs_pkt:挂在 pipe 的链表上,由fifo.c驱动实际收发(含 DMA map 控制钩子)。
3.3 中断:usbhs_interrupt(mod.c)
- 读取并组装
usbhs_irq_state(INTSTS0/1、BRDYSTS、NRDYSTS、BEMPSTS)。 - 按手册要求 写清除 中断位(注释强调 INTSTS0_MAGIC / INTSTS1_MAGIC 等敏感性)。
- 按当前模式调用
struct usbhs_mod中的回调:设备状态(DVST)、控制阶段(CTRT)、FIFO 空/就绪(BEMP/BRDY);主机模式额外处理 ATTCH/DTCH/SIGN/SACK。 usbhs_irq_callback_update根据当前 mod 动态开关 INTENB / BEMPENB / BRDYENB,避免与硬件行为冲突。
3.4 角色与热插拔:usbhsc_hotplug(common.c)
- 通过
get_vbus/get_id决定是否上电、选择 Host 或 Gadget,再调用对应 mod 的start/stop。 - 若 DTS 带
extconphandle,会用extcon_get_state(..., EXTCON_USB_HOST)与get_id结果做一致性检查,不匹配则拒绝切入以免角色错误。 - 从中断等上下文调用
usbhsc_schedule_notify_hotplug,用 delayed work 落到进程上下文执行(避免在中断里做复杂切换)。
Autonomy 模式(mod.c):平台未提供「notify」路径时,用 VBINT 自行 schedule_delayed_work,并自带 get_vbus(读 INTSTS0 的 VBSTS),时钟常开。
4. 主机侧要点(mod_host.c)
- 通过
struct usb_hcd接入usbcore,注释明确写出硬件限制:- 可管理设备数量有限(约 9 台量级,与
DEVADDn等一致)。 - Pipe 数量有限且复用:多个下游设备的 endpoint 会 时分复用 同一 pipe,软件需维护各设备的 DATA0/1(见文件头部示意图与说明)。
- 可管理设备数量有限(约 9 台量级,与
usbhsh_device/usbhsh_ep:把usb_device/usb_host_endpoint映射到usbhs_pipe。
5. Gadget 侧要点(mod_gadget.c)
struct usbhsg_gpriv内嵌usb_gadget与usbhs_mod,每个usbhsg_uep绑定一个usbhs_pipe。- 控制传输与各标准 recipient(device/interface/endpoint)由
usbhsg_recip_handle分发表处理;状态位(started、registered、wedge、self-powered、soft-connect)配合usb_phy/VBUS。
6. 设备树匹配(common.c:usbhs_of_match)
兼容字符串覆盖多个瑞萨芯片与通用别名,例如:
renesas,usbhs-r8a7790、renesas,rcar-gen2-usbhs→usbhs_rcar_gen2_plat_inforenesas,usbhs-r8a7795、renesas,rcar-gen3-usbhs→usbhs_rcar_gen3_plat_inforenesas,rza1-usbhs、renesas,rza2-usbhs→ RZ/A 平台信息
Gen2 示例(rcar2.c):通过 Generic PHY 做 phy_init / phy_power_on,并声明 has_usb_dmac、has_new_pipe_configs 等能力位。
7. 小结
| 维度 | 说明 |
|---|---|
| 协议层 | USB 2.0 FS/HS;不实现 USB3 |
| 软件栈 | Host:usb_hcd + usbcore;Device:usb_gadget + composite/功能驱动 |
| 核心抽象 | Pipe + FIFO + pkt 队列;IRQ 统一入口再分发给 Host/Gadget |
| DRD/OTG 协作 | 平台 get_id/get_vbus + 可选 extcon + 延迟 work;可选 autonomy VBINT |
| 平台差异 | R-Car Gen2/3、RZ/A 通过 renesas_usbhs_platform_info 区分 PHY、DMAC、pipe 表与时序参数 |
若要对照寄存器级行为,需结合瑞萨 USBHS 用户手册(SYSCFG、PIPE/DCP、FIFO、中断屏蔽与清除顺序);本驱动注释中已标出若干「硬件挑剔」的写入顺序,调试 IRQ/FIFO 问题时应优先核对。
正在加载留言…