Skip to contentSkip to conversation

usb: dwc2: correctly program hcchar for LS devices

PATCH New Stephen Warren 2 participants 4 messages Apr 11, 2015 USB

lore
Share & tools
lore
#0 lore raw

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!

---
 drivers/usb/host/dwc2.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)
drivers/usb/host/dwc2.c +12 -9
index b506ff23ed38..b1d94ccc1a69 100644
@@ -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)
Signature · 1 line
1.9.1
#1 lore raw

PATCH 2/2 usb: dwc2: implement interrupt transfers

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.

---
 drivers/usb/host/dwc2.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/usb/host/dwc2.c +2 -3
index b1d94ccc1a69..f3fbe76acf9b 100644
@@ -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 */
Signature · 1 line
1.9.1
#2 lore raw

PATCH 2/2 usb: dwc2: implement interrupt transfers

Quoted 14 lines · Stephen Warren

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.

Quoted 5 lines

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.

Applied to u-boot-usb/topic/dwc2, thanks!

Best regards,
Marek Vasut

#3 lore raw

PATCH 1/2 usb: dwc2: correctly program hcchar for LS devices

In reply to Stephen Warren
Quoted 5 lines · Stephen Warren

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!

Applied to u-boot-usb/topic/dwc2, thanks!

Best regards,
Marek Vasut