Last edited 4 months ago

USBH device tree configuration

Applicable for STM32MP13x lines, STM32MP15x lines, Unknown MPU

1. Article purpose[edit | edit source]

This article explains how to configure the USBH 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 USBH Linux drivers (EHCI[1], OHCI[2]) which register the relevant information in the USB framework.

2. DT bindings documentation[edit | edit source]

STM32 USBH internal peripheral is a USB Host device, composed of an EHCI controller and an OHCI controller.

Each controller is represented as a separate binding document:

  • The generic USB EHCI controller device tree bindings[3] document deals with standard EHCI controller core resources (e.g. registers, clock, reset, interrupt, ...).
  • The generic USB OHCI controller device tree bindings[4] document deals with standard OHCI controller core resources (e.g. registers, clock, reset, interrupt, ...).

Each controller uses the generic USB Host Controller Device (HCD) properties and generic USB properties, proposed by USB framework:

  • The generic USB HCD device tree bindings[5] document deals with USB Host Controller resources such as companion controller.
  • The generic USB device tree bindings[6] document deals with USB optional properties such as PHY or maximum speed.

On STM32MP25x lines More info.png, some additional configuration logic is handled via STM32 USB2 controller glue driver which encapsulates EHCI and OHCI controller nodes:

  • STM32 USB2 glue controller device tree bindings[7] document deals with common glue logic encapsulating both EHCI and OHCI controller.


3. DT configuration[edit | 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 | edit source]

3.1.1. On STM32MP1 series[edit | edit source]

The usbh_ehci and usbh_ohci DT nodes are declared in stm32mp151.dtsi[8].

They are composed of a set of properties, used to describe the USBH_EHCI and USBH_OHCI controllers: registers address, clocks, resets, interrupts...

usbh_ohci: usbh-ohci@5800c000 { 			/* USBH OHCI controller */
	compatible = "generic-ohci";
	reg = <0x5800c000 0x1000>;
	clocks = <&rcc USBH>;
	resets = <&rcc USBH_R>;
	interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
	status = "disabled";
};

usbh_ehci: usbh-ehci@5800d000 { 			/* USBH EHCI controller */
	compatible = "generic-ehci";
	reg = <0x5800d000 0x1000>;
	clocks = <&rcc USBH>;
	resets = <&rcc USBH_R>;
	interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
	companion = <&usbh_ohci>;  			/* When USBH EHCI controller detects a full or low speed device on a port,
	status = "disabled";  				 * that port is switched over to the USBH OHCI companion[5] controller */
};

3.1.2. On STM32MP2 series[edit | edit source]

The usb2h DT node containing usb2h_ehci and usb2h_ohci DT nodes are declared in stm32mp251.dtsi[9].

usb2h_ehci and usb2h_ohci are composed of a set of properties, used to describe the USBH EHCI and OHCI controllers: registers address, clocks, resets, interrupts...

usb2h: usb@482e0000 {
	compatible = "st,stm32mp25-usb2h";
	st,syscfg = <&syscfg 0x2420>;
	#address-cells = <1>;
	#size-cells = <1>;
	ranges = <0x482e0000 0x482e0000 0x20000>;
	feature-domains = <&rifsc STM32MP25_RIFSC_USBH_ID>;
	power-domains = <&CLUSTER_PD>;
	status = "disabled";

	usb2h_ohci: usb@482e0000 {	/* USB2H OHCI controller */
		compatible = "generic-ohci";
		reg = <0x482e0000 0x1000>;
		clocks = <&rcc CK_BUS_USB2OHCI>;
		resets = <&rcc USB2_R>;
		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
		phys = <&usb2_phy1>;
		phy-names = "usb";
	};

	usb2h_ehci: usb@482f0000 {	/* USB2H EHCI controller */
		compatible = "generic-ehci";
		reg = <0x482f0000 0x1000>;
		clocks = <&rcc CK_BUS_USB2EHCI>;
		resets = <&rcc USB2_R>;
		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
		companion = <&usb2h_ohci>;	/* When USBH EHCI controller detects a full or low speed device on a port,
		phys = <&usb2_phy1>;		 * that port is switched over to the USBH OHCI companion[5] controller */
		phy-names = "usb";
	};
};
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 | edit source]

USBH is composed of EHCI and OHCI controllers:

  • high-speed operation is achieved through the EHCI controller
  • full-speed and low-speed operation can be achieved by either:
    • a high-speed HUB IC wired to the downstream port
    • the OHCI controller

3.2.1. On STM32MP1 series[edit | edit source]

Follow the sequences described in the below chapters to configure and enable the USBH on your board.

USBH supports up to two physical ports, using on-chip USBPHYC:

  • USBPHYC port#1 is assigned to the USBH
  • USBPHYC port#2 can be statically assigned to the USBH or to the OTG
Info white.png Information
Please refer to USBPHYC device tree configuration for additional information on the USBPHYC configuration
3.2.1.1. DT configuration with external high speed-HUB[edit | edit source]
  • Enable the usbh_ehci by setting status = "okay"
  • Configure the PHY(s) through phys and phy-names
Info white.png Information
There's no need to enable usbh_ohci, when all the low-speed and full-speed traffic is managed by the high-speed hub directly connected to the downstream port.
3.2.1.2. DT configuration with OHCI to achieve full-speed and low-speed[edit | edit source]
  • Enable the usbh_ehci by setting status = "okay"
  • Enable the usbh_ohci by setting status = "okay"

For both controllers:

  • Configure the PHY(s) through phys and phy-names

3.2.2. On STM32MP2 series[edit | edit source]

Follow the sequences described in the below chapters to configure and enable the USBH on your board.

USBH is connected to an internal USB2PHY supporting high, full and low speeds

Info white.png Information
Please refer to USB2PHY device tree configuration for additional information on the internal USB2PHY configuration
3.2.2.1. DT configuration with external high speed-HUB[edit | edit source]
  • Enable the usb2h by setting status = "okay"
  • Disable the usb2h_ohci by setting status = "disabled" (default enabled in stm32mp251.dtsi[9])
  • Configure the PHY(s) through phys and phy-names (specified already in stm32mp251.dtsi[9])
Info white.png Information
There's no need to enable usb2h_ehci, as enabled by default in stm32mp251.dtsi[9].
3.2.2.2. DT configuration with OHCI to achieve full-speed and low-speed[edit | edit source]
  • Enable the usb2h by setting status = "okay"
  • Configure VBUS and OVRCUR pins using pinctrl, use pinctrl-names = "default"; and pinctrl-0 = <&usb2h_test_pins_a>;
  • Optionally set active-low polarity for VBUS and OVRCUR pins using st,vbusen-active-low; and st,ovrcur-active-low;

For both controllers:

  • Configure the PHY(s) through phys and phy-names (specified already in stm32mp251.dtsi[9])
Info white.png Information
There's no need to enable usb2h_ehci and usb2h_ohci, as enabled by default in stm32mp251.dtsi[9].

3.3. DT configuration examples[edit | edit source]

3.3.1. On STM32MP1 series[edit | edit source]

3.3.1.1. DT configuration when using port0 with a high-speed hub[edit | edit source]

Below example shows how to configure the USBH when using the physical port 0 (the second physical port is unused).

A high-speed hub controller IC is used on the board: no need to enable usbh_ohci, all low-speed and full-speed traffic is managed by the hub.

&usbh_ehci {
	phys = <&usbphyc_port0>;           /* Use USBPHYC HS PHY port #1, mapped on USBH controller */
	phy-names = "usb";
	status = "okay";
};

/* No need to configure and enable usbh_ohci */
3.3.1.2. DT configuration when using port0[edit | edit source]

Below example shows how to configure the USBH when using the physical port 0 (the second physical port is unused, or in use by the OTG and no high-speed hub is used).

&usbh_ehci {
	phys = <&usbphyc_port0>;           /* Use USBPHYC HS PHY port #1, mapped on USBH controller */
	phy-names = "usb";
	status = "okay";
};

&usbh_ohci {
	phys = <&usbphyc_port0>;           /* Use USBPHYC HS PHY port #1, mapped on USBH controller */
	phy-names = "usb";
	status = "okay";
};
3.3.1.3. DT configuration when using the two physical ports[edit | edit source]

Below example shows how to configure the USBH when using the two physical ports.

&usbh_ehci {
	phys = <&usbphyc_port0>, <&usbphyc_port1 1>;     /* Use USBPHYC HS PHY port #1, mapped on USBH controller */
                                                         /* Use USBPHYC HS PHY port #2, configure UTMI switch to select USBH controller */
	phy-names = "usb", "usb";
	status = "okay";
};

&usbh_ohci {
	phys = <&usbphyc_port0>, <&usbphyc_port1 1>;     /* Use USBPHYC HS PHY port #1, mapped on USBH controller */
                                                         /* Use USBPHYC HS PHY port #2, configure UTMI switch to select USBH controller */
	phy-names = "usb", "usb";
	status = "okay";
};

3.3.2. On STM32MP2 series[edit | edit source]

3.3.2.1. DT configuration when using with a high-speed hub[edit | edit source]

Below example shows how to configure the USBH connected to internal USB2PHY.

  • Use phys = <&usb2_phy1>; and phy-names = "usb"; (specified already in stm32mp251.dtsi[9])
  • A high-speed hub controller IC is used on the board: disable usb2h_ohci, all low-speed and full-speed traffic is managed by the hub.
&usb2h {
	status = "okay";	/* enable USBH */

	usb2h_ohci: usb@482e0000 {
		status = "disabled";
	};
};
/* No need to enable usb2h_ehci as enabled by default */
3.3.2.2. DT configuration when using directly with Type-A connector[edit | edit source]

Below example shows how to configure the USBH when using with Type-A connector (no high-speed hub is used).

  • Use phys = <&usb2_phy1>; and phy-names = "usb"; (specified already in stm32mp251.dtsi[9])
  • Use pinctrl-names = "default"; and pinctrl-0 = <&usb2h_test_pins_a>; to configure gpio alternate mode for VBUS and OVRCUR pins
  • Use active-low polarity for OVRCUR pins using st,ovrcur-active-low;
&usb2h {
	pinctrl-names = "default";
	pinctrl-0 = <&usb2h_test_pins_a>;
	st,ovrcur-active-low;
	status = "okay";	/* enable USBH */
};
/* No need to enable usb2h_ehci and usb2h_ohci as enabled by default */

4. How to configure the DT using STM32CubeMX[edit | 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 | edit source]

Please refer to the following links for full description:

  1. drivers/usb/host/ehci-platform.c , Generic platform ehci driver
  2. drivers/usb/host/ohci-platform.c , Generic platform ohci driver
  3. Documentation/devicetree/bindings/usb/generic-ehci.yaml Generic USB EHCI controller device tree bindings
  4. Documentation/devicetree/bindings/usb/generic-ohci.yaml Generic USB OHCI controller device tree bindings
  5. 5.0 5.1 5.2 Documentation/devicetree/bindings/usb/usb-hcd.yaml Generic USB HCD (Host Controller Device) device tree bindings
  6. Documentation/devicetree/bindings/usb/usb.yaml Generic USB device tree bindings
  7. Documentation/devicetree/bindings/usb/stm32,usb2h.yaml STM32 USB2 glue controller device tree bindings
  8. arch/arm/boot/dts/stm32mp151.dtsi , STM32MP151 device tree file
  9. 9.0 9.1 9.2 9.3 9.4 9.5 9.6 9.7 arch/arm64/boot/dts/st/stm32mp251.dtsi , STM32MP251 device tree file