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:
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
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:
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 ???????? ???????? ???????? ???????? 0x00400140 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400160 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400180 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004001A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004001C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004001E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400200 00000301 00000200 00000200 00000200 00000200 00000200 00000200 00000200 0x00400220 00000200 00000200 ???????? ???????? ???????? ???????? ???????? ???????? 0x00400240 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400260 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400280 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004002A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004002C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004002E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400300 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x00400320 00000000 00000000 ???????? ???????? ???????? ???????? ???????? ???????? 0x00400340 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400360 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400380 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004003A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004003C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004003E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400400 0000000D 00000004 00000000 00000004 00000004 00000004 00000004 00000004 0x00400420 00000004 00000000 ???????? ???????? ???????? ???????? ???????? ???????? 0x00400440 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400460 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400480 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004004A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004004C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004004E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400500 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400520 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400540 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400560 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400580 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004005A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004005C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004005E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400600 000039FF 000019FF 000011FF 000019FF 000019FF 000019FF 000019FF 000019FF 0x00400620 000019FF 000011FF 000011FF 000011FF 000011FF 000011FF 000011FF 000011FF 0x00400640 000019FF 000011FF 000011FF 000011FF 000011FF 000011FF 000011FF 000011FF 0x00400660 000011FF 000011FF 000011FF 000011FF 000011FF 000019FF 000019FF 000011FF 0x00400680 000011FF 000059FF 000011FF 000011FF 000011FF 000011FF 000019FF 000019FF 0x004006A0 000119FF 000211FF 000319FF 000311FF 000311FF 000419FF 000519FF 000619FF 0x004006C0 000719FF 000819FF 000811FF 000911FF ???????? ???????? ???????? ???????? 0x004006E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400700 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400720 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400740 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400760 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400780 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004007A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004007C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004007E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400800 00001F03 00011F03 00001F03 00001F03 00001F03 00001F03 00001F03 00001F03 0x00400820 00000A00 00000F02 00000F02 00000F02 00000F02 00000F02 00001F03 00000A00 0x00400840 00000A00 00000A00 00000A00 00000A00 00000A00 00000A00 00000A00 00000F02 0x00400860 00001F0A 00000A00 00000A00 00001F03 00001F03 00001F03 00000A00 00001F03 0x00400880 00001F03 00001F03 00001F03 00000A00 00001F03 00001F03 00000A00 00000A00 0x004008A0 00010A00 00000A00 00010A00 00000A00 00000A00 00010A00 00010A00 00010A00 0x004008C0 00010A00 00010A00 00000A00 00000A00 ???????? ???????? ???????? ???????? 0x004008E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400900 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400920 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400940 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400960 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400980 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004009A0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004009C0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x004009E0 ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? 0x00400A00 00000103 00000103 00000103 00000103 00000103 00000103 00000103 00000103 0x00400A20 00000100 00000102 00000102 00000102 00000102 00000102 00000103 00000100 0x00400A40 00000100 00000100 00000100 00000100 00000100 00000100 00000100 00000102 0x00400A60 00000102 00000100 00000100 00000103 00000103 00000103 00000100 00000103 0x00400A80 00000103 00000103 00000103 00000100 00000103 00000103 00000100 00000100 0x00400AA0 00000100 00000100 00000100 00000100 00000100 00000100 00000100 00000100 0x00400AC0 00000100 00000100 00000100 00000100 ???????? ???????? ???????? ????????
DM firmware version:
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
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):
rtcwake -s 10 -m mem
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:
We've now tried a few setups with external devices, on both our hardware and the EVM:
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:
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.
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
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):
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
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:
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
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
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:
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.
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
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:
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 I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=01 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms I:* If#= 0 Alt= 1 #EPs= 1 Cls=09(hub ) Sub=00 Prot=02 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms
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:
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'/
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:
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
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:
The last two were already set to 0, but I echoed 0 to them again nonetheless:
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
/: 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
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
1-1 bind uevent unbind usb1
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
echo 1 | tee /sys/bus/usb/drivers/usb/usb1/1-0\:1.0/usb1-port1/disable
echo 0 | tee /sys/bus/usb/drivers/usb/usb1/1-0\:1.0/usb1-port1/disable
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):
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
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:
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
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?
devmem2 0x000F4258
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:
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