Re: dwc3 inconsistent gadget connection state?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jul 3, 2020 at 12:57 AM Anurag Kumar Vulisha
<anuragku@xxxxxxxxxx> wrote:
> >On Thu, Jul 2, 2020 at 2:44 PM John Stultz <john.stultz@xxxxxxxxxx> wrote:
> >The one consistent difference between the working and not working case I
> >saw was the DWC3_DSTS_COREIDLE bit in the DWC3_DSTS register.
> >
> >It seems when we get to gadget_start()/pullup() if the DSTS_COREIDLE bit
> >isn't on we won't get the reset irq.
> >
> >I added a simple timeout loop to pullup() similar to the DSTS_DEVCTRLHLT
> >loop, but in the failure mode it always times out with COREIDLE not being set.
> >
> >Searching around hasn't provided any info on what COREIDLE actually means,
> >so I'm a bit in the dark.  Any clues?
> >
> DSTS.CoreIdle bit indicates that the core processed all the RXFIFO data, updated the
> Descriptors and is in idle state.
> From your previous mail I understood that the USB-C connection is configured for
> USB 2.0 only. Since you are facing issue with reset, can u please try setting the
> USB2PHYCFG. XCVRDLY bit. Enabling this bit adds an extra 2.5us delay after the
> controller sending command to configure the ULPI transceiver to HS mode and
> controller driving TxValid to 0,  for sending a HS chirp signal. Please check if this
> workaround works for you.

Hey Anurag!
  Sorry for the slow response! I finally took a bit more time to chase
this issue today, and tried your suggestion above. Unfortunately
adding the XCVRDLY bit to the USB2PHYCFG register doesn't seem to
help. I see the same behavior either way. Thanks for the suggestion
though!

I can consistently detect the problem when the COREIDLE bit isn't set
after the dwc3_ep0_out_start() call in __dwc3_gadget_start():
  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/dwc3/gadget.c?h=v5.8#n2130

When it gets stuck off, the COREIDLE bit doesn't seem to ever come
back while the cable is plugged in.
Since unplugging and replugging the cable does seem to unstick this,
and since I can consistently detect when the problem has occured, I
tweaked the code so we would return a error (and that error would be
handled in the calling dwc3_gadget_start() code.  However, the device
then tries to initialize over and over, but the COREIDLE is still
stuck off. So I tried a few times to see if I could reset via
dwc3_reset_gadget(), but that doesn't seem to actually do anything
that unsticks the core. Then I tried to mimic something similar to the
softreset code but that just ends up getting the code stuck elsewhere
(i see hard hangs and rcu warnings, but not sure where it goes awry).
So not much luck...

Is there some recommendation for how to best reset the hardware from
the gadget.c code? Or is there a better place to try to detect this
COREIDLE stuck-off state and do something about it?

thanks
-john



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux