1. Article purpose[edit source]
The purpose of this article is to explain how to configure the USB3DR internal peripheral using the device tree mechanism, relying on the bindings documentation, that is the description of the required and optional device-tree properties.
It is used by:
- DWC3 USB DRD Linux driver[1] which registers the relevant information in the USB framework.
- DWC3 USB DRD U-Boot driver[2].
The peripheral can be assigned to different contexts/software components, depending on the final product needs. Refer to How to assign an internal peripheral to an execution context for guidelines on this configuration.
2. DT bindings documentation[edit source]
The device tree binding documents are stored in the Linux kernel repository:
- Linux® OS:
- STM32 DWC3 USB DRD Controller Glue: Documentation/devicetree/bindings/usb/stm32,dwc3.yaml
- Synopsys DesignWare USB3 Controller: Documentation/devicetree/bindings/usb/snps,dwc3.yaml
The generic USB device tree bindings represent generic USB properties used by the USB framework:
- usb.yaml[3] is the base DT schema for all USB controllers. It describes properties such as maximum-speed.
- usb-drd.yaml[4] is specific to dual-role USB controllers. It describes properties such as dr_mode, usb-role-switch...
- usb-hcd.yaml[5] is specific to USB Host controllers.
- usb-connector.yaml[6] is specific to USB connectors.
3. DT configuration[edit source]
This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device tree file split.
STM32CubeMX can be used to generate the board device tree. Refer to How to configure the DT using STM32CubeMX for more details.
3.1. DT configuration (STM32 level)[edit source]
The usb3dr DT node is declared in:
- stm32mp251.dtsi[7] on STM32MP25x lines
It is composed of a set of properties, used to describe the USB3DR controller: registers address, clocks, resets, interrupts, dwc3-core node, phys...
usb3dr: usb@48300000 { compatible = "st,stm32mp25-dwc3"; st,syscfg = <&syscfg 0x4800>; #address-cells = <1>; #size-cells = <1>; ranges = <0x48300000 0x48300000 0x100000>; feature-domains = <&rifsc STM32MP25_RIFSC_USB3DR_ID>; 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; }; };
3.2. DT configuration (board level)[edit source]
Follow the sequences described in the below chapters to configure and enable the USB3DR on your board.
USB3DR uses two PHY interfaces for supporting USB2.0 and USB3.0 speeds that can be specified via DT:
- USB2-speed PHY, also called USB2PHY[8]. It supports HS/FS/LS.
- USB3-speed PHY, also called COMBOPHY[9]. It supports SS. It can be assigned to either the USB3DR or the PCIe controller.
Information |
USB3DR needs both PHYs to operate in SuperSpeed (SS), here reference handles of both phys is specified in the phys DT property. In such a case only the USB2-speed PHY must be specified in the DT (as in the example below) |
3.2.1. DT configuration using only USB2.0 speeds[edit source]
- Enable the USB3DR by setting status = "okay".
- Use embedded USB2-speed PHY (already set by default inside stm32mp251.dtsi[7])
3.2.2. DT configuration using USB3.0 speeds[edit source]
- Enable the USB3DR by setting status = "okay";
- Set phys = <&usb2_phy2>, <&combophy PHY_TYPE_USB3>;
- Set phy-names = "usb2-phy", "usb3-phy";
3.3. DT configuration examples[edit source]
3.3.1. DT configuration example as USB3-speed USB3DR, with Type-C connector[edit source]
The example below shows how to configure the USB3DR internal peripheral running at USB3-speed with a Type-C connector. Type-C connector is managed by the UCPD internal peripheral controller, which is represented as a separate DT node. The Type-C controller implements a "USB role switch" class to detect connection and data role (peripheral, host). Steps to configure are:
- Enable SuperSpeed by setting:
- phys = <&usb2_phy2>, <&combophy PHY_TYPE_USB3>;
- phy-names = "usb2-phy", "usb3-phy";
- Add usb-role-switch property to USB3DR controller node: it indicates that the device can assign the USB data role (USB host or USB device) for a given USB connector.
- Add a connector subnode to the Type-C controller node[6], with a port child node pointing to the USB3DR controller endpoint and add a port child node to the USB3DR controller node pointing to the Type-C controller endpoint: Type-C controller driver will be able to get the USB role switch to inform it of a role change.
#example of Type-C controller node &mlahb { ......... i2c_rpmsg: i2c@1 { ......... typec@35 { ......... connector { compatible = "usb-c-connector"; label = "USB-C"; port { typec_ep: endpoint { remote-endpoint = <&dwc3_ep>; /* point the USB3DR controller endpoint node */ }; }; }; }; }; };
&usb3dr { status = "okay"; /* enable USB3DR */ dwc3: usb@48300000 { ......... phys = <&usb2_phy2>, <&combophy PHY_TYPE_USB3>; phy-names = "usb2-phy", "usb3-phy"; usb-role-switch; port { dwc3_ep: endpoint { remote-endpoint = <&typec_ep>; /* point the Type-C controller endpoint node */ }; }; }; };
Information |
dwc3 node : Dual-role mode (dr_mode) = "otg" (is the default value hence unspecified) |
3.3.2. DT configuration example as USB2-speed only USB3DR, with Type-C connector[edit source]
The example below shows how to configure the USB3DR internal peripheral running at USB2-speed only, with a Type-C connector. Type-C connector is managed by the UCPD internal peripheral controller, which is represented as a separate DT node. The Type-C controller implements a "USB role switch" class to detect connection and data role (peripheral, host). Steps to configure are:
- Add maximum-speed = "high-speed"; property to USB3DR controller node: it indicates that usb-device-mode max operating speed of USB3DR ctrl is USB2.0 high-speed.
- Add usb-role-switch property to USB3DR controller node: it indicates that the device can assign the USB data role (USB host or USB device) for a given USB connector.
- Add a connector subnode to the Type-C controller node[6], with a port child node pointing to the USB3DR controller endpoint and add a port child node to the USB3DR controller node pointing to the Type-C controller endpoint: Type-C controller driver will be able to get the USB role switch to inform it of a role change.
#example of Type-C controller node &mlahb { ......... i2c_rpmsg: i2c@1 { ......... typec@35 { ......... connector { compatible = "usb-c-connector"; label = "USB-C"; port { typec_ep: endpoint { remote-endpoint = <&dwc3_ep>; /* point the USB3DR controller endpoint node */ }; }; }; }; }; };
&usb3dr { status = "okay"; /* enable USB3DR */ dwc3: usb@48300000 { ......... maximum-speed = "high-speed"; usb-role-switch; port { dwc3_ep: endpoint { remote-endpoint = <&typec_ep>; /* point the Type-C controller endpoint node */ }; }; }; };
Information |
dwc3 node : phys = <&usb2_phy2>; and phy-names = "usb2-phy"; (is the value present already in stm32mp251.dtsi[7] hence unspecified) |
3.3.3. DT configuration example as USB2-speed only USB3DR in Peripheral mode, with micro-B(ID left unconnected) or Type-C connector[edit source]
The example below shows how to configure USB2-speed only USB3DR with a Type-C connector, and forces the mode to peripheral mode.
- Add maximum-speed = "high-speed"; property to USB3DR controller node: it indicates that usb-device-mode max operating speed of USB3DR ctrl is USB2.0 high-speed.
- Add usb-role-switch;
- Add role-switch-default-mode and set it to "peripheral";
&usb3dr { status = "okay"; /* enable USB3DR */ dwc3: usb@48300000 { maximum-speed = "high-speed"; role-switch-default-mode = "peripheral"; usb-role-switch; }; };
Information |
dwc3 node : phys = <&usb2_phy2>; and phy-names = "usb2-phy"; (is the value present already in stm32mp251.dtsi[7] hence unspecified) |
4. How to configure the DT using STM32CubeMX[edit source]
The STM32CubeMX tool can be used to configure the STM32MPU device and get the corresponding platform configuration device tree files.
STM32CubeMX may not support all the properties described in DT binding files listed in the above DT bindings documentation paragraph. If so, the tool inserts user sections in the generated device tree. These sections can then be edited to add some properties, and they are preserved from one generation to another. Refer to STM32CubeMX user manual for further information.
5. References[edit source]
Please refer to the following links for additional information:
- ↑ drivers/usb/dwc3/ , DesignWare DWC3 USB DRD Controller Linux driver
- ↑ drivers/usb/dwc3/gadget.c , DesignWare DWC3 USB DRD Controller U-Boot driver
- ↑ Documentation/devicetree/bindings/usb/usb.yaml , Generic USB Controller Device Tree Bindings
- ↑ Documentation/devicetree/bindings/usb/usb-drd.yaml , Generic DWC3 USB DRD Controller Device Tree Bindings
- ↑ Documentation/devicetree/bindings/usb/usb-hcd.yaml , Generic USB Host Controller Device Tree Bindings
- ↑ 6.0 6.1 6.2 Documentation/devicetree/bindings/connector/usb-connector.yaml , Generic USB Connector Device Tree Bindings
- ↑ 7.0 7.1 7.2 7.3 arch/arm64/boot/dts/st/stm32mp251.dtsi , STM32MP251 device tree file
- ↑ USB2PHY internal peripheral
- ↑ COMBOPHY internal peripheral