From: Stephen Warren Date: Sat, 11 Apr 2015 03:05:21 +0000 (-0600) Subject: usb: dwc2: correctly program hcchar for LS devices X-Git-Tag: v2015.07-rc1~407 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ed9bcbc792bdcb8b4443c9aa5dff30ad6f8524c0;p=oweals%2Fu-boot.git usb: dwc2: correctly program hcchar for LS devices A bit must be set in HCCHAR when communicating with low-speed devices. I have no idea why there's no corresponding bit to distinguish between full-speed and high-speed devices, but no matter; they all work now! Signed-off-by: Stephen Warren --- diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index b506ff23ed..b1d94ccc1a 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -398,15 +398,18 @@ static void dwc_otg_core_init(struct dwc2_core_regs *regs) * @param hc Information needed to initialize the host channel */ static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num, - uint8_t dev_addr, uint8_t ep_num, uint8_t ep_is_in, - uint8_t ep_type, uint16_t max_packet) + struct usb_device *dev, uint8_t dev_addr, uint8_t ep_num, + uint8_t ep_is_in, uint8_t ep_type, uint16_t max_packet) { struct dwc2_hc_regs *hc_regs = ®s->hc_regs[hc_num]; - const uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) | - (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) | - (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) | - (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) | - (max_packet << DWC2_HCCHAR_MPS_OFFSET); + uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) | + (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) | + (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) | + (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) | + (max_packet << DWC2_HCCHAR_MPS_OFFSET); + + if (dev->speed == USB_SPEED_LOW) + hcchar |= DWC2_HCCHAR_LSPDDEV; /* Clear old interrupt conditions for this host channel. */ writel(0x3fff, &hc_regs->hcint); @@ -766,8 +769,8 @@ int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in, do { /* Initialize channel */ - dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, in, eptype, - max); + dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, dev, devnum, ep, in, + eptype, max); xfer_len = len - done; if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)