[U-Boot] [PATCH 1/2] 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 --- drivers/usb/host/dwc2.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index b506ff23ed38..b1d94ccc1a69 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)

As best I can tell, there's no difference between bulk and interrupt transfers in terms of how the HW should be programmed, at least given that we're executing one transaction at a time rather than scheduling them into frames for maximum throughput.
This patch ends up sharing the toggle bit state between bulk and interrupt transfers on a particular EP. However I believe this is fine; AFAIK a given EP either uses bulk or interrupt transfers and doesn't mix them.
This patch doesn't do anything with the "interval" parameter for interrupt transfers, but then most other USB controller drivers in U-Boot don't either.
It turns out that one of my keyboards is happy to work using control transfers but the other only gives non-zero "HID reports" via interrupt transfers.
Signed-off-by: Stephen Warren swarren@wwwdotorg.org --- drivers/usb/host/dwc2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index b1d94ccc1a69..f3fbe76acf9b 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -904,9 +904,8 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int len, int interval) { - printf("dev = %p pipe = %#lx buf = %p size = %d int = %d\n", - dev, pipe, buffer, len, interval); - return -ENOSYS; + /* FIXME: what is interval? */ + return submit_bulk_msg(dev, pipe, buffer, len); }
/* U-Boot USB control interface */

On Saturday, April 11, 2015 at 05:05:22 AM, Stephen Warren wrote:
As best I can tell, there's no difference between bulk and interrupt transfers in terms of how the HW should be programmed, at least given that we're executing one transaction at a time rather than scheduling them into frames for maximum throughput.
This patch ends up sharing the toggle bit state between bulk and interrupt transfers on a particular EP. However I believe this is fine; AFAIK a given EP either uses bulk or interrupt transfers and doesn't mix them.
This patch doesn't do anything with the "interval" parameter for interrupt transfers, but then most other USB controller drivers in U-Boot don't either.
It turns out that one of my keyboards is happy to work using control transfers but the other only gives non-zero "HID reports" via interrupt transfers.
Signed-off-by: Stephen Warren swarren@wwwdotorg.org
Applied to u-boot-usb/topic/dwc2, thanks!
Best regards, Marek Vasut

On Saturday, April 11, 2015 at 05:05:21 AM, Stephen Warren wrote:
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
Applied to u-boot-usb/topic/dwc2, thanks!
Best regards, Marek Vasut
participants (2)
-
Marek Vasut
-
Stephen Warren