[U-Boot] Fastboot and MUSB driver on OMAP3

I've been looking at getting fastboot working on my LG Optimus Black (P970), codename sniper, port. I found out that the BeagleBoard code is using that too, so I copied the required config options:
#define CONFIG_MUSB_GADGET #define CONFIG_USB_MUSB_OMAP2PLUS #define CONFIG_MUSB_PIO_ONLY #define CONFIG_USB_GADGET_DUALSPEED #define CONFIG_TWL4030_USB 1 #define CONFIG_USB_ETHER #define CONFIG_USB_ETHER_RNDIS #define CONFIG_USB_GADGET #define CONFIG_USB_GADGET_VBUS_DRAW 0 #define CONFIG_USBDOWNLOAD_GADGET
#define CONFIG_G_DNL_VENDOR_NUM 0x0451 #define CONFIG_G_DNL_PRODUCT_NUM 0xd022 #define CONFIG_G_DNL_MANUFACTURER "TI" #define CONFIG_CMD_FASTBOOT #define CONFIG_ANDROID_BOOT_IMAGE #define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR #define CONFIG_USB_FASTBOOT_BUF_SIZE 0x07000000
And removed the ones that relate to the legacy code:
-#define CONFIG_MUSB_UDC 1 -#define CONFIG_USB_OMAP3 1 -#define CONFIG_TWL4030_USB 1 -#define CONFIG_USB_DEVICE 1 -#define CONFIG_USB_TTY 1
I also added the relevant "platform" data: http://git.code.paulk.fr/gitweb/?p=u-boot-sniper.git;a=blob;f=board/lge/snip...
The current state of the port is available for reference at: http://git.code.paulk.fr/gitweb/?p=u-boot-sniper.git;a=shortlog;h=refs/heads... It is not yet ready to be pushed upstream.
With all this, I run the fastboot command and UART shows: musb-hdrc: peripheral reset irq lost!
On the host side, I get the following messages from dmesg:
[11281.565099] usb 3-1: new high-speed USB device number 39 using xhci_hcd [11283.178280] usb 3-1: Device not responding to set address. [11283.378663] usb 3-1: Device not responding to set address. [11283.579739] usb 3-1: device not accepting address 39, error -71 [11283.939123] usb 3-1: new high-speed USB device number 41 using xhci_hcd [11283.939313] usb 3-1: Device not responding to set address. [11284.140316] usb 3-1: Device not responding to set address. [11284.341381] usb 3-1: device not accepting address 41, error -71
and so on until it fails: [11286.007890] hub 3-0:1.0: unable to enumerate USB device on port 1
So it fails early. Is there something more I need to do in order to get the new musb driver to work properly on my device?

On the host side, I get the following messages from dmesg:
[11281.565099] usb 3-1: new high-speed USB device number 39 using xhci_hcd [11283.178280] usb 3-1: Device not responding to set address. [11283.378663] usb 3-1: Device not responding to set address. [11283.579739] usb 3-1: device not accepting address 39, error -71 [11283.939123] usb 3-1: new high-speed USB device number 41 using xhci_hcd [11283.939313] usb 3-1: Device not responding to set address. [11284.140316] usb 3-1: Device not responding to set address. [11284.341381] usb 3-1: device not accepting address 41, error -71
I investigated a bit further and added a few debug prints to U-Boot. If I understand correctly, IRQs are not actually being used and the fastboot command is polling on usb_gadget_handle_interrupts.
The status so far is that it still doesn't work on the host. As far as I can see, it doesn't get as far as enumerating the endpoints (see the log below).
The SET_ADDRESS request is received just fine, it then sets musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; but no IRQ arrives to trigger another call to musb_g_ep0_irq. Eventually, the host just sends back another SET_REQUEST. Looking at dmesg on the host (Device not responding to set address), I guess that the device should send something back and it apparently doesn't.
Do you have any clue?
Here is the relevant U-Boot log:
U-Boot SPL 2015.01-rc2-gfc9200f-dirty (Dec 15 2014 - 17:59:56) reading u-boot.img reading u-boot.img
U-Boot 2015.01-rc2-gfc9200f-dirty (Dec 15 2014 - 17:59:56)
OMAP36XX/37XX-GP ES1.2, CPU-OPP2, L3-200MHz, Max CPU Clock 1 Ghz Sniper + LPDDR/MMC I2C: ready DRAM: 512 MiB MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 Using default environment
In: serial Out: serial Err: serial musb_register musb_init_controller omap2430_musb_init HS USB OTG: revision 0x40, sysconfig 0x1008, sysstatus 0x1, intrfsel 0x1, simenable 0x0 omap2430_musb_disable musb_gadget_setup USB Peripheral mode controller at 480ab000 using PIO, IRQ 0 Hit any key to stop autoboot: 0 usb_gadget_register_driver musb_gadget_start musb_start omap2430_musb_enable fastboot_add adding 'f_fastboot'/9fe55240 to config 'usb_dnload'/9fe55180 fastboot_bind IN fastboot_bind OUT generic_interrupt: 45 1 0 ** IRQ peripheral usb002d tx0001 rx0000 <== Power=f0, DevCtl=98, int_usb=0x2d csr 0001, count 8, myaddr 0, ep0stage idle musb-hdrc: peripheral reset irq lost! musb_g_ep0_irq: power: 0xf0 speed: 0x3 new ep0 state is 6 service_zero_data_request() service_zero_data_request: SET_ADDRESS new ep0 state is 4 generic_interrupt: 1 0 0 ** IRQ peripheral usb0001 tx0000 rx0000 <== Power=e0, DevCtl=99, int_usb=0x1 generic_interrupt: 4 0 0 ** IRQ peripheral usb0004 tx0000 rx0000 <== Power=f0, DevCtl=99, int_usb=0x4 generic_interrupt: 8 0 0

The SET_ADDRESS request is received just fine, it then sets musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; but no IRQ arrives to trigger another call to musb_g_ep0_irq. Eventually, the host just sends back another SET_REQUEST. Looking at dmesg on the host (Device not responding to set address), I guess that the device should send something back and it apparently doesn't.
Do you have any clue?
To get a better understanding of what is going on, I added debug prints to the Linux kernel (since that musb-new driver is apparently a direct copy of the Linux code). In Linux, everything is working nicely (for instance with ADB on Android). The relevant part is this:
[ 8.616943] adb_open [ 8.674926] generic_interrupt: 1 0 0 [ 8.678680] ** IRQ peripheral usb0001 tx0000 rx0000 [ 8.683807] [ED_MC]1-2.<INT>USB_SUSPEND [ 8.777709] generic_interrupt: 4 0 0 [ 8.781433] ** IRQ peripheral usb0004 tx0000 rx0000 [ 8.893463] omapdss DSI error: DSI CIO error, cio irqstatus 400 [ 8.893493] DSI CIO IRQ 0x400: ERRCONTROL1 [ 8.929138] generic_interrupt: 8 1 0 [ 8.932922] ** IRQ peripheral usb0008 tx0001 rx0000 [ 8.938049] musb_g_ep0_irq: Current EP0 state is 0x1 [ 8.943267] service_zero_data_request: SET_ADDRESS [ 8.948303] new ep0 state is 4 [ 8.951507] Writing ACKPEND 0x48 [ 8.954925] generic_interrupt: 8 1 0 [ 8.958679] ** IRQ peripheral usb0008 tx0001 rx0000 [ 8.963806] musb_g_ep0_irq: Current EP0 state is 0x4 [ 8.969024] musb_g_ep0_irq: Actually setting address now! [ 8.974670] musb_g_ep0_irq: MUSB_EP0_STAGE_STATUSOUT now [ 8.983337] omapdss DSI error: DSI CIO error, cio irqstatus 100400 [ 8.983367] DSI CIO IRQ 0x100400: ERRCONTROL1 ERRCONTENTIONLP0_1 [ 9.077239] generic_interrupt: 8 1 0 [ 9.080993] ** IRQ peripheral usb0008 tx0001 rx0000 [ 9.086120] musb_g_ep0_irq: Current EP0 state is 0x0 [ 9.091400] generic_interrupt: 8 1 0
To put in perspective with my current U-Boot log:
musb_register musb_init_controller omap2430_musb_init HS USB OTG: revision 0x40, sysconfig 0x1008, sysstatus 0x1, intrfsel 0x1, simenable 0x0 omap2430_musb_disable musb_gadget_setup USB Peripheral mode controller at 480ab000 using PIO, IRQ 0 Hit any key to stop autoboot: 0 usb_gadget_register_driver musb_gadget_start musb_start omap2430_musb_enable fastboot_add adding 'f_fastboot'/9fe50480 to config 'usb_dnload'/9fe503c0 fastboot_bind IN fastboot_bind OUT generic_interrupt: 45 1 0 ** IRQ peripheral usb002d tx0001 rx0000 <== Power=f0, DevCtl=98, int_usb=0x2d csr 0001, count 8, myaddr 0, ep0stage idle musb-hdrc: peripheral reset irq lost! musb_g_ep0_irq: power: 0xf0 speed: 0x3 new ep0 state is 6 service_zero_data_request() service_zero_data_request: SET_ADDRESS new ep0 state is 4 Writing ACKPEND 0x48 generic_interrupt: 1 0 0 ** IRQ peripheral usb0001 tx0000 rx0000 <== Power=e0, DevCtl=99, int_usb=0x1 generic_interrupt: 4 0 0 ** IRQ peripheral usb0004 tx0000 rx0000 <== Power=f0, DevCtl=99, int_usb=0x4 generic_interrupt: 8 0 0 ** IRQ peripheral usb0008 tx0000 rx0000 <== Power=f0, DevCtl=99, int_usb=0x8 generic_interrupt: 8 0 0 ** IRQ peripheral usb0008 tx0000 rx0000 <== Power=f0, DevCtl=99, int_usb=0x8
The difference between both is apparently that the first IRQ I get in U-Boot has, in addition to TX, an USB IRQ with value 0x2D. 0x2D is MUSB_INTR_DISCONNECT | MUSB_INTR_SUSPEND | MUSB_INTR_RESET | MUSB_INTR_BABBLE
I'm a bit worried about MUSB_INTR_DISCONNECT, which normally indicates that the device was disconnected. In any case, I'm not getting the second TX message which is supposed to let the actual address set take place.
I would appreciate a some highlights from people using this on the BeagleBoard, where it is apparently supposed to work. My current code (including debug prints) is at: http://git.code.paulk.fr/gitweb/?p=u-boot-sniper.git;a=shortlog;h=refs/heads...
Thanks, have a nice holiday season!

The SET_ADDRESS request is received just fine, it then sets musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; but no IRQ arrives to trigger another call to musb_g_ep0_irq. Eventually, the host just sends back another SET_REQUEST. Looking at dmesg on the host (Device not responding to set address), I guess that the device should send something back and it apparently doesn't.
Over the past few days, I have figured part of the problem (I am still far from being done). I was loading the U-Boot SPL via USB, which implies that the bootrom sets up the USB link first: that was the key to that first issue. The controller was simply not being reset properly: MUSB_POWER_SOFTCONN was still present in the MUSB_POWER register, so I cleared it early and cleared the interrupt registers as well. Then, the musb-new driver could work properly.
This is all because the bootrom doesn't cleanly deinit musb (the host isn't notified of the disconnection when the bootrom starts executing the loaded software). I'll submit a patch in due time so that the musb-new driver works with bootrom USB peripherial load.
While working on this, I flashed the U-Boot SPL to the internal memory. When the device boots from it, with no USB cable attached, neither the legacy musb driver nor musb-new work properly. I only get the first IRQ and nothing more. However, as soon as I boot with the bootrom initializing USB, it works in U-Boot. So there must be an extra step in the initialization process that the bootrom is taking and U-Boot is missing.
I have looked at muxing and clocks, everything seems to be fine, so I'm starting to run out of ideas.
Any suggestion or help appreciated!

The SET_ADDRESS request is received just fine, it then sets musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; but no IRQ arrives to trigger another call to musb_g_ep0_irq. Eventually, the host just sends back another SET_REQUEST. Looking at dmesg on the host (Device not responding to set address), I guess that the device should send something back and it apparently doesn't.
Over the past few days, I have figured part of the problem (I am still far from being done). I was loading the U-Boot SPL via USB, which implies that the bootrom sets up the USB link first: that was the key to that first issue. The controller was simply not being reset properly: MUSB_POWER_SOFTCONN was still present in the MUSB_POWER register, so I cleared it early and cleared the interrupt registers as well. Then, the musb-new driver could work properly.
Actually, issuing a software reset works just as well and seems cleaner to me. I will submit a patch about this. Apparently, this behaviour can be observed with xhci_hcd on the host (USB3), but not with ehci-pci (USB2), where it works fine.
While working on this, I flashed the U-Boot SPL to the internal memory. When the device boots from it, with no USB cable attached, neither the legacy musb driver nor musb-new work properly. I only get the first IRQ and nothing more. However, as soon as I boot with the bootrom initializing USB, it works in U-Boot. So there must be an extra step in the initialization process that the bootrom is taking and U-Boot is missing.
I have looked at muxing and clocks, everything seems to be fine, so I'm starting to run out of ideas.
It turns out this was the MAX14526 MUIC not muxing the USB connector to the TWL. I suspect that it only does it automatically when VBUS is there during its initialization (which is the case when booting from USB, but not when booting with no USB cable attached). Of course, I will be submitting code for this along with the rest of the patches for LG Optimus Black (P970) codename sniper support when things are ready.
participants (1)
-
Paul Kocialkowski