From 3f484226793166c75bd56784832d4c1a84061ad5 Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Tue, 22 May 2018 15:24:48 +0200 Subject: usb: xhci-rcar: deregister before deactivating clock During the execution of xhci_deregister xHCI registers are accessed. If the clock is already deactivated when xhci_deregister is called this can lead to undefined behavior. Change the order to deregister the device before deactivating the clock. Signed-off-by: Matthias Blankertz --- drivers/usb/host/xhci-rcar.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index a837afc483b..f2e91ef0feb 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -117,12 +117,15 @@ err_clk: static int xhci_rcar_deregister(struct udevice *dev) { + int ret; struct rcar_xhci_platdata *plat = dev_get_platdata(dev); + ret = xhci_deregister(dev); + clk_disable(&plat->clk); clk_free(&plat->clk); - return xhci_deregister(dev); + return ret; } static int xhci_rcar_ofdata_to_platdata(struct udevice *dev) -- cgit v1.3.1 From 793c819c6e2168110ad7cfca0349738c79d79a1f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 23 May 2018 23:40:47 -0700 Subject: usb: xhci: Set accurate add context flags when updating hub attributes If a USB 3.0 hub is plugged into the root port of the xHC, the xHCI driver will issue a 'Configure Endpoint' command to the xHC for it to update its internal data structure for this hub device. The hub attributes are in the slot context so we need tell xHC to update the slot context by setting the add context flags of the input control context to only cover the slot context. At present the add context flags is or'ed with the slot context bit, but it should really be accurately set to the slot context, as the variable that holds the value of the add context flags comes from whatever was set in the last command execution, which may contain additional contexts that 'Configure Endpoint' command should not touch. Some xHC implementations like x86 don't complain such, but it was observed on Renesas RCar Gen3 platform that the RCar xHC complains with a 'TRB error' completion codes as the response. Reported-by: Marek Vasut Signed-off-by: Bin Meng Tested-by: Marek Vasut Tested-by: Matthias Blankertz --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3adb0028f2a..565948c1199 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -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); -- cgit v1.3.1 From ae751b060e8cee3f9c48112898cd3e31ee6c0734 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 23 May 2018 23:40:48 -0700 Subject: usb: xhci: Initialize dev_state to 0 in the input slot context Per xHCI spec chapter 6.2.2 table 6-7, as input, software shall initialize the dev_state field to '0'. Though this does not seem to cause any issue with most xHC implementations, let's do this to conform with the spec. Signed-off-by: Bin Meng Tested-by: Marek Vasut Tested-by: Matthias Blankertz --- drivers/usb/host/xhci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 565948c1199..8c1126e79dd 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1452,6 +1452,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); } -- cgit v1.3.1 From eaaefb066c86f08fb285e73fb8c5fbf497be6b57 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 23 May 2018 23:40:49 -0700 Subject: usb: xhci: Fix config fail of FS hub behind a HS hub with MTT If a full speed hub connects to a high speed hub which supports MTT, the MTT field of its slot context will be set to 1 when xHCI driver setups an xHCI virtual device in xhci_setup_addressable_virt_dev(). Once usb core fetch its hub descriptor, and need to update the xHC's internal data structures for the device, the HUB field of its slot context will be set to 1 too, meanwhile MTT is also set before, this will cause configure endpoint command fail. In the case, we should clear MTT to 0 for full speed hub according to section 6.2.2. This keeps in sync with Linux kernel commit: 096b110: usb: xhci: fix config fail of FS hub behind a HS hub with MTT Signed-off-by: Bin Meng --- drivers/usb/host/xhci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8c1126e79dd..f9c6bbb9e98 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -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. -- cgit v1.3.1 From e40406603fe22a5b18d7e8ac7a2eb0f2d2b13cf1 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 23 May 2018 23:40:50 -0700 Subject: usb: xhci: Handle endianness in xhci_set_configuration() In xhci_set_configuration(), 'Context Entries' field in the slot context was cleared with mask LAST_CTX_MASK, but it should have taken the endianness into consideration. Signed-off-by: Bin Meng --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f9c6bbb9e98..9ded14cc3cb 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -536,7 +536,7 @@ static int xhci_set_configuration(struct usb_device *udev) /* slot context */ xhci_slot_copy(ctrl, in_ctx, out_ctx); slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx); - slot_ctx->dev_info &= ~(LAST_CTX_MASK); + slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK)); slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0); xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0); -- cgit v1.3.1 From afa314d3a37797bd88c9a379a6fa150e6829fdf9 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Thu, 24 May 2018 17:11:57 +0200 Subject: rockchip: xhci: remove DTS parsing for PHY (which is unused) The xhci wrapper-driver for Rockchip searches the DTS to find its child node compatbile with 'rockchip,rk3399-usb3-phy' to retrieve the base-address of the PHY. However, this is currently broken (and always has been), returning NULL. However, the (wrongly) retrieved base-address is never used. We thus remove this code for now. Signed-off-by: Philipp Tomsich --- drivers/usb/host/xhci-rockchip.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c index 060a6c43092..f19bea3a91b 100644 --- a/drivers/usb/host/xhci-rockchip.c +++ b/drivers/usb/host/xhci-rockchip.c @@ -17,7 +17,6 @@ struct rockchip_xhci_platdata { fdt_addr_t hcd_base; - fdt_addr_t phy_base; struct udevice *vbus_supply; }; @@ -35,7 +34,6 @@ struct rockchip_xhci { static int xhci_usb_ofdata_to_platdata(struct udevice *dev) { struct rockchip_xhci_platdata *plat = dev_get_platdata(dev); - struct udevice *child; int ret = 0; /* @@ -47,20 +45,6 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev) return -ENXIO; } - /* Get the base address for usbphy from the device node */ - for (device_find_first_child(dev, &child); child; - device_find_next_child(&child)) { - if (!device_is_compatible(child, "rockchip,rk3399-usb3-phy")) - continue; - plat->phy_base = devfdt_get_addr(child); - break; - } - - if (plat->phy_base == FDT_ADDR_T_NONE) { - pr_err("Can't get the usbphy register address\n"); - return -ENXIO; - } - /* Vbus regulator */ ret = device_get_supply_regulator(dev, "vbus-supply", &plat->vbus_supply); -- cgit v1.3.1