usb: host: xhci-tegra: Tegra186/Tegra194 LPM
diff mbox series

Message ID 20200224062145.25785-1-jckuo@nvidia.com
State Accepted
Headers show
Series
  • usb: host: xhci-tegra: Tegra186/Tegra194 LPM
Related show

Commit Message

JC Kuo Feb. 24, 2020, 6:21 a.m. UTC
Tegra186 and Tegra194 xHC supports USB 3.0 LPM. This commit enables
XHCI_LPM_SUPPORT quirk for Tegra186 and Tegra194.

Signed-off-by: JC Kuo <jckuo@nvidia.com>
---
 drivers/usb/host/xhci-tegra.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Mathias Nyman Feb. 24, 2020, 10:51 a.m. UTC | #1
On 24.2.2020 8.21, JC Kuo wrote:
> Tegra186 and Tegra194 xHC supports USB 3.0 LPM. This commit enables
> XHCI_LPM_SUPPORT quirk for Tegra186 and Tegra194.
> 
> Signed-off-by: JC Kuo <jckuo@nvidia.com>

Thanks, added to queue

-Mathias
Thierry Reding Feb. 24, 2020, 12:51 p.m. UTC | #2
On Mon, Feb 24, 2020 at 02:21:45PM +0800, JC Kuo wrote:
> Tegra186 and Tegra194 xHC supports USB 3.0 LPM. This commit enables
> XHCI_LPM_SUPPORT quirk for Tegra186 and Tegra194.
> 
> Signed-off-by: JC Kuo <jckuo@nvidia.com>
> ---
>  drivers/usb/host/xhci-tegra.c | 7 +++++++
>  1 file changed, 7 insertions(+)

I see that Mathias has already queued this up, but for the record:

Acked-by: Thierry Reding <treding@nvidia.com>

JC, is there some way that we can test this? I see that there are some
sysfs files that can control LPM enablement on a per-device basis, but
is there some way to check that this works as expected? Or do we just
assume everything is fine as long as all the devices continue to operate
properly? Perhaps there are some state transition counters or something
that would indicate that devices are properly transitioning?

Thierry
JC Kuo Feb. 26, 2020, 8:12 a.m. UTC | #3
Hi Thierry,
Yes, it can be verified with a LPM capable device. For example, a VIA USB 3.0
hub is connected to Jetson-Xavier. "lsusb -v" output [1] shows the device
supports LPM and the host has enabled U1/U2 states for the device. If host LPM
is disabled, there will be no "U1 Enabled" and "U2 Enabled" strings in "Device
Status" section.

To check LPM operation, disconnect all USB 3.0 devices from the hub and disable
runtime PM for the super-speed portion of the hub, so that it won't be
auto-suspended.
root@tegra-ubuntu:~# echo on > /sys/bus/usb/devices/2-4/power/control

Since there is no data transaction for the hub, link will enter U2 soon. This
can be checked by reading XHCI.PORTSC register. In below, PLS (Port Link State)
field is U2.
root@tegra-ubuntu:~# devmem 0x3610450
0x00001243

Thanks,
JC

[1] lsusb -v -d 2109:0820
Bus 002 Device 002: ID 2109:0820 VIA Labs, Inc.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               3.10
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         3
  bMaxPacketSize0         9
  idVendor           0x2109 VIA Labs, Inc.
  idProduct          0x0820
  bcdDevice            4.e3
  iManufacturer           1 VIA Labs, Inc.
  iProduct                2 USB3.0 Hub
  iSerial                 0
  bNumConfigurations      1

...
Binary Object Store Descriptor:
  bLength                 5
  bDescriptorType        15
  wTotalLength           42
  bNumDeviceCaps          3
  USB 2.0 Extension Device Capability:
    bLength                 7
    bDescriptorType        16
    bDevCapabilityType      2
    bmAttributes   0x00000002
      Link Power Management (LPM) Supported
  SuperSpeed USB Device Capability:
    bLength                10
    bDescriptorType        16
    bDevCapabilityType      3
    bmAttributes         0x00
    wSpeedsSupported   0x000e
      Device can operate at Full Speed (12Mbps)
      Device can operate at High Speed (480Mbps)
      Device can operate at SuperSpeed (5Gbps)
    bFunctionalitySupport   1
      Lowest fully-functional device speed is Full Speed (12Mbps)
    bU1DevExitLat           4 micro seconds
    bU2DevExitLat         231 micro seconds
  Container ID Device Capability:
    bLength                20
    bDescriptorType        16
    bDevCapabilityType      4
    bReserved               0
    ContainerID             {5cf3ee30-d507-4925-b001-802d79434c30}
Device Status:     0x000d
  Self Powered
  U1 Enabled
  U2 Enabled



On 2/24/20 8:51 PM, Thierry Reding wrote:
> On Mon, Feb 24, 2020 at 02:21:45PM +0800, JC Kuo wrote:
>> Tegra186 and Tegra194 xHC supports USB 3.0 LPM. This commit enables
>> XHCI_LPM_SUPPORT quirk for Tegra186 and Tegra194.
>>
>> Signed-off-by: JC Kuo <jckuo@nvidia.com>
>> ---
>>  drivers/usb/host/xhci-tegra.c | 7 +++++++
>>  1 file changed, 7 insertions(+)
> 
> I see that Mathias has already queued this up, but for the record:
> 
> Acked-by: Thierry Reding <treding@nvidia.com>
> 
> JC, is there some way that we can test this? I see that there are some
> sysfs files that can control LPM enablement on a per-device basis, but
> is there some way to check that this works as expected? Or do we just
> assume everything is fine as long as all the devices continue to operate
> properly? Perhaps there are some state transition counters or something
> that would indicate that devices are properly transitioning?
> 
> Thierry
>
Mathias Nyman Feb. 26, 2020, 9:32 a.m. UTC | #4
On 26.2.2020 10.12, JC Kuo wrote:
> Hi Thierry,
> Yes, it can be verified with a LPM capable device. For example, a VIA USB 3.0
> hub is connected to Jetson-Xavier. "lsusb -v" output [1] shows the device
> supports LPM and the host has enabled U1/U2 states for the device. If host LPM
> is disabled, there will be no "U1 Enabled" and "U2 Enabled" strings in "Device
> Status" section.
> 
> To check LPM operation, disconnect all USB 3.0 devices from the hub and disable
> runtime PM for the super-speed portion of the hub, so that it won't be
> auto-suspended.
> root@tegra-ubuntu:~# echo on > /sys/bus/usb/devices/2-4/power/control
> 
> Since there is no data transaction for the hub, link will enter U2 soon. This
> can be checked by reading XHCI.PORTSC register. In below, PLS (Port Link State)
> field is U2.
> root@tegra-ubuntu:~# devmem 0x3610450
> 0x00001243

A more human friendly way to read portsc registers:

# cat /sys/kernel/debug/usb/xhci/0000\:00\:14.0/ports/port02/portsc 
Powered Connected Enabled Link:U0 PortSpeed:3 Change: Wake: 

-Mathias
JC Kuo Feb. 27, 2020, 2:03 a.m. UTC | #5
Hi Mathias,
Thanks for the tip. It's really helpful.

root@tegra-ubuntu:/d/usb/xhci/3610000.usb/ports/port04# cat portsc
Powered Connected Enabled Link:U2 PortSpeed:4 Change: Wake:

-JC

On 2/26/20 5:32 PM, Mathias Nyman wrote:
> On 26.2.2020 10.12, JC Kuo wrote:
>> Hi Thierry,
>> Yes, it can be verified with a LPM capable device. For example, a VIA USB 3.0
>> hub is connected to Jetson-Xavier. "lsusb -v" output [1] shows the device
>> supports LPM and the host has enabled U1/U2 states for the device. If host LPM
>> is disabled, there will be no "U1 Enabled" and "U2 Enabled" strings in "Device
>> Status" section.
>>
>> To check LPM operation, disconnect all USB 3.0 devices from the hub and disable
>> runtime PM for the super-speed portion of the hub, so that it won't be
>> auto-suspended.
>> root@tegra-ubuntu:~# echo on > /sys/bus/usb/devices/2-4/power/control
>>
>> Since there is no data transaction for the hub, link will enter U2 soon. This
>> can be checked by reading XHCI.PORTSC register. In below, PLS (Port Link State)
>> field is U2.
>> root@tegra-ubuntu:~# devmem 0x3610450
>> 0x00001243
> 
> A more human friendly way to read portsc registers:
> 
> # cat /sys/kernel/debug/usb/xhci/0000\:00\:14.0/ports/port02/portsc 
> Powered Connected Enabled Link:U0 PortSpeed:3 Change: Wake: 
> 
> -Mathias
>

Patch
diff mbox series

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 8163aefc6c6b..a6e36b3c968f 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -203,6 +203,7 @@  struct tegra_xusb_soc {
 
 	bool scale_ss_clock;
 	bool has_ipfs;
+	bool lpm_support;
 };
 
 struct tegra_xusb_context {
@@ -1779,6 +1780,7 @@  static const struct tegra_xusb_soc tegra186_soc = {
 		.data_out = 0xec,
 		.owner = 0xf0,
 	},
+	.lpm_support = true,
 };
 
 static const char * const tegra194_supply_names[] = {
@@ -1808,6 +1810,7 @@  static const struct tegra_xusb_soc tegra194_soc = {
 		.data_out = 0x70,
 		.owner = 0x74,
 	},
+	.lpm_support = true,
 };
 MODULE_FIRMWARE("nvidia/tegra194/xusb.bin");
 
@@ -1832,7 +1835,11 @@  static struct platform_driver tegra_xusb_driver = {
 
 static void tegra_xhci_quirks(struct device *dev, struct xhci_hcd *xhci)
 {
+	struct tegra_xusb *tegra = dev_get_drvdata(dev);
+
 	xhci->quirks |= XHCI_PLAT;
+	if (tegra && tegra->soc->lpm_support)
+		xhci->quirks |= XHCI_LPM_SUPPORT;
 }
 
 static int tegra_xhci_setup(struct usb_hcd *hcd)