This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM57x USB3 SS device mode cable disconnect not detected

Champs,

Customer reported the following issue on custom AM571x based board: they use USB in SS mode as a device. Upon first connection to a PC the board connects and enumerates successfully and communicates with the host in SuperSpeed mode.

Upon cable disconnect the board does not detect the disconnect and no disconnect sound produced by the PC. When the cable is re-connected the board does not detect the connection and communication link isn't established. Upon second cable disconnect it is detected both on the board and the PC. Upon second connect the link is established and the board communicates successfully with the PC. the pattern repeats itself upon subsequent connects/disconnects.

The SuperSpeed link state of the Linux dwc3 USB driver during this sequence of cable disconnects/reconnects is as follows:

Cable status       SS Link State

Connected          U2

Disconnected    U2                          (no disconnect event is generated on our board)

Connected          SS.Inactive

Disconnected    U3                          (disconnect event is generated on our board)

Connected          U2                          (connect event is generated and communication is reestablished)

 

The issue seems to be that the first disconnect is not causing the link to go from SS U2 to SS.Inactive.

That transition occurs only when the cable is reconnected.

 

This only occurs when using USB3 cable and the link is SS. When using USB 2.0 cable there is no issue: all connects and disconnects are properly detected.

Is this a known issue? What could have caused this?

ANy insights will be greatly appreciated

thanks

Michael

  • Hi,

    This has been forwarded to the USB experts. They will respond here.
  • Michael,

    Has the customer tried with multiple USB host?

    Is this running Linux on AM57x? If so what is the kernel version?

  • Bin,

    Customer is testing using Win7 Pro host. They are currently using kernel version 4.7.2 (use Yocto to build own distro) and in the process of transitioning to 4.8.

    thanks

    Michael

  • Michael,

    Bin is asking if more than one Host was tested. I'm interested in the answer as well.

    Also,

    Was this schematic reviewed by TI?

  • -DK- said:

    Michael,

    Bin is asking if more than one Host was tested. I'm interested in the answer as well.

    -- No, only one Win7 host was tested

    Also,

    Was this schematic reviewed by TI?

    -- Yes, the schematic was reviewed by TI

    • Please verify that the issue exists on more than one Host.
    • Please use a different (known-good) USB3 cable and re-test.

  • More than one host also means not limited to Windows, please also test with Linux host.
  • Michael,


    Please ask the customer to apply the following patch. This should fix the issue.

    diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
    index 07cc892..cd509a8 100644
    --- a/drivers/usb/dwc3/gadget.c
    +++ b/drivers/usb/dwc3/gadget.c
    @@ -2584,7 +2584,7 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
             * STAR#9000446952: RTL: Device SS : if U1/U2 ->U0 takes >128us
             * core send LGO_Ux entering U0
             */
    -       if (dwc->revision < DWC3_REVISION_183A) {
    +       if (dwc->revision < DWC3_REVISION_240A) {
                    if (next == DWC3_LINK_STATE_U0) {
                            u32     u1u2;
                            u32     reg;
    
  • Bin,

    The customer tried the patch and while it resolves original issue it creates another.

    I tried the patch and the result is good news and bad news.

    The good news is that connecting and disconnecting a Superspeed cable is now working as expected every time.

    I noticed that whenever the cable is connected, the link state is U0.

    And when it’s disconnected, the link state is U3.

     

    The problem is that our device is now failing the USB30 Command Verifier test suite for USB and WHQL compliance, which our product is required to pass.

    Specifically, it fails test 9.24 U1U2 test, which attempts to put the link in U1 and U2 and verify the link state.

    With this patch, the link is never allowed to go into U1 or U2, so the test fails.

     

    Here’s the entire test sequence of the U1U2 test:

     

    TD.9.24 U1 and U2 Test

    This test verifies U1 and U2 behavior. Run at the root port and behind a SS hub.

    Assertions Used in Test

    9.4.9#6, 9.4.5#10, 9.1.1.6#1, 9.4.5#9, 9.4.5#8, 9.4.5#7,

    Device States for Test

    Configured state only

    Overview of Test Steps

    The test software performs the following steps:

    U2 with SetFeature() to device

    1. Send a SetFeature(U2_ENABLE) to the device.

    2. Send a GetStatus() to the device and verify that U2 is enabled.

    USB Command Verifier Compliance Test Specification for the USB 3.0 Architecture

    Page 45

    3, Set the U2 Timeout value to 1 for the parent port of the device

    4. Allow 520ms for port to go to U2.

    5. Bring link back to U0 by changing Link State of parent port to U0

    6. Send a ClearFeature(U2_ENABLE) to the device.

    7. Set U2 Timeout value to 0 for the parent port of the device.

    8. Send a GetStatus() to the device and verify that U2 is disabled.

    U1 with SetFeature() to device

    9. Send a SetFeature(U1_ENABLE) to the device.

    10. Send a GetStatus() to the device and verify that U1 is enabled.

    11. Set the U1 Timeout value to 1 for the parent port of the device.

    12. Allow 520ms for port to go to U2.

    13. Bring link back to U0 by chaning Link State of parent port to U0.

    14. Send a ClearFeature(U1_ENABLE) to the device.

    15. Set U1 Timeout value to 0 for the parent port of the device.

    16. Send a GetStatus() to the device and verify that U1 is disabled.

    U1 and U2 with SetFeature() to device

    17. Send a SetFeature(U1_ENABLE) to the device.

    18. Send a GetStatus() to the device and verify that U1 is enabled.

    19. Send a SetFeature(U2_ENABLE) to the device.

    20. Send a GetStatus() to the device and verify that U2 is enabled.

    21. Set U1 and U2 timeout values to 1 for the parent port.

    22. Wait 520ms for the port to go to a low power state.

    23. Device should go to U1 and then U2.

    24. Bring the link back to U0 by setting Port Link State of parent port to U0.

    25. Send a ClearFeature(U1_ ENABLE) to the device.

    26. Send a GetStatus() to the device and verify that U1 is disabled.

    27. Send a ClearFeature(U2_ ENABLE) to the device.

    28. Send a GetStatus() to the device and verify that U2 is disabled.

    U1 with Force PM Link Accept

    29. Enable Force PM Link Accept

    30. Set the U1 Timeout value to 1 for the parent port of the device

    31. Allow 520ms for the port to go to U2

    32. Bring link back to U0 by changing Link State of parent port to U0

    33. Set U1 Timeout value to 0 for the parent port of the device.

    34. Clear Force PM Link Accept

    U1 + U2 with Force PM Link Accept

    35. Enable force PM Link Accept

    36. Set U1 and U2 timeout values to 1 for the parent port.

    37. Wait 520ms for the port to go to a low power state.

    38. Device should go to U1 and then U2.

    39. Bring the link back to U0 by setting Port Link State of parent port to U0.

    40. Disable Force PM Link Accept

    44. Re-enumerate the device to make sure the Force PM Link Accept LPM is cleared.

  • Michael,

    Yes, the patch prevents dwc3 enters U1/U2.

    I will try to find an alternative solution for the original disconnect issue.
  • Michael,

    Can you please check if the customer's board design has VBUS detect for the supper-speed device port?

    AM57x GPEVM USB2 port can be used as a reference, which uses USB2 receptacle VBUS pin to control GPIO4_21 through PMIC as VBUS detect, then GPIO4_21 is claimed as extcon vbus-gpio in device tree. The Linux driver will handle it from there.

  • Please note that GPIO is not fail-safe, so please don't directly feed VBUS line to a GPIO, otherwise the device could be damaged.

  • Update:

    Upon close verification it turned out that the root cause for the issue was the fact that the GPIO that recieves VBUS_DET signal from PMIC (which in turn connects to VBUS pin in USB connector) was not correctly described in the ext_con entry in the device tree. As a result, the connect/disconnect event was not registered at the SoC and not communicated to the USB driver. Once the ext_con was fixed the eache plug/unplig event was correctly identified in Linux.