]> git.sur5r.net Git - u-boot/blobdiff - drivers/usb/host/xhci.c
usb: xhci: Fix config fail of FS hub behind a HS hub with MTT
[u-boot] / drivers / usb / host / xhci.c
index 3adb0028f2ae3501b84b0cab8d4fc1e6e432d2d6..f9c6bbb9e983419c5d789ab92911c6b90e3b4fd8 100644 (file)
@@ -1424,7 +1424,7 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
 
        ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
        /* Initialize the input context control */
-       ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
+       ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
        ctrl_ctx->drop_flags = 0;
 
        xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -1435,8 +1435,15 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
 
        /* Update hub related fields */
        slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
-       if (hub->tt.multi && udev->speed == USB_SPEED_HIGH)
+       /*
+        * refer to section 6.2.2: MTT should be 0 for full speed hub,
+        * but it may be already set to 1 when setup an xHCI virtual
+        * device, so clear it anyway.
+        */
+       if (hub->tt.multi)
                slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+       else if (udev->speed == USB_SPEED_FULL)
+               slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
        slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild));
        /*
         * Set TT think time - convert from ns to FS bit times.
@@ -1452,6 +1459,7 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
                think_time = (think_time / 666) - 1;
        if (udev->speed == USB_SPEED_HIGH)
                slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time));
+       slot_ctx->dev_state = 0;
 
        return xhci_configure_endpoints(udev, false);
 }