[U-Boot] DWC2 driver issues

Stephen Warren
2015-02-16T18:28:45Z

Marek,

Following on from my Google+ post about DWC2/RPi USB host controller
issues in U-Boot.

There are 3 issues I've identified so far:

1)

On an RPi with the DWC2 controller connected directly to a single
external USB connector (i.e model A, A+), a LS (and perhaps FS) device
pluged directly into the board doesn't work due to the small max packet
size limit.

Your patch 9b1161af8c51 "usb: dwc2: Add support for multi-packet control
xfers" in u-boot-usb.git topic/dwc2 addresses this issue for control
transfers at least. With your patch, I can now enumerate a USB kbd on a
model A+. That's a great improvement; thanks for the quick response with
a patch.

However, when I enable CONFIG_USB_KEYBOARD, I see errors when the USB
keyboard input driver initializes:

> starting USB...
> USB0: Core Release: 2.80a
> scanning bus 0 for devices... 3 USB Device(s) found
> scanning usb for storage devices... 0 Storage Device(s) found
> scanning usb for ethernet devices... 0 Ethernet Device(s) found
> dev = 0df92ac0 pipe = 0x40408380 buf = 0db4a780 size = 8 int = 10
> Failed to get keyboard state from device 413c:2010

I haven't investigated this further yet.

2)

On any RPi with a HS USB hub connected between the DWC2 controller and
an LS/FS device (e.g. model A/A+ with external hub, model B/B+ with
on-board hub), LS/FS devices don't work since the driver needs to issue
USB "split transactions". This involves communicating with the
Transaction Translator in the USB hub nearest to the LS/FS device.
Namely, performing each transaction first with DWC2_HCSPLT_SPLTENA, then
repeating (perhaps polling until we get the final response?) it with
DWC2_HCSPLT_COMPSPLT to pick up the response.

Reference:

http://www.usbmadesimple.co.uk/ums_7.htm#split_trans

http://am.renesas.com/applications/key_technology/connectivity/usb/about_usb/usb2_0/usb2_8/index.jsp

To fully cover both (1) and (2) for all types of transfer, I think we
should create a couple functions to do the low-level handling of USB
transfers:

a) Perform a large transfer by splitting it up into smaller
transactions, each as large as the max packet size. This is what your
patch does, but perhaps it'd be better as a separate function so the
logic can be shared with transfer types other than control; I assume
this size-based splitting is relevant everywhere?

b) Perform an individual transfer on the wire. This will optionally
perform split transactions when necessary. I'm sure this will be needed
by all transaction types.

Existing code that invokes USB transfers will call (a) once. (a) will
call (b) as many times as needed to break up the packet into small
chunks. (b) will either send the transaction to the HW (HS devices or
directly attached LS/FS devices), or perform the split transaction
handling (remotely attached LS/FS devices).

Does that sound like a reasonable approach?

I can start looking into getting split transactions going; I just
couldn't motivate myself last Friday night.

3)

On the RPI 2, even directly attached HS devices (i.e. the on-board USB
hub, Ethernet) don't work correctly. I haven't tracked down the cause
yet, since I got side-tracked on the two issues above, initially
thinking they might have the same/similar root-cause. However, I don't
think this issue is related, since the RPi2 on-board devices don't fall
into either of the categories above.

In theory, the HW should work the same since both the BCM2835/2836 have
the same rev of the DWC2 controller. The only difference is the CPUs and
perhaps some bus logic. I vaguely wonder about memory barrier or timing
issues, but who knows yet.