USB设备树片段
原始的USB接口定义在STM32MP251.dtsi中,包括:
/{
usb2_phy1: usb2-phy1 {
compatible = "st,stm32mp25-usb2phy";
#phy-cells = <0>;
#clock-cells = <0>;
st,syscfg = <&syscfg 0x2400>;
clocks = <&rcc CK_KER_USB2PHY1>;
resets = <&rcc USB2PHY1_R>;
status = "disabled";
};
usb2_phy2: usb2-phy2 {
compatible = "st,stm32mp25-usb2phy";
#phy-cells = <0>;
#clock-cells = <0>;
st,syscfg = <&syscfg 0x2800>;
clocks = <&rcc CK_KER_USB2PHY2EN>;
resets = <&rcc USB2PHY2_R>;
status = "disabled";
};
soc@0 {
combophy: phy@480c0000 {
compatible = "st,stm32mp25-combophy";
reg = <0x480c0000 0x1000>;
#phy-cells = <1>;
clocks = <&rcc CK_BUS_USB3PCIEPHY>, <&rcc CK_KER_USB3PCIEPHY>;
clock-names = "apb-clk", "ker-clk";
resets = <&rcc USB3PCIEPHY_R>;
reset-names = "phy-rst";
st,syscfg = <&syscfg>;
access-controllers = <&rifsc 67>;
power-domains = <&CLUSTER_PD>;
wakeup-source;
interrupts-extended = <&exti1 45 IRQ_TYPE_EDGE_FALLING>;
status = "disabled";
};
usbh: usb@482e0000 {
compatible = "st,stm32mp25-usbh";
st,syscfg = <&syscfg 0x2420>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x482e0000 0x482e0000 0x20000>;
access-controllers = <&rifsc 63>;
power-domains = <&CLUSTER_PD>;
wakeup-source;
interrupts-extended = <&exti1 43 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
usbh_ohci: usb@482e0000 {
compatible = "generic-ohci";
reg = <0x482e0000 0x1000>;
clocks = <&usb2_phy1>, <&rcc CK_BUS_USB2OHCI>;
resets = <&rcc USB2_R>;
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usb2_phy1>;
phy-names = "usb";
wakeup-source;
status = "disabled";
};
usbh_ehci: usb@482f0000 {
compatible = "generic-ehci";
reg = <0x482f0000 0x1000>;
clocks = <&rcc CK_BUS_USB2EHCI>;
resets = <&rcc USB2_R>;
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
companion = <&usbh_ohci>;
phys = <&usb2_phy1>;
phy-names = "usb";
wakeup-source;
status = "disabled";
};
};
usb3dr: usb@48300000 {
compatible = "st,stm32mp25-dwc3";
st,syscfg = <&syscfg 0x4800>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x48300000 0x48300000 0x100000>;
access-controllers = <&rifsc 66>;
power-domains = <&CLUSTER_PD>;
wakeup-source;
interrupts-extended = <&exti1 44 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
dwc3: usb@48300000 {
compatible = "snps,dwc3";
reg = <0x48300000 0x100000>;
interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "ref", "bus_early", "suspend";
clocks = <&rcc CK_KER_USB2PHY2>, <&rcc CK_BUS_USB3DR>,
<&rcc CK_KER_USB2PHY2>;
resets = <&rcc USB3DR_R>;
phys = <&usb2_phy2>;
phy-names = "usb2-phy";
wakeup-source;
};
};
}
}
在板级设备树中关键启用是:
&usbh {
status = "okay";
};
&usbh_ehci {
status = "okay";
};
&usb3dr {
status = "okay";
dwc3: usb@48300000 {
maximum-speed = "high-speed";
usb-role-switch;
role-switch-default-mode = "peripheral";
};
};
在PLC的板子上,usbh_ehci: usb@482f0000 这个用的是usb2_phy1,对应板子上的USB HOST接口,而usb3dr是用usb2_phy2,对应板子上的U21 type C接口。
ST开发板,默认的DTS中明确禁用了OHCI (usbh_ohci: usb@482e0000 { status = "disabled"; }😉,但板载了一个USB Hub芯片(compatible="usb424,2514",如USB2514系列)。这个Hub是高速度Hub,它可以作为中介处理FS/LS设备:即使OHCI禁用,Hub会将FS/LS信号转换为HS信号,再由EHCI处理。 因此,一些像伪ch343的USB转serial低速设备在能被识别(尽管DTS只启用了EHCI)——这是Hub的功劳,而不是直接依赖OHCI。
但单端USB的PLC板卡,对于FS设备如USB转serial,缺少OHCI会导致内核无法正确切换和处理低速信号。因此我们需要启用OHCI。
&usbh_ohci {
status = "okay";
};
USB硬件电路
ST的PLC参考设计板提供了最简的USB电路,但这个电路中的type C只是下载接口,而ST官方用STUSB1600来实现OTG功能,可能是一个正常的设计。