2024-02-07 10:13 AM
Hey there,
I am trying to troubleshoot the following issue for quite some time now. I am working on an stm32mp157f based board attempting to enable a combination of stusb16xx and USB OTG . The behavior I am expecting to see is that when a usb device is connected to usbphyc_port1 (usb-c) it will get recognized in the same way as if it was on ehci but when a host device is connected to the same port I can trigger a gadget script in udev.rules. My current configuration works as expected for all gadget modes:
typec: stusb1600@28 {
compatible = "st,stusb1600";
reg = <0x28>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
interrupt-parent = <&gpioi>;
vsys-supply = <&vdd_usb>;
pinctrl-names = "default";
pinctrl-0 = <&stusb1600_pins_a>;
status = "okay";
vdd-supply = <&vin>;
typec_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "dual";
data-role = "dual";
typec-power-opmode = "default";
port {
con_usbotg_hs_ep: endpoint {
remote-endpoint = <&usbotg_hs_ep>;
};
};
};
};
&usbotg_hs {
compatible = "st,stm32mp15-hsotg", "snps,dwc2";
phys = <&usbphyc_port1 0>; /* 0: UTMI switch selects the OTG controller */
phy-names = "usb2-phy";
dr_mode = "otg";
g-rx-fifo-size = <256>;
g-np-tx-fifo-size = <32>;
g-tx-fifo-size = <128 128 128 128 64 32 16 16>;
usb-role-switch;
role-switch-default-mode = "peripheral"; /* see USB generic bindings [4] */
status = "okay"; /* enable OTG */
port {
usbotg_hs_ep: endpoint {
remote-endpoint = <&con_usbotg_hs_ep>; /* point the Type-C controller endpoint node */
};
};
};
To my understanding phys = <&usbphyc_port1 0>; will set the UTMI to OTG and dr_mode="otg" will set the mode in the same way. In this configuration I can get the board recognized as a USB peripheral from other devices successfully. If I connect a peripheral device to the usb-c when the gadget is running the usb-c port will not provide any power as expected. If I stop the gadget and connect a peripheral the usb-c port will send the right power. Although this behavior looks correct according to the dts, no peripherals will get recognized in stlinux when the gadget is not running and a peripheral usb device is connected to the usb-c port.
If I use the same phys to ehci and ohci then I will get the usb running only on host mode and all peripherals will get successfully detected in lsusb.
&usbh_ehci {
phys = <&usbphyc_port0>, <&usbphyc_port1 1>;
phy-names = "usb", "usb2-phy";
status = "okay";
};
&usbh_ohci {
status = "okay";
phy-names = "usb", "usb2-phy";
phys = <&usbphyc_port0>, <&usbphyc_port1 1>;
};
If I understand this correctly for recognizing USB 1.1 I need the OHCI host controller and for USB2.0 I need the EHCI controller. If this is the case in order for the OTG to work as expected I need to share <&usbphyc_port1> between usbotg_hs, usbh_ehci and usbh_ohci so when OTG performs a role switch the host part is managed by the USBH controllers. When attempting to share the same usbphyc between otg_hs and USBH I do not get OTG mode since the phy is already occupied before otg gets intialized:
[ 4.069548] stusb160x 2-0028: Failed to get port caps: -6
[ 4.108387] stm32-usbphyc 5a006000.usbphyc: phy port1 already used
[ 4.113359] dwc2 49000000.usb-otg: error -EBUSY: error getting phy
If I share the node with 0 UTMI flag as below:
&usbotg_hs {
compatible = "st,stm32mp15-hsotg", "snps,dwc2";
phys = <&usbphyc_port1 0>; /* 0: UTMI switch selects the OTG controller */
phy-names = "usb2-phy";
dr_mode = "otg";
g-rx-fifo-size = <256>;
g-np-tx-fifo-size = <32>;
g-tx-fifo-size = <128 128 128 128 64 32 16 16>;
usb-role-switch;
role-switch-default-mode = "peripheral"; /* see USB generic bindings [4] */
status = "okay"; /* enable OTG */
port {
usbotg_hs_ep: endpoint {
remote-endpoint = <&con_usbotg_hs_ep>; /* point the Type-C controller endpoint node */
};
};
};
&usbh_ehci {
phys = <&usbphyc_port0>, <&usbphyc_port1 0>;
phy-names = "usb", "usb2-phy";
status = "okay";
};
&usbh_ohci {
status = "okay";
phy-names = "usb", "usb2-phy";
phys = <&usbphyc_port0>, <&usbphyc_port1 0>;
};
I get all 3 entries recongized in lsusb but no peripherals recongised when connected.
Any ideas or pointers on how to debug this further are really appreciated.
Solved! Go to Solution.
2024-02-23 07:44 AM
After some time I found out that the SDA and SCL I2C lines of the stusb1600x were inverted. By correcting this in HW I was able to change data roles from the stusb160x driver or from user space with
/sys/devices/platform/soc/49000000.usb-otg/usb_role/49000000.usb-otg-role-switch/role
This has been part of a more complex solution described in this post.
2024-02-23 07:44 AM
After some time I found out that the SDA and SCL I2C lines of the stusb1600x were inverted. By correcting this in HW I was able to change data roles from the stusb160x driver or from user space with
/sys/devices/platform/soc/49000000.usb-otg/usb_role/49000000.usb-otg-role-switch/role
This has been part of a more complex solution described in this post.