This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

USB gadget unreliable on software reboot

Other Parts Discussed in Thread: TPS65920, TPS65950, SYSCONFIG

Hi,

On our own 3730 board (with TPS65920) as well as on BeagleBoard xM (TPS65950), configuring the MUSB controller in Linux to peripheral mode (i.e. not OTG mode) and using a built-in gadget driver, the gadget device sometimes does not appear after a software reboot.

This is using the latest Arago, but I've seen it with Angstrom 2008.1 and 2010.x too.

Configuring the MUSB controller in u-boot as a device and only booting as far as u-boot before a software reset, the device always appears. To me this suggests a MUSB driver issue in Linux (as opposed to, say, PHY initialization).

I checked with a USB analyzer what happens on the bus: when it doesn't
show up there is a reset on the bus when we reboot, but it doesn't
re-enter full speed mode. No SOFs are sent either.

I did a rudimentary check of the OTG registers in the TPS chip (over
i2c) but saw nothing out of the ordinary.

I set musb_debug = 5 in musb_core.c, but no errors are reported.


Anyone else seen this?

Thanks,

Orjan

  • Orjan,

    Which gadget driver are you using? Can you try using the gadget module as module and not builtin and see if same isssue persist?

    Regards,

    Ajay

  • Ajay,

    On the xM board I've been using the g_serial as a built-in, on our own board I'm using g_hid as a module.  The behaviour is the same in both cases.

    Just to be sure, I'm re-running the test on the xM board with g_serial as a module now.

  • As expected, the same thing happens on the xM board with g_serial as a module.

     

    FWIW, this is what /proc/driver/musb_hdrc says (on our own board, .32 kernel, g_hid as a module):

    When it works:

    Status: MHDRC, Mode=Peripheral (Power=f0, DevCtl=99)
    OTG state: b_peripheral; active
    Options: musb-dma, peripheral, debug=0 [eps=16]
    Peripheral address: 5f
    Gadget driver: g_hid

    ep0 (hw0): 1buf, csr 0000 maxp 0000
    (queue empty)

    ep1in (hw1): 1buf dma, csr 2004 maxp 00c0
    (queue empty)

     

    When it doesn't work:

    Status: MHDRC, Mode=Peripheral (Power=e0, DevCtl=80)
    OTG state: b_idle; inactive
    Options: musb-dma, peripheral, debug=0 [eps=16]
    Peripheral address: 00
    Gadget driver: g_hid

    ep0 (hw0): 1buf, csr 0000 maxp 0000
    (queue empty)

  • In non working case Vbus is not present. D[3:4] of DevCTL. It shoud be '11' but is showing to be '00' in non working case.

    As Vbus will come from the host side so please check if you are connecting the cable properly to PC?

    Ajay

  • The USB cable is permanently connected during the tests, so that shouldn't be an issue.

    On our board VBUS is permanently connected to 5V, meaning we will see VBUS even with the device disconnected.

    However, on the xM board DEVCTL=90 when it's not working and also doesn't change when plugging/unplugging the device.  I.e., the symptom that VBUS is not seen is the same.

    I'll stick to using the xM board while we're sorting this out (using  /sys/kernel/debug/musb/regdump instead of /proc/driver/musb_hdrc).

     

    Is the MUSB controller register spec publicly available?  (Those registers are not in the AM/DM37x or TPS chip TRM, and the Mentor site only lists a couple of data sheets.)

     

    Thanks for your help,

    Orjan

  • A couple of more things I've tried to get out of the idle state:

    • RESET bit in FUNC_CTRL register (TPS, set over i2c)
    • OTG_EN bit in POWER_CTRL register (also TPS and i2c)
    • SOFTRESET in OTG_SYSCONFIG register (OMAP, tried various places in the musb_hdrc driver and reloaded the module)

     

    What's weird is that USB_INT_STS.VBUSVALID = 1 (TPS) even though DEVCTL (OMAP) later claims there is no VBUS.

  • Orjan,

    Which transceiver have you enabled in kernel config? You should only enable TWL4030 and disable others like, NOP, etc.

    Thnaks,

    Ajay

  • Ajay,

    I tried disabling the others, but this made no difference.

  • Orjan Friberg said:

    What's weird is that USB_INT_STS.VBUSVALID = 1 (TPS) even though DEVCTL (OMAP) later claims there is no VBUS.

    Any comment on this difference?  I.e., it looks like the USB PHY does see the VBUS but that the MUSB controller does not.

  • Can you measure the voltage on VDD line and see if there is really 5V present?

    Ajay

  • Hm, it seems that USB_INT_STS.VBUSVALID does not change when plugging/unplugging the device cable.  I must have misread the TRM.

    I think I need a way to tell what the TPS chip thinks the VBUS pin status is, or rather: what it communicates to the MUSB controller.

     

    Dumping the TPS USB registers over I2C under Linux and comparing the working and the non-working-case, the following two registers differ:

    • USB_INT_LATCH  (register 0x14): 0x0 (working) vs. 0x17 (non-working)
      • Does this means that the MUSB controller has missed these interrupts (i.e. un-ACKed interrupts)?
      • If I reload the musb driver at this point, USB_INT_LATCH is cleared but bits 3:4 in DEVCTL are still 0 (i.e. no VBUS).
    • DEBUG (register 0x15): 0x0 (working) vs. 0x14 (non-working)
      • This register is not completely defined by the TRM (only bits 1:0), so I can't tell what this means.

     

    Thanks,

    Orjan

  • Orjan,

    You can refer the drivers/usb/otg/two4030-usb.c file where ID and VBUS events are handled for TPS (aka, TWL4030) device.

    USB_INT_LATCH is indicating that this register is not read and handled and so the value retain. I don;t see this register being read in

    drivers/usb/otg/two4030-usb.c so it seems this is done by ULPI link itself.

    I also see that in DEBUG register only BIT0 and BIT1 is defined and rest others are reserved.

    Thanks,

    Ajay

  • I measured VBUS to GND at the OTG connector when it's not working: it's at 5.13 V, so it should be ok.

  • So it seems the problem is in how TPS device is sending Vbus info to musb controller over ULPI.. Could you check in drivers/usb/otg/twl4030-usb.c?

    Ajay

  • Ajay said:

    So it seems the problem is in how TPS device is sending Vbus info to musb controller over ULPI.. Could you check in drivers/usb/otg/twl4030-usb.c?

    Exactly.  The twl4030 driver reads the STS_HW_CONDITIONS register from the TPS chip as 0xc0 (where bit 7 is STS_VBUS) both when it's working and when it's not.

     

    I don't see yet how the link status is passed from the twl4030 driver to the MUSB controller/driver.  (I.e., how it affects MUSB_DEVCTL.)

    I'll continue looking.

     

    Thanks,

    Orjan

     

  • Ajay,

    A register spec for the MUSB controller would be very useful at this point.  I don't think I will be getting any further without knowing what the contents of MUSB_DEVCTL, MUSB_LINKINFO etc mean.  Should I contact Mentor directly?

    Thanks,

    Orjan

  • Orjan,

    Please contact your local TI person and you would need to sign NDA to get the Mentor MUSB core document.

    for the time being you can also refer mentor register detail available at,

    http://www.ti.com.cn/cn/lit/ug/sprufy9/sprufy9.pdf

    section 4-46 at page 109 till section 4-89 page 138

    Regards,
    Ajay

  • Ajay,

    Great, thank you.  Since things seems to be working well when only booting as far as u-boot (with u-boot configured as an OTG device) I have looked at the differences between the two drivers and copied some constructs from u-boot to Linux.  No luck yet, though.

    Am I right in assuming that when DEVCTL is read in musb_core.c that this translates to a request to the PHY over ULPI?

    Or is there additional logic within the MUSB controller that affects whether the PHY is probed for this information?

     

    Thanks again,

    Orjan

  • Orjan,

    You can also refer the latest twl4030-usb.c file in Linus's tree below,

    http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/usb/otg/twl4030-usb.c;h=14f66c35862938adc5817c123233521c9ca1f925;hb=65112dccf8a113737684366349d7f9ec373ddc47

    PHY would be probed by controller to get Vbus information but it's not always when you read DEVCTL register.

    Ajay

  • Orjan,

    We are struggling with the same issues on our 3530 board where we run musb in host-only mode. The symptoms and register values match yours. Did you come up with any fix/workaround for this?

    Tried merging https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f65f4f40fb23b64a59adbe8629e8e7e6fea279cf into our 2.6.39 kernel, but that did not fix it. When it fails we read HW_CONDITIONS 0xc4, when it works we read HW_CONDITIONS 0x44.

  • Hi Anders,

    No, we never solved that particular problem.

  • Ok. I'm gonna try to get to the bottom of this. I hope it is ok that I post my findings here.

    When it fails PHY_DPLL_CLK in PHY_CLK_CTRL_STS is 0, so the code decides that twl4030 is not driving VBUS, something it should always do since we run in host only mode.

  • We have still not figured out this issue, and it still happens from time to time. Any TI people still around that know if anyone ever figured this problem out?