AM625: Failing to enter deep sleep due to USB LPSC timeout

Part Number: AM625
Other Parts Discussed in Thread: SK-AM62B-P1,

Tool/software:

Hi,

We're trying to get deep sleep working on a custom hardware design using SDK 10 and have found that the board fails to sleep unless we disable the usbss1 node in our Linux device tree. We do not have to disable usbss0 for deep sleep to work. We've observed this on multiple boards.

With SYSFW tracing enabled, we see that when usbss1 is enabled, the DM LPM sequence fails at enabling USB reset isolation:

Fullscreen
1
2
3
4
5
6
Configuring trace data version to: 0x03007
0x6C000100: Power Management: PM_LPM_SEQ(Low power mode sequence): DM stub started Value: 0
0x6C000200: Power Management: PM_LPM_SEQ(Low power mode sequence): Unlocked MMRs Value: 0
0x6C000400: Power Management: PM_LPM_SEQ(Low power mode sequence): DDR in reset isolation Value: 0
0x6C007700: Power Management: PM_LPM_SEQ(Low power mode sequence): Unknown Sub Message: 0x77 Value: 0
0x7C000500: Power Management/FAIL(Action failed): PM_LPM_SEQ(Low power mode sequence): Enabled USB reset isolation Value: 0
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The DM source code included in MCU+ SDK 10 appears slightly newer than the version we're running, but it looks like this step starts by disabling the USB and USB ISO modules via their LPSCs. Attached is a dump of the PSC registers collected via JTAG; USB0_ISO, USB0, and USB1_ISO appear disabled in their MDSTAT registers, but USB1 has state 10 (which I don't see in the documentation) and PTSTAT indicates the transition is in progress. Even after several seconds refreshing the memory contents in CCS, these register values don't change. The JTAG connection was made a second or two after the SYSFW trace on the DM core's UART stopped, presumably after the LPM sequence had already failed.

PSC registers:

psc-regs.txt
Fullscreen
1
2
3
4
5
6
7
8
9
10
0x00400000 44828200 ???????? ???????? ???????? 00000000 00000000 00000000 00000000
0x00400020 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
0x00400040 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x00400060 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x00400080 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
0x004000A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
0x004000C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
0x004000E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
0x00400100 00000000 00000000 00000000 00000000 ???????? ???????? ???????? ????????
0x00400120 00000000 00000000 00000001 00000000 ???????? ???????? ???????? ????????
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

DM firmware version:

Fullscreen
1
2
3
Sciserver Testapp Built On: Jul 25 2024 06:35:21
Sciserver Version: v2024.07.0.0-REL.MCUSDK.K3.10.00.00.08+
RM_PM_HAL Version: v10.00.08
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Here are links to our custom device trees at the revision we're testing; the USB1 nodes are nearly identical to those in k3-am62x-sk-common.dtsi, minus a connector subnode and the fact that we accidentally have DRVVBUS pinmuxed as an input. Fixing the DRVVBUS pinmux and removing the connector subnode don't affect the sleep behavior. Both USB interfaces do work outside of this sleep issue.

What might cause this state change to apparently hang? Is there other debug info we can collect to help pinpoint the problem?

Thanks,
Zach

  • Hi Zach,

    I'm looking into any additional debugging steps to try. Please expect an update by Monday.

    Have you tried to replicate this on a TI EVM?

    Thanks,

    Anshu

  • Hi Anshu,

    Thanks for looking into this. We've perhaps narrowed things down a bit more; full details are below, but the summary is that sleep failure on our hardware seems to correlate with having a downstream device attached (on either USB interface), and we can't get sleep to fail on an EVM.


    We have confirmed that the SK-AM62B-P1 EVM with SDK 10.00.07.04 doesn't exhibit this issue out of the box. Both USB subsystems are enabled in the device tree and the board appears to sleep and wake as expected. (One of the symptoms we see on our own design is that since the DM firmware aborts at the error, the board never wakes.)

    We also updated the board-cfg.bin on the EVM SDK 10 setup to confirm via JTAG that the LPM sequence ran to completion without error.

    The DM in the EVM SDK 10 setup also prints the exact same version info as on our custom hardware above. (We do rebuild the SDK ourselves, but my understanding is that our SDK 10 is based on TI's with minimal changes, and I do know that we pull prebuilt firmware from ti-linux-firmware; we're not running anything custom on the R5.)

    Since I forgot to mention it above, we're testing sleep using rtcwake (with various time durations depending on the scenario):

    Fullscreen
    1
    rtcwake -s 10 -m mem
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    After some more discussion and debug internally, we've actually found that the sleep failure on our hardware appears to be caused by having a device connected; we have a hub chip on USB1, which is why that appeared to be the problematic interface.

    Our USB topology is:

    • USB0: OTG (like EVM), AM62 -> Type-B port
    • USB1: Host (like EVM), AM62 -> two-port hub -> dual Type-A ports

    We've now tried a few setups with external devices, on both our hardware and the EVM:

    • Our hardware:
      • Both USBs enabled, nothing plugged into either, hub active: sleep fails
      • Both USBs enabled, nothing plugged into either, hub in reset: sleep succeeds
      • Only USB0 enabled, nothing plugged in or only OTG adapter plugged in (to force host mode): sleep succeeds
      • Only USB0 enabled, flash drive or external hub plugged in via OTG adapter: sleep fails
    • EVM (both USBs enabled for all tests):
      • Nothing plugged into either interface or only Type-C adapter plugged into USB0 (to force host mode): sleep succeeds
      • Flash drive or external hub plugged into USB1 or the same plugged into USB0 via Type-C adapter: sleep succeeds

    We did verify that all the failures here occur at the same USB reset isolation step of the LPM sequence as before, although we didn't examine the PSC registers again (under the assumption that we'd just see either the USB0 or USB1 state transitions stuck as before, depending on which interface we had a device plugged into); if register dumps would be helpful though, we can collect them.

    These tests were done with our DRVVBUS pinmuxes fixed and the USB1 connector subnode removed from our device tree as described in my first post, such that the usbss1 node should be functionally identical to the EVM's. There are some differences in the usbss0 node, but since both interfaces seem to act the same regarding the presence of downstream devices, we haven't bothered changing anything in usbss0 aside from the DRVVBUS pinmux.

    I've also verified that the entire drivers/usb/ tree is identical between our Linux kernel and the commit the EVM was built against. We do have a custom defconfig, but I've compared the generated configs and nothing jumped out as relevant to this issue.

  • Thanks for the update Zach. I'll be sharing this with our software development team. Feel free to ping this thread by Wednesday if you haven't heard back since I'll be out of office Monday + Tuesday.


    Thanks,

    Anshu

  • Hi Zach,

    Here is some feedback from the software development team:

    When the USB LPSC is attempting to be turned off, there are a few status checks on the USB IP (like USB1). If any of these checks fail, then it would return a fail on turning off the USB LPSC. We'll try to talk to the USB team at TI to see any of their thoughts.

    The LPSC status registers would provide any information about why it failed.

    So there are few things that can be tried:

    • We can try unloading the USB driver prior to entering a suspend state.
    • Run 'echo N > /sys/module/printk/parameters/console_suspend' to see if there are any errors suspending the USB

    Best Regards,

    Anshu

  • Hi Anshu,

    Thanks for passing that along.

    The LPSC status registers would provide any information about why it failed.

    Is there a separate set of LPSC registers from what I attached in my original post? I didn't notice any error bits set in the ones I posted, but it's certainly possible I missed something. I didn't see this in the DM source code from MCU+ SDK 10, but would any of the firmware have noticed error bits in the (L)PSC and cleared them?

    So there are few things that can be tried:

    • We can try unloading the USB driver prior to entering a suspend state.
    • Run 'echo N > /sys/module/printk/parameters/console_suspend' to see if there are any errors suspending the USB

    With console_suspend disabled, the output is the same with the onboard hub active (with which sleep fails) and with the onboard hub held in reset (with which sleep succeeds). There was nothing plugged into USB0 for these tests.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    root@mitysom-am62x:~# echo N > /sys/module/printk/parameters/console_suspend
    root@mitysom-am62x:~# rtcwake -s 10 -m mem
    rtcwake: wakeup from "mem" using /dev/rtc0 at Mon Jan 20 17:30:00 2025
    [ 66.819741] PM: suspend entry (deep)
    [ 66.823475] Filesystems sync: 0.000 seconds
    [ 66.830620] Freezing user space processes
    [ 66.836797] Freezing user space processes completed (elapsed 0.002 seconds)
    [ 66.843806] OOM killer disabled.
    [ 66.847027] Freezing remaining freezable tasks
    [ 66.852903] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
    [ 67.010888] am65-cpsw-nuss 8000000.ethernet eth1: Link is Down
    [ 68.750685] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 117: state: 1: ret 0
    [ 68.764147] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 178: state: 1: ret 0
    [ 68.784532] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 179: state: 1: ret 0
    [ 69.674582] remoteproc remoteproc0: stopped remote processor 5000000.m4fss
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I'm not sure whether you had something specific/different in mind for unloading the USB driver, but unloading just dwc3_am62 with rmmod does cause sleep to succeed on our hardware, even with devices still plugged in.

    With USB1 disabled in the device tree (to take the onboard hub out of the mix) and a flash drive plugged into USB0 (via OTG adapter):

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    root@mitysom-am62x:~# lsusb -t
    /: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    |__ Port 001: Dev 002, If 0, Class=Mass Storage, Driver=usb-storage, 480M
    root@mitysom-am62x:~# rmmod dwc3_am62
    [ 87.083655] xhci-hcd xhci-hcd.6.auto: remove, state 1
    [ 87.088862] usb usb1: USB disconnect, device number 1
    [ 87.094060] usb 1-1: USB disconnect, device number 2
    [ 87.162759] xhci-hcd xhci-hcd.6.auto: USB bus 1 deregistered
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    With USB1 disabled in the device tree and an external hub plugged into USB0 (via OTG adapter), the unload does have an error, but sleep still succeeds after that:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    root@mitysom-am62x:~# lsusb -t
    /: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    |__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/7p, 480M
    root@mitysom-am62x:~# rmmod dwc3_am62
    [ 84.639658] xhci-hcd xhci-hcd.6.auto: remove, state 4
    [ 84.644868] usb usb1: USB disconnect, device number 1
    [ 84.650058] usb 1-1: USB disconnect, device number 2
    [ 97.076302] xhci-hcd xhci-hcd.6.auto: Abort failed to stop command ring: -110
    [ 97.099594] xhci-hcd xhci-hcd.6.auto: xHCI host controller not responding, assume dead
    [ 97.107618] xhci-hcd xhci-hcd.6.auto: Unsuccessful disable slot 1 command, status 25
    [ 97.116788] xhci-hcd xhci-hcd.6.auto: USB bus 1 deregistered
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    With both USBs enabled in the device tree, the onboard hub on USB1 not held in reset, and nothing external plugged in, the unload output/error is the same as with the external hub (and again, sleep still succeeds).

    The EVM still sleeps successfully with the exact same external hub or flash drive plugged in though, so the sleep issue doesn't seem to be directly caused by the specific devices themselves.

    I do also notice now that the EVM has the dwc3, dwc3_am62, and xhci_plat_hcd drivers built into the kernel, whereas we load them as modules on our platform. Not that I really expect it to make a difference, but I did try rebuilding our kernel with these three drivers built in, and sleep still fails (in the same manner) with the onboard hub being the only downstream device. I didn't retest with the external devices with this kernel.

  • Hi Zach,

    Is there a separate set of LPSC registers from what I attached in my original post? I didn't notice any error bits set in the ones I posted, but it's certainly possible I missed something. I didn't see this in the DM source code from MCU+ SDK 10, but would any of the firmware have noticed error bits in the (L)PSC and cleared them?

    My apologies, I meant to say the LPSC register wouldn't provide the information for why it failed.


    Thanks for the experiments and updates.

    With USB1 disabled in the device tree and an external hub plugged into USB0 (via OTG adapter), the unload does have an error, but sleep still succeeds after that:

    I'll check with the USB team to see if they have any comments on unloading the USB driver, I wasn't expecting that to be an issue.

    I'm looking into if there are any USB registers to check that will point to additional information.

    Thanks,

    Anshu

  • Hi,

    Just wanted to check in and see whether there are any updates on TI's side. We unfortunately haven't had any further developments ourselves.

    Thanks,
    Zach

  • Hi Zach,

    Apologies for the delay as I was working on high priority work the past week. I'll try to get an update by Thursday this week.

    Thanks,

    Anshu

  • Hi Anshu,

    No worries, but wanted to check in again.

    In a previous post, you mentioned status checks on the USB IP that would prevent the LPSC state change from succeeding. Are those documented somewhere, or could you share them if not? Perhaps that would help guide further tests.

    Thanks,
    Zach

  • Hi Zach,

    I'll find time to discuss this with the team on Tuesday.


    Thanks,
    Anshu

  • Great, thank you!

  • Hi Zach,

    After some discussion with the team on this, we were able to replicate the issue on a TI EVM.


    Can you try to suspend the USB hub using 'echo 0 > /sys/bus/usb/drivers<hub-identifier>/<portN>/power/autosuspend_delay_ms'? Check if the changes were made with 'cat /sys/bus/usb/drivers<hub-identifier>/<portN>/power/runtime_status'. Then try the rtcwake commands.

    If this didn't work, can you share the output of 'ls -la /sys/bus/drivers/usb/' before and after connecting the USB hub?

    Additionally, can you share which driver is being used for the USB hub?

    Thanks,
    Anshu

  • Hi Anshu,

    It appears that both our onboard hub and the external hub we've tested (which both exhibit the same behavior) just use the generic hub driver.

    Trying to read or write the autosuspend_delay_ms files in any of the port directories results in an I/O error, which the kernel documentation says is the expected behavior if the driver doesn't support that attribute. (This is also the case on the EVM with the external hub.)

    The same is also true for the flash drive we've tested with, which appears to use the usb-storage driver.

    In case I'm misunderstanding, I tried this with autosuspend files such as:

    • /sys/bus/usb/drivers/hub/1-1\:1.0/1-1-port1/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb-storage/1-1\:1.0/ep_01/power/autosuspend_delay_ms

    In the case of both hubs, the port runtime_status is active; for the flash drive, it's unsupported.

    There was also an autosuspend_delay_ms file at the following path, but it was already set to 0, and the corresponding runtime_status file said suspended: /sys/bus/usb/drivers/usb/usb1/1-1/power/autosuspend_delay_ms

    Assuming the last path should be /sys/bus/usb/drivers, the output is the same before and after connecting the hub. This was actually before and after releasing it from reset, since I tested this with the onboard hub.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    root@mitysom-am62x:~# ls -la /sys/bus/usb/drivers
    total 0
    drwxr-xr-x 7 root root 0 Jan 1 00:00 .
    drwxr-xr-x 4 root root 0 Jan 1 00:00 ..
    drwxr-xr-x 2 root root 0 Jan 1 00:00 hub
    drwxr-xr-x 2 root root 0 Jan 1 00:00 usb
    drwxr-xr-x 2 root root 0 Jan 1 00:00 usb-storage
    drwxr-xr-x 2 root root 0 Jan 1 00:00 usbfs
    drwxr-xr-x 2 root root 0 Jan 1 00:00 usbhid
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    What was required to replicate the issue on an EVM? Setting a non-zero value for autosuspend_delay_ms? What driver was your device using?

    Thanks,
    Zach

  • Hello Zach,

    In case I'm misunderstanding, I tried this with autosuspend files such as:

    • /sys/bus/usb/drivers/hub/1-1\:1.0/1-1-port1/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb-storage/1-1\:1.0/ep_01/power/autosuspend_delay_ms

    While it is the USB Hub whose ports we intend to suspend, the sysfs location is incorrect. Please try running the 'echo 0' command at the following sysfs location:
    /sys/bus/usb/drivers/usb/
    There is a second 'usb' after drivers and it is only within this directory that we can configure the 'autosuspend_delay_ms' parameter of the Hub's ports. Based on the sysfs locations that you have shared above, it will probably be:
    echo 0 > /sys/bus/usb/drivers/usb/<usbX>/1-1\:1.0/usbX-portY/power/autosuspend_delay_ms
    For each Hub identified within:
    /sys/bus/usb/drivers/hub
    there should be its equivalent that shows up within:
    /sys/bus/usb/drivers/usb/<usbX>
    where X could be 1, 2, ... depending on the number of USB instances enabled in your system. Similarly, each Hub will have N ports which show up as:
    usbX-portY with Y ranging from 1 to N.

    Please try setting autosuspend_delay_ms to zero in the sysfs location mentioned above for all ports of the Hub and check if that works.

    Regards,
    Siddharth.

  • Hi Siddharth,

    For reference, here's our USB topology/info with just the onboard hub:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    root@mitysom-am62x:~# lsusb -t
    /: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    |__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/2p, 480M
    root@mitysom-am62x:~# cat /sys/kernel/debug/usb/devices
    T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1
    B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0
    D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
    P: Vendor=1d6b ProdID=0002 Rev= 6.06
    S: Manufacturer=Linux 6.6.32-g-g859bf5d9b23f xhci-hcd
    S: Product=xHCI Host Controller
    S: SerialNumber=xhci-hcd.6.auto
    C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
    I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
    E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms
    T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 2
    D: Ver= 2.10 Cls=09(hub ) Sub=00 Prot=02 MxPS=64 #Cfgs= 1
    P: Vendor=0451 ProdID=8027 Rev= 1.10
    S: SerialNumber=33000879F9DF
    C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    For each Hub identified within:
    /sys/bus/usb/drivers/hub
    there should be its equivalent that shows up within:
    /sys/bus/usb/drivers/usb/<usbX>

    I see the following in those two directories:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    root@mitysom-am62x:~# ls -lF /sys/bus/usb/drivers/hub/
    total 0
    lrwxrwxrwx 1 root root 0 Feb 19 18:01 1-0:1.0 -> '../../../../devices/platform/bus@f0000/f910000.dwc3-usb/31100000.usb/xhci-hcd.6.auto/usb1/1-0:1.0'/
    lrwxrwxrwx 1 root root 0 Feb 19 18:01 1-1:1.0 -> '../../../../devices/platform/bus@f0000/f910000.dwc3-usb/31100000.usb/xhci-hcd.6.auto/usb1/1-1/1-1:1.0'/
    --w------- 1 root root 4096 Feb 19 18:01 bind
    -rw-r--r-- 1 root root 4096 Feb 19 18:01 new_id
    -rw-r--r-- 1 root root 4096 Feb 19 18:01 remove_id
    --w------- 1 root root 4096 Feb 19 18:01 uevent
    --w------- 1 root root 4096 Feb 19 18:01 unbind
    root@mitysom-am62x:~# ls -lF /sys/bus/usb/drivers/usb/
    total 0
    lrwxrwxrwx 1 root root 0 Feb 19 18:02 1-1 -> '../../../../devices/platform/bus@f0000/f910000.dwc3-usb/31100000.usb/xhci-hcd.6.auto/usb1/1-1'/
    --w------- 1 root root 4096 Feb 19 18:02 bind
    --w------- 1 root root 4096 Feb 19 18:02 uevent
    --w------- 1 root root 4096 Feb 19 18:02 unbind
    lrwxrwxrwx 1 root root 0 Feb 19 18:02 usb1 -> '../../../../devices/platform/bus@f0000/f910000.dwc3-usb/31100000.usb/xhci-hcd.6.auto/usb1'/
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Ignoring symlinks (which just clutters the output with duplicates and warnings about loops, but finds the same set of files), we have the following autosuspend_delay_ms files for usb1:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@mitysom-am62x:~# find /sys/bus/usb/drivers/usb/usb1/ -name autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/ep_00/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-1/ep_00/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-1/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-1/1-1:1.0/1-1-port1/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-1/1-1:1.0/ep_81/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-1/1-1:1.0/1-1-port2/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-0:1.0/usb1-port1/power/autosuspend_delay_ms
    /sys/bus/usb/drivers/usb/usb1/1-0:1.0/ep_81/power/autosuspend_delay_ms
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    There's not quite an exact match for the path template you gave, so I tried them all.

    The following return I/O errors for both reads and writes:

    • /sys/bus/usb/drivers/usb/usb1/ep_00/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-1/ep_00/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-1/1-1:1.0/1-1-port1/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-1/1-1:1.0/ep_81/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-1/1-1:1.0/1-1-port2/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-0:1.0/usb1-port1/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-0:1.0/ep_81/power/autosuspend_delay_ms

    The last two were already set to 0, but I echoed 0 to them again nonetheless:

    • /sys/bus/usb/drivers/usb/usb1/power/autosuspend_delay_ms
    • /sys/bus/usb/drivers/usb/usb1/1-1/power/autosuspend_delay_ms

    The sleep behavior is still unchanged.

    Was the test hub TI used to replicate this on the EVM using a different driver?

    Thanks,
    Zach

  • Hello Zach,

    The USB Hub that I tested with is:
    https://zebronics.com/products/zeb-100hb
    which is a 4-port USB Hub from Zebronics.

    In my setup, the outputs for the commands are:
    1. lsusb -t

    Fullscreen
    1
    2
    /: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    |__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/4p, 480M
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    2. cat /sys/kernel/debug/usb/devices
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1
    B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0
    D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
    P: Vendor=1d6b ProdID=0002 Rev= 6.12
    S: Manufacturer=Linux 6.12.13-gcab6cafd320b xhci-hcd
    S: Product=xHCI Host Controller
    S: SerialNumber=xhci-hcd.0.auto
    C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
    I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
    E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl=256ms
    T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 4
    D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1
    P: Vendor=2148 ProdID=7022 Rev= 1.00
    S: Product=USB2.0 HUB
    C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
    I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
    E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    3. ls /sys/bus/usb/drivers/usb
    Fullscreen
    1
    1-1 bind uevent unbind usb1
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    4. ls /sys/bus/usb/drivers/usb/1-1/1-1\:1.0/
    Fullscreen
    1
    2
    3
    1-1-port1 1-1-port4 bInterfaceClass bInterfaceSubClass ep_81 subsystem
    1-1-port2 authorized bInterfaceNumber bNumEndpoints modalias supports_autosuspend
    1-1-port3 bAlternateSetting bInterfaceProtocol driver power uevent
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    Could you try a different approach which is to disable the Hub from sysfs and then attempt Deep Sleep followed by re-enabling it on system Resume to re-enumerate the Hub? The commands and sequence are as follows:
    1. Disable USB Hub and any devices connected to it by running:
    Fullscreen
    1
    echo 1 | tee /sys/bus/usb/drivers/usb/usb1/1-0\:1.0/usb1-port1/disable
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    2. Ensure that runtime_status of USB1 shows 'suspended'
    3. Put the SoC into Deep Sleep state
    4. When SoC resumes, re-enable USB Hub for enumerating it and any devices connected to it by running:
    Fullscreen
    1
    echo 0 | tee /sys/bus/usb/drivers/usb/usb1/1-0\:1.0/usb1-port1/disable
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Please try this and let me know if this works for you.

    Regards,
    Siddharth.

  • Hi Siddharth,

    Disabling the hub as you said produced the following output; I'm not sure if the errors are expected (I'm also not sure if the audit messages are related or just coincidentally occurred at around the same time):

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@mitysom-am62x:~# echo 1 | tee /sys/bus/usb/drivers/usb/usb1/1-0\:1.0/usb1-port1/disable
    1
    [ 38.282520] usb 1-1: USB disconnect, device number 2
    [ 50.672820] xhci-hcd xhci-hcd.6.auto: Abort failed to stop command ring: -110
    [ 50.696103] xhci-hcd xhci-hcd.6.auto: xHCI host controller not responding, assume dead
    [ 50.704041] xhci-hcd xhci-hcd.6.auto: HC died; cleaning up
    [ 50.709652] xhci-hcd xhci-hcd.6.auto: Timeout while waiting for configure endpoint command
    [ 50.712100] audit: type=1334 audit(1740506750.978:32): prog-id=23 op=LOAD
    tee: '/sys/bus/usb/drivers/usb/usb1/1-0:1.0/usb1-port1/disable': No such device
    [ 50.896066] audit: type=1334 audit(1740506751.166:33): prog-id=23 op=UNLOAD
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    The runtime_status file (/sys/bus/usb/drivers/usb/usb1/1-0\:1.0/usb1-port1/power/runtime_status) also still shows "active" after running the above command, although the physical hub no longer shows up in the lsusb output (the root hub still does).

    In this state, sleep appears to fail at the Linux driver level:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    root@mitysom-am62x:~# rtcwake -s 10 -m mem
    rtcwake: wakeup from "mem" using /dev/rtc0 at Tue Feb 25 18:10:36 2025
    [ 325.107720] PM: suspend entry (deep)
    [ 325.111476] Filesystems sync: 0.000 seconds
    [ 325.121644] Freezing user space processes
    [ 325.127581] Freezing user space processes completed (elapsed 0.001 seconds)
    [ 325.134607] OOM killer disabled.
    [ 325.137845] Freezing remaining freezable tasks
    [ 325.143690] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
    [ 325.151103] printk: Suspending console(s) (use no_console_suspend to debug)
    [ 325.159356] xhci-hcd xhci-hcd.6.auto: PM: dpm_run_callback(): platform_pm_suspend+0x0/0x80 returns -22
    [ 325.159397] xhci-hcd xhci-hcd.6.auto: PM: failed to suspend async: error -22
    [ 325.159429] PM: Some devices failed to suspend, or early wake event detected
    [ 325.159475] usb-conn-gpio usb_microb_connector: repeated role: device
    [ 325.190533] OOM killer enabled.
    [ 325.193679] Restarting tasks ... done.
    [ 325.199297] random: crng reseeded on system resumption
    [ 325.204735] PM: suspend exit
    rtcwake: write error
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Running the command from step 4 at this point also fails with a "no such device" error.

    Thanks,
    Zach

  • Hello Zach,

    Thank you for testing out the suggestions. Going back to the initial non-working scenario, could you share the output of the following command before and after running the "rtcwake" command?

    Fullscreen
    1
    devmem2 0x000F4258
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    0x000F4258 corresponds to the PAD_CONFIG register for USB1_DRVVBUS. I am specifically looking for the value of BIT-30 (zero based indexing) which indicates whether or not a Wakeup event has occurred. This will help us determine if the USB Hub is immediately triggering a Wakeup due to which Deep Sleep transition fails.

    Regards,
    Siddharth.

  • Hi Siddharth,

    I have to use JTAG to read the register after running rtcwake, since the DM aborts and the board never wakes up; but both before and after rtcwake, the value of that register is 0x00050000.

    Thanks,
    Zach

  • Hello Zach,

    Going through this thread again, I came across the following points which might be important to consider for the next steps to be performed:

    • Our hardware:
      • Both USBs enabled, nothing plugged into either, hub active: sleep fails
      • Both USBs enabled, nothing plugged into either, hub in reset: sleep succeeds
      • Only USB0 enabled, nothing plugged in or only OTG adapter plugged in (to force host mode): sleep succeeds
      • Only USB0 enabled, flash drive or external hub plugged in via OTG adapter: sleep fails
    • EVM (both USBs enabled for all tests):
      • Nothing plugged into either interface or only Type-C adapter plugged into USB0 (to force host mode): sleep succeeds
      • Flash drive or external hub plugged into USB1 or the same plugged into USB0 via Type-C adapter: sleep succeeds

    The points to pay attention to are:
    a) On the custom hardware that you are using, both USB0 and USB1 cause Deep Sleep to fail if they have devices connected to them.
    b) On TI EVM, having devices connected to USB0 and USB1 doesn't affect Deep Sleep.

    Based on the above, it seems to be a board integration issue. If possible, please probe all the USB lines on both the custom hardware and TI EVM for either of USB0 or USB1 during the Deep Sleep sequence. That might give an idea regarding the cause of the issue.

    Regards,
    Siddharth.

  • Hi Siddharth,

    I think that led us down the right path; we had compared the VBUS behavior to the EVM previously, but only on the connector side of our onboard hub. What we're seeing is that the EVM's VBUS stays enabled during sleep while our own board's doesn't, because we have external pull-downs on DRVVBUS.

    If we remove the pull-down from one of the interfaces (USB0, without the hub) on our board, it now sleeps and wakes properly with or without a USB device plugged into that interface. Similarly, if we add an equivalent pull-down to the EVM, it now only sleeps properly without a USB device plugged in, like our board's original behavior.

    We do still have a couple questions to confirm we're understanding the problem correctly; if you'd be able to provide some insight it'd be greatly appreciated:

    1. With the DRVVBUS PADCONFIG register set to 0x00010000 or 0x00050000, is it correct that during deep sleep the driver for this pad is disabled, but the internal pull resistor is enabled to hold the previous value? (So, in this case a pull-up?)
    2. Would the LPSC timeout we see with the pull-downs be caused by the change in VBUS itself (on the USB_VBUS input back to the SoC) or some interaction with the downstream device?

    Thanks,
    Zach

  • Hello Zach,

    With the DRVVBUS PADCONFIG register set to 0x00010000 or 0x00050000, is it correct that during deep sleep the driver for this pad is disabled, but the internal pull resistor is enabled to hold the previous value? (So, in this case a pull-up?)

    Please refer to the following table corresponding to the definition of the PADCONFIG bits:


    The table is present on page 5829 of the AM625 Technical Reference Manual (https://www.ti.com/lit/ug/spruiv7b/spruiv7b.pdf).
    The behavior during Deep Sleep is configured by BIT(27) DS_PULLUD_EN and BIT(28) DS_PULLTYPE_SEL. In both cases (0x00010000 and 0x00050000), BIT(27) is zero, indicating that "Pullup / pulldown is enabled". Since BIT(28) is also zero, it indicates that "0 - Offmode pulldown selected". So the DRVVBUS PADCONFIG register indicates a Pull-Down in Deep Sleep state. To support USB Wakeup, BIT(28) is set to 1:
    https://github.com/torvalds/linux/blob/v6.14-rc6/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi#L259
    AM62X_IOPAD(0x0258, PIN_OUTPUT | PIN_DS_PULLUD_ENABLE | PIN_DS_PULL_UP, 0) /* (F18/E16) USB1_DRVVBUS */
    and we don't see issues in this case on the EVM.

    It appears to me that a PULL-UP is required during Deep Sleep, and for that to work, the external Pull-Downs on DRVVBUS have to be removed.

    Would the LPSC timeout we see with the pull-downs be caused by the change in VBUS itself (on the USB_VBUS input back to the SoC) or some interaction with the downstream device?

    I am not sure but if I have to guess then I would assume that the SoC entering Deep Sleep state requires USB_VBUS to be pulled up as indicated above, and failing to do so (due to the external Pull-Down resistor) is probably resulting in DM (Device Manager) handling it as an error. We could get details from the DM team and the USB IP team to confirm the same.

    Regards,
    Siddharth.

  • Hi Siddharth,

    Thanks for the pointer to that dtsi; the older versions we had looked at didn't have the DS settings. Are those settings applied when bit 24 is 0 (as it would appear to be in that line), or are they configuring the "OFF mode value" that's used when bit 24 is 1?

    Assuming there's an internal pull-up on DRVVBUS (whether by default or from the device tree setting), our main concern at this point is determining how to update the interface with the hub (TUSB4020BIPHP) to avoid this issue. Since that hub isn't VBUS-powered, we don't have a current-limiting switch for VBUS there; we just connect DRVVBUS to the hub's USB_VBUS pin through a voltage divider to shift it to the appropriate voltage for that pin. It's not clear to us from the datasheet or TRM whether the AM62's USBn_VBUS input is relevant/required for a host-only interface, or even what its high/low thresholds are, so we also have it connected to a voltage divider from DRVVBUS. On this interface, these voltage dividers are acting as the pull-down, so it seems that we'd need to redesign this part of the circuit to avoid the pull-down. We're also looking into using larger resistor values for the dividers so the internal pull-up has less effect, but so far that's had mixed results.

    Is there a reference schematic or recommendations somewhere for using the AM62 with this (or another self-powered) hub? That would be our ideal path forward, but if not, that's where it would be helpful to understand exactly why what we're doing doesn't work. (And in that case, if this could be forwarded along to the DM and/or USB IP team as appropriate, we'd be appreciative.)

    Thanks,
    Zach

  • Hello Zach,

    Are those settings applied when bit 24 is 0 (as it would appear to be in that line), or are they configuring the "OFF mode value" that's used when bit 24 is 1?

    The macros used for Deep Sleep are defined in:
    https://github.com/torvalds/linux/blob/v6.14-rc6/arch/arm64/boot/dts/ti/k3-pinctrl.h
    PIN_DS_PULLUD_ENABLE => BIT(27) should be zero
    PIN_DS_PULL_UP => BIT(28) should be one
    BIT(24) is unaffected by the AM62X_IOPAD macro used for USB1_DRVVBUS and should remain at its reset value of zero.

    For the other questions that you have asked, support from the Hardware team will be required. Anshu can reach out to the Hardware team to get clarification on those questions.

    Regards,
    Siddharth.

  • ssuming there's an internal pull-up on DRVVBUS

    There is a pulldown for the DRVVBUS enabled after reset

    The USVx_VBUS connection is optional for host.

    For the device, a switched dc input along with the VBUS divider as per the SOC data sheet is recommended.

    Regards,

    Sreenivasa

  • Thanks, knowing that USBn_VBUS is not required for hosts, we were able to prototype a solution and confirm that we can suspend the board with USB devices plugged into either/both interface(s).

    Thanks everyone for the help with this!

  • Hello Zach

    Thank you and good to hear you have been able to make progress.

    Would you mind summarizing the steps or the bits that were set in the PADconfig register to enable the functionality.

    Regards,

    Sreenivasa