summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Warren <swarren@wwwdotorg.org>2015-04-10 21:05:21 -0600
committerMarek Vasut <marex@denx.de>2015-04-14 05:47:59 +0200
commited9bcbc792bdcb8b4443c9aa5dff30ad6f8524c0 (patch)
treec994b66ae0c6d24e0c850e5aba4733fbc1550e06
parent122426d46e31391480c4b83b1003e4feca24d491 (diff)
downloadu-boot-imx-ed9bcbc792bdcb8b4443c9aa5dff30ad6f8524c0.zip
u-boot-imx-ed9bcbc792bdcb8b4443c9aa5dff30ad6f8524c0.tar.gz
u-boot-imx-ed9bcbc792bdcb8b4443c9aa5dff30ad6f8524c0.tar.bz2
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 <swarren@wwwdotorg.org>
-rw-r--r--drivers/usb/host/dwc2.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index b506ff2..b1d94cc 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 = &regs->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)