On Thu Aug 13, 2026 at 12:34 AM IST, Anders Roxell wrote:
> On 2026-08-10 15:26, Anshul Dalal wrote:
>> On Mon Aug 10, 2026 at 1:52 PM IST, Anders Roxell wrote:
>> > On 2026-08-06 18:47, Anshul Dalal wrote:
>> >> On Thu, 16 Jul 2026 15:41:30 +0200, Anders Roxell 
>> >> <[email protected]> wrote:
>> >> > [...]
>
> [...]
>
>> >
>> > And in dwc3_gadget_uboot_handle_interrupt(), same file:
>> >
>> > -          struct dwc3_event_buffer *evt;
>> > -          dwc3_thread_interrupt(0, dwc);
>> > +          struct dwc3_event_buffer *evt = dwc->ev_buf;
>> > +          dwc3_thread_interrupt(0, evt);
>> 
>> Thanks for the pointers Anders but I encounter a similar failure even
>> with the diff you suggested. I enabled some logging for the SPL by
>> defining the DEBUG macro in the following files (dfu.c spl.c spl_ram.c
>> dwc3-am62.c composite.c g_dnl.c).
>
> Hi Anshul,
>
> Good news. I found two more bugs on top of the two I already sent you
> (the event buffer and allow_connect). With all four the device
> enumerates.
>
>> 
>> Failure logs:
>> 
>>      U-Boot SPL 2026.07-00860-g5a9b7a715be2 (Aug 10 2026 - 15:06:27 +0530)
>>      SYSFW ABI: 4.0 (firmware rev 0x000c '12.1.0--v12.01.00 (Clever Cat)')
>>      Set clock rates for '/a53@0', CPU: 1250MHz at Speed Grade 'V'
>>      SPL initial stack usage: 17104 bytes
>>      SPL malloc() before relocation used 0x64d0 bytes (25 KB)
>>      >>SPL: board_init_r()
>>      spl_init
>>      Trying to boot from DFU
>>      g_dnl_register: g_dnl_driver.name = usb_dnl_dfu
>>      g_dnl_bind: gadget: 0x81c44a98 cdev: 0x81c66bc0
>>      usb_add_config: adding config #1 'usb_dnload'/81c67cc0
>>      g_dnl_do_config: configuration: 0x81c67cc0 composite dev: 0x81c66bc0
>>      adding 'dfu'/81c67d34 to config 'usb_dnload'/81c67cc0
>>      cfg 1/81c67cc0 speeds: high full
>>      usb_add_config: interface 0 = dfu/81c67d34
>>      g_dnl_bind: calling usb_gadget_connect for controller 'dwc3-gadget'
>>      usb_dnl_dfu: ready
>> 
>> <CTRL-C> from user
>> 
>>      unbind function 'dfu'/81c67d34
>>      g_dnl_unbind: calling usb_gadget_disconnect for controller 'dwc3-gadget'
>>      Legacy image
>>      u_boot_pos = ffffffff
>>      Raw boot image support not enabled, proceeding to other boot methods
>>      Error: -22
>>      SPL: Unsupported Boot Device!
>>      SPL: failed to boot from all boot devices
>>      ### ERROR ### Please RESET the board ###
>> 
>> Succes logs (same debug symbols ontop of main branch):
>> 
>>      U-Boot SPL 2026.10-rc1-00209-g0bdd5e5daf95 (Aug 10 2026 - 14:58:28 
>> +0530)
>>      SYSFW ABI: 4.0 (firmware rev 0x000c '12.1.0--v12.01.00 (Clever Cat)')
>>      Set clock rates for '/a53@0', CPU: 1250MHz at Speed Grade 'V'
>>      SPL initial stack usage: 17104 bytes
>>      SPL malloc() before relocation used 0x64d0 bytes (25 KB)
>>      >>SPL: board_init_r()
>>      spl_init
>>      Trying to boot from DFU
>>      g_dnl_register: g_dnl_driver.name = usb_dnl_dfu
>>      g_dnl_bind: gadget: 0x81c44aa4 cdev: 0x81c4af40
>>      usb_add_config: adding config #1 'usb_dnload'/81c4c040
>>      g_dnl_do_config: configuration: 0x81c4c040 composite dev: 0x81c4af40
>>      adding 'dfu'/81c4c0b4 to config 'usb_dnload'/81c4c040
>>      cfg 1/81c4c040 speeds: high full
>>      usb_add_config: interface 0 = dfu/81c4c0b4
>>      g_dnl_bind: calling usb_gadget_connect for controller 'dwc3-gadget'
>>      usb_dnl_dfu: ready
>>      composite_suspend: suspend
>>      set_config: high speed config #1: usb_dnload
>>      non-core control reqa1.03 v0000 i0000 l6
>>      non-core control req21.01 v0000 i0000 l4096
>> ...(repeated)
>>      #non-core control reqa1.03 v0000 i0000 l6
>>      non-core control reqa1.03 v0000 i0000 l6
>>      DOWNLOAD ... OK
>>      Ctrl+C to exit ...
>> 
>> I'm not that familiar with the DW3 driver, let me know if you need me to
>> test with any further changes.
>> 
>> >
>> > evt was used there without being set as well.
>> >
>> > All of this is in v6 that I plan to send out. I have no AM62p and it is
>> > only compile tested, so please try it on your board so we know if it
>> > solves your issue before I send out v6.
>> 
>> I was able to reproduce the issue on beagleplay since it uses the same
>> DWC3. You can try it locally if you have that board with you by
>> resetting to DFU mode from U-Boot prompt:
>> 
>> => mw.w 43000030 53; res
>
> I could not use the mw.w 43000030 53; res trick on the BeagleBoard-X15
> that I found. But I can run DFU directly, it is the same DWC3 gadget
> path you hit.
>
> How I tested on x15:
>
>   env set dfu_alt_info "${dfu_alt_info_ram}"
>   dfu 0 ram 0
>
> On the host dfu-util finds it:
>
>   Found DFU: [0451:d022] ... name="kernel"/"fdt"/"ramdisk"
>
> The two new bugs:
>
> 3. udc-core never sets dwc->async_callbacks. So the gadget setup() is
>    never called and every GET_DESCRIPTOR returns -EINVAL.
>
> 4. ep0. The trb and the ep0 buffers are normal cached memory. In u-boot
>    dma_alloc_coherent is not coherent, so nothing keeps them in sync with
>    the controller dma. The resync dropped the manual flush and invalidate,
>    so the controller reads a stale trb and stale buffers.
>
> The patch below is only 3 and 4. Keep the first two you already have,
> this goes on top. It is against v5. I built it and tested it on x15,
> it works.
>
> Can you test it on BeaglePlay with your reset trick? These fixes will
> be part of the coming usb_dwc3_sync_v6 branch.

Great news! I applied the diff you suggested and DFU boot seems to be
working now. I have hosted my working tree here[1] with all 4 bug fixes
applied.

Let me know if you would want anything else to be tested before a v6.

[1]: https://github.com/ArchUsr64/u-boot/tree/ti_k3_usb_dwc3_sync_working

Regards,
Anshul

>
> Cheers,
> Anders
>
>
> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> index 0a4f69cbc28a..2ba05fc3f573 100644
> --- a/drivers/usb/dwc3/ep0.c
> +++ b/drivers/usb/dwc3/ep0.c
> @@ -54,6 +54,9 @@ static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep,
>       else
>               trb->ctrl |= (DWC3_TRB_CTRL_IOC
>                               | DWC3_TRB_CTRL_LST);
> +
> +     dwc3_flush_cache((uintptr_t)buf_dma, len);
> +     dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
>  }
>  
>  static int dwc3_ep0_start_trans(struct dwc3_ep *dep)
> @@ -811,6 +814,8 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
>       int ret = -EINVAL;
>       u32 len;
>  
> +     dwc3_invalidate_cache((uintptr_t)ctrl, sizeof(*ctrl));
> +
>       if (!dwc->gadget_driver || !dwc->softconnect || !dwc->connected)
>               goto out;
>  
> @@ -856,6 +861,8 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
>       dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
>       trb = dwc->ep0_trb;
>  
> +     dwc3_invalidate_cache((uintptr_t)trb, sizeof(*trb) * 2);
> +
>       r = next_request(&ep0->pending_list);
>       if (!r)
>               return;
> @@ -873,6 +880,9 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
>  
>       length = trb->size & DWC3_TRB_SIZE_MASK;
>       transferred = ur->length - length;
> +
> +     if (ur->buf && !r->direction)
> +             dwc3_invalidate_cache((uintptr_t)ur->dma, ur->length);
>       ur->actual += transferred;
>  
>       if ((IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) &&
> diff --git a/drivers/usb/gadget/udc/udc-core.c 
> b/drivers/usb/gadget/udc/udc-core.c
> index 6355931f9ff1..f03ff937dfde 100644
> --- a/drivers/usb/gadget/udc/udc-core.c
> +++ b/drivers/usb/gadget/udc/udc-core.c
> @@ -941,6 +941,8 @@ static inline void usb_gadget_udc_set_speed(struct 
> usb_udc *udc,
>               gadget->ops->udc_set_speed(gadget, s);
>  }
>  
> +static inline void usb_gadget_enable_async_callbacks(struct usb_udc *udc);
> +
>  static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver 
> *driver)
>  {
>          int ret;
> @@ -960,6 +962,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct 
> usb_gadget_driver *dri
>                  driver->unbind(udc->gadget);
>                  goto err1;
>          }
> +        usb_gadget_enable_async_callbacks(udc);
>          udc->allow_connect = true;
>          usb_gadget_connect(udc->gadget);
>  
> @@ -1156,6 +1159,7 @@ static void usb_gadget_remove_driver(struct usb_udc 
> *udc)
>                       udc->driver->function);
>  
>       udc->allow_connect = false;
> +     usb_gadget_disable_async_callbacks(udc);
>       usb_gadget_disconnect(udc->gadget);
>       udc->driver->disconnect(udc->gadget);
>       udc->driver->unbind(udc->gadget);

Reply via email to