USB3DR device tree configuration

Applicable for STM32MP25x lines

1. Article purpose[edit source]

This article explains how to configure the USB3DR internal peripheral when it is assigned to the Linux® OS. In that case, it is controlled by the USB framework.

The configuration is performed using the device tree mechanism.

It is used by DWC3 USB DRD Linux driver[1] which registers the relevant information in the USB framework.

2. DT bindings documentation[edit source]

The Platform DesignWare DWC3 USB DRD controller device tree bindings[2] document represents the USB3DR (DRD) controller.

The generic USB device tree bindings represents 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 usb3drd DT node is declared in:

  • stm32mp251.dtsi[7] on STM32MP25x lines More info.png

It is composed of a set of properties, used to describe the USB3DR controller: registers address, clocks, resets, interrupts, dwc3-core node, phys...

usb3drd: 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>;
 	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_USB3DRD>,
 			<&rcc CK_KER_USB2PHY2>;
 		resets = <&rcc USB3DRD_R>;
 		phys = <&usb2_phy2>;
 		phy-names = "usb2-phy";
 	};
};
Warning white.png Warning
This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.

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.
Info white.png Information

USB3DR needs both PHYs to operate in SuperSpeed (SS), here reference handles of both phys is specified in the phys DT property.
USB3DR can operate in USB2-speed only, typically when the PCIe controller is used along with the COMBOPHY.

In such a case only the USB2-speed PHY must be specified in the DT (as in below example)

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 USB3-speed USB3DR with a Type-C connector. Type-C is managed by an external controller which detects connection and data role (peripheral, host) and implements Linux USB role switch class:

  • Enable SuperSpeed by setting: phys = <&usb2_phy2>, <&combophy PHY_TYPE_USB3>;
  • Enable SuperSpeed by setting: phy-names = "usb2-phy", "usb3-phy";
  • Dual-role mode (dr_mode) is "otg" (e.g. the default as unspecified)
  • Add usb-role-switch property to USB3DR controller node: it indicates that the device is capable of assigning 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 */
					};
				};
			};
		};
	};
};
&usb3drd {
	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 */
			};
		};
	};
};

3.3.2. DT configuration example as USB2-speed only USB3DR, with Type-C connector[edit source]

The example below shows how to configure USB2-speed only USB3DR with a Type-C connector. Type-C is managed by an external controller which detects connection and data role (peripheral, host) and implements Linux USB role switch class:

  • Use phys = <&usb2_phy2>; and phy-names = "usb2-phy"; (specified already in stm32mp251.dtsi[7])
  • Dual-role mode (dr_mode) is "otg" (e.g. the default as unspecified)
  • 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 is capable of assigning 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 */
					};
				};
			};
		};
	};
};
&usb3drd {
	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 */
			};
		};
	};
};

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. Type-C is managed by an external controller which detects connection and data role (peripheral, host) and implements Linux USB role switch class:

  • Use phys = <&usb2_phy2>; and phy-names = "usb2-phy"; (specified already in stm32mp251.dtsi[7])
  • Dual-role mode (dr_mode) is "peripheral"
  • 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 st,internal-vbus-comp; property to usb2_phy2 phy node, this indicates that VBUS ball (pin) is used to detect the VBUS availability. Here the internal VBUS (or session valid) comparator of USB2PHY2 is used by USB3DR ctrl to check if VBUS is present or not.
&usb2_phy2 {
	.........
	st,internal-vbus-comp;
};
&usb3drd {
	status = "okay";	/* enable USB3DR */

	dwc3: usb@48300000 {
		.........
		maximum-speed = "high-speed";
		dr_mode = "peripheral";
	};
};

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.
The STM32CubeMX may not support all the properties described 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:

  1. drivers/usb/dwc3/ , DesignWare DWC3 USB DRD Controller driver
  2. Documentation/devicetree/bindings/usb/snps,dwc3.yaml , Platform DesignWare DWC3 USB DRD controller device tree bindings
  3. Documentation/devicetree/bindings/usb/usb.yaml , Generic USB Controller Device Tree Bindings
  4. Documentation/devicetree/bindings/usb/usb-drd.yaml , Generic DWC3 USB DRD Controller Device Tree Bindings
  5. Documentation/devicetree/bindings/usb/usb-hcd.yaml , Generic USB Host Controller Device Tree Bindings
  6. 6.0 6.1 6.2 Documentation/devicetree/bindings/connector/usb-connector.yaml , Generic USB Connector Device Tree Bindings
  7. 7.0 7.1 7.2 7.3 arch/arm64/boot/dts/st/stm32mp251.dtsi , STM32MP251 device tree file
  8. USB2PHY internal peripheral
  9. COMBOPHY internal peripheral