4. USB控制器设备树绑定:常见USB控制器(如DWC2、DWC3、Chipidea)的设备树节点定义与属性
在嵌入式Linux系统中,USB Gadget功能的实现高度依赖于底层USB控制器的正确配置。设备树(Device Tree)是描述硬件拓扑和资源的关键手段,对于USB控制器而言,设备树节点定义了其寄存器地址、中断号、时钟、电源管理、DMA以及USB 2.0/3.0相关的属性。本章将深入剖析三种主流USB控制器——DWC2(常用于STM32MP1、Allwinner)、DWC3(常用于TI AM64x、Qualcomm、Rockchip)和Chipidea(常用于NXP i.MX系列)——的设备树绑定规范,并提供可直接参考的节点定义与属性说明。
实践提示: 设备树中的USB控制器节点通常位于SoC的
soc 节点下,其 compatible 属性是内核匹配驱动入口的关键。错误的 compatible 字符串将导致驱动无法加载,Gadget功能完全失效。
4.1 DWC2控制器设备树绑定
DWC2(DesignWare USB 2.0 OTG Controller)是广泛使用的USB 2.0 OTG控制器,支持Host、Device(Gadget)和OTG模式。其设备树节点需要明确指定操作模式、DMA掩码、以及物理接口类型。
4.1.1 核心属性与节点结构
| 属性名 | 类型 | 描述 | 是否必需 |
|---|---|---|---|
compatible |
string | 必须包含 "snps,dwc2",可附加SoC特定兼容字符串 |
是 |
reg |
address-cells | 寄存器基地址和长度,通常为0x1000 | 是 |
interrupts |
interrupt-specifier | USB控制器中断号 | 是 |
dr_mode |
string | 操作模式:"host"、"peripheral"、"otg" |
是 |
g-rx-fifo-size |
u32 | 接收FIFO大小(单位:DWORD) | 推荐 |
g-np-tx-fifo-size |
u32 | 非周期性发送FIFO大小 | 推荐 |
g-tx-fifo-size |
u32数组 | 周期性发送FIFO大小(每个端点一个值) | 推荐 |
clocks |
phandle | 时钟句柄,通常包含OTG时钟和总线时钟 | 是 |
phys |
phandle | PHY句柄,用于USB物理层控制 | 推荐 |
4.1.2 典型设备树节点示例
usb_otg: usb@49000000 {
compatible = "snps,dwc2";
reg = <0x49000000 0x10000>;
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_OTG>, <&ccu CLK_OTG>;
clock-names = "bus", "otg";
resets = <&ccu RST_BUS_OTG>;
reset-names = "bus";
dr_mode = "peripheral";
g-rx-fifo-size = <512>;
g-np-tx-fifo-size = <32>;
g-tx-fifo-size = <256 128 128 64 64 32>;
phys = <&usbphy0>;
phy-names = "usb2-phy";
status = "okay";
};
关键点: 当
dr_mode = "peripheral" 时,DWC2仅作为Gadget设备工作,内核将不会初始化Host相关逻辑。FIFO大小的配置直接影响批量传输和等时传输的稳定性,建议根据实际端点数量和使用场景调整。
4.1.3 DWC2 Gadget模式数据流
4.2 DWC3控制器设备树绑定
DWC3(DesignWare USB 3.0 Controller)是高性能USB 3.0/3.1控制器,支持SuperSpeed和SuperSpeedPlus。其设备树绑定比DWC2更复杂,需要额外处理USB 3.0 PHY、LPM(链路电源管理)以及多端口配置。
4.2.1 核心属性与差异
| 属性名 | 类型 | 描述 | DWC3特有 |
|---|---|---|---|
compatible |
string | 必须包含 "snps,dwc3" |
否 |
reg |
address-cells | 寄存器基地址,通常包含两个区域:core和glue | 否 |
interrupts |
interrupt-specifier | 中断号,可能包含多个(如dwc3和dwc3_event) | 否 |
dr_mode |
string | 同DWC2,支持 "host"、"peripheral"、"otg"、"dual" |
否 |
snps,dis_u3_susphy_quirk |
boolean | 禁用USB 3.0 PHY挂起,解决某些PHY的兼容性问题 | 是 |
snps,dis_u2_susphy_quirk |
boolean | 禁用USB 2.0 PHY挂起 | 是 |
snps,usb3_lpm_capable |
boolean | 使能USB 3.0 LPM(链路电源管理) | 是 |
snps,has-lpm-erratum |
boolean | 启用LPM errata工作区 | 是 |
phys |
phandle数组 | 通常包含两个PHY:usb2-phy和usb3-phy | 是 |
phy-names |
string数组 | 对应 "usb2-phy" 和 "usb3-phy" |
是 |
maximum-speed |
string | 限制最高速度:"super-speed-plus"、"super-speed"、"high-speed" |
否 |
4.2.2 典型设备树节点示例(含glue层)
usb: usb@ff600000 {
compatible = "ti,am64-dwc3", "snps,dwc3";
reg = <0x0 0xff600000 0x0 0x10000>;
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&k3_clks 151 0>, <&k3_clks 151 1>;
clock-names = "bus", "ref";
power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>;
ti,syscon-phy-pll-refclk = <&scm_conf 0x4000>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
dwc3: dwc3@ff600000 {
compatible = "snps,dwc3";
reg = <0x0 0xff600000 0x0 0x10000>;
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "peripheral";
maximum-speed = "super-speed";
snps,dis_u3_susphy_quirk;
snps,dis_u2_susphy_quirk;
snps,usb3_lpm_capable;
phys = <&usb0_phy>, <&usb0_phy>;
phy-names = "usb2-phy", "usb3-phy";
tx-fifo-resize;
status = "okay";
};
};
常见陷阱: DWC3的
phys 属性通常需要两个PHY句柄,即使只使用USB 2.0模式也必须提供usb2-phy。如果PHY未正确初始化,DWC3驱动在probe阶段会返回-EPROBE_DEFER,导致设备无法注册。此外,snps,dis_u3_susphy_quirk 在TI AM64x平台上必须设置,否则PHY挂起后无法恢复。
4.2.3 DWC3 Gadget模式与PHY交互
4.3 Chipidea控制器设备树绑定
Chipidea(现已被NXP收购,常见于i.MX系列)是另一种广泛使用的USB 2.0 OTG控制器。其设备树绑定与DWC2有相似之处,但具有独特的 ci-hdrc 驱动框架和 phy 接口。
4.3.1 核心属性与配置
| 属性名 | 类型 | 描述 | 示例值 |
|---|---|---|---|
compatible |
string | 必须包含 "fsl,imx6q-usb" 或 "chipidea,usb2" |
"fsl,imx6q-usb", "fsl,imx27-usb" |
reg |
address-cells | 寄存器基地址,长度通常为0x200 | <0x02184000 0x200> |
interrupts |
interrupt-specifier | 中断号 | <0 43 IRQ_TYPE_LEVEL_HIGH> |
dr_mode |
string | 同DWC2,支持 "host"、"peripheral"、"otg" |
"peripheral" |
phy_type |
string | PHY类型:"utmi"、"ulpi"、"serial" |
"utmi" |
fsl,usbphy |
phandle | 指向USB PHY节点的句柄 | <&usbphy1> |
fsl,usbmisc |
phandle | 指向USB misc控制器的句柄(用于电源和ID检测) | <&usbmisc 0> |
disable-over-current |
boolean | 禁用过流检测 | 存在即生效 |
srp-disable |
boolean | 禁用SRP(会话请求协议) | 存在即生效 |
hnp-disable |
boolean | 禁用HNP(主机协商协议) | 存在即生效 |
4.3.2 典型设备树节点示例(i.MX6Q)
usbotg: usb@02184000 {
compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
reg = <0x02184000 0x200>;
interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6Q_CLK_USBOH3>;
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
dr_mode = "peripheral";
phy_type = "utmi";
disable-over-current;
srp-disable;
hnp-disable;
status = "okay";
};
关键差异: Chipidea控制器使用
fsl,usbphy 而不是通用的 phys 属性。此外,fsl,usbmisc 是NXP特有的辅助控制器,用于处理ID引脚检测和VBUS电源控制,在Gadget模式下通常需要禁用HNP和SRP以避免意外切换角色。
4.3.3 Chipidea控制器模式切换逻辑
4.4 三种控制器设备树对比总结
| 对比维度 | DWC2 | DWC3 | Chipidea |
|---|---|---|---|
| compatible | snps,dwc2 |
snps,dwc3 |
fsl,imx6q-usb / chipidea,usb2 |
| PHY接口 | phys / phy-names |
phys (usb2-phy + usb3-phy) |
fsl,usbphy (专用属性) |
| FIFO配置 | g-rx-fifo-size 等 |
tx-fifo-resize (自动调整) |
通常不需要手动配置 |
| 模式控制 | dr_mode |
dr_mode |
dr_mode + hnp-disable / srp-disable |
| 速度限制 | 仅USB 2.0 | maximum-speed |
仅USB 2.0 |
| 特殊quirk | 较少 | snps,dis_u3_susphy_quirk 等 |
disable-over-current |
| 典型SoC | STM32MP1, Allwinner H3 | TI AM64x, Rockchip RK3588 | NXP i.MX6/7/8 |
移植建议: 在移植USB Gadget到新平台时,首先确认SoC参考手册中USB控制器的
compatible 字符串。对于DWC3,务必检查PHY的初始化顺序;对于Chipidea,注意 fsl,usbmisc 节点的存在性。建议在设备树中显式设置 dr_mode = "peripheral" 以避免内核在OTG模式下进行不必要的角色协商。
4.5 设备树节点调试与验证
在完成设备树配置后,可以通过以下方法验证节点是否正确加载:
- 检查设备树解析: 使用
ls /sys/firmware/devicetree/base/soc/查看节点是否存在。 - 查看驱动绑定:
cat /sys/bus/platform/drivers/dwc2/或cat /sys/bus/platform/drivers/ci_hdrc/确认驱动已绑定。 - 检查中断和寄存器:
cat /proc/interrupts | grep dwc查看中断是否触发。 - 验证Gadget功能:
ls /sys/kernel/config/usb_gadget/确认Gadget目录可访问。
# 检查DWC2设备树节点是否被内核识别
# 在目标板上执行:
ls /sys/firmware/devicetree/base/soc/usb@49000000/
cat /sys/firmware/devicetree/base/soc/usb@49000000/compatible
cat /sys/firmware/devicetree/base/soc/usb@49000000/dr_mode
# 预期输出:
# snps,dwc2
# peripheral
调试警告: 如果设备树节点存在但驱动未加载,检查
dmesg | grep dwc 或 dmesg | grep ci_hdrc。常见错误包括:EPROBE_DEFER(PHY或时钟未就绪)、ENOMEM(内存分配失败)、EINVAL