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