[PATCH] rockchip: rk3576: Properly handle USB controller takeover from BootROM

Quentin Schulz quentin.schulz at cherry.de
Wed May 6 16:54:56 CEST 2026


Hi Alexey, Jonas,

On 4/27/26 6:44 PM, Alexey Charkov wrote:
> Hi Quentin,
> 
> On Mon, Apr 27, 2026 at 6:43 PM Quentin Schulz <quentin.schulz at cherry.de> wrote:
>>
>> Hi Alexey,
>>
>> On 4/27/26 2:53 PM, Alexey Charkov wrote:
>>> From: Anton Burticica <mouse at ya.ru>
>>>
>>> When booting via USB download mode (Maskrom), the BootROM leaves the
>>> USB3OTG0 controller in an active state. U-Boot must properly reset
>>> the controller before reinitializing it for fastboot or other USB
>>> gadget functions.
>>>
>>> Without this change, USB gadget mode commands such as fastboot and ums
>>> fail when U-Boot is loaded via Maskrom USB download because the
>>> controller state is inconsistent.
>>>
>>> Signed-off-by: Anton Burticica <mouse at ya.ru>
>>> [Removed unrelated changes, adjusted the commit description]
>>> Signed-off-by: Alexey Charkov <alchark at flipper.net>
>>> ---
>>>    arch/arm/mach-rockchip/rk3576/rk3576.c | 18 ++++++++++++++++++
>>>    1 file changed, 18 insertions(+)
>>>
>>> diff --git a/arch/arm/mach-rockchip/rk3576/rk3576.c b/arch/arm/mach-rockchip/rk3576/rk3576.c
>>> index c17ba418ced5..84618ad5acb7 100644
>>> --- a/arch/arm/mach-rockchip/rk3576/rk3576.c
>>> +++ b/arch/arm/mach-rockchip/rk3576/rk3576.c
>>> @@ -7,6 +7,8 @@
>>>
>>>    #include <dm.h>
>>>    #include <misc.h>
>>> +#include <linux/bitops.h>
>>> +#include <linux/delay.h>
>>>    #include <asm/armv8/mmu.h>
>>>    #include <asm/arch-rockchip/bootrom.h>
>>>    #include <asm/arch-rockchip/hardware.h>
>>> @@ -39,6 +41,10 @@
>>>    #define USB_GRF_BASE                0x2601E000
>>>    #define USB3OTG0_CON1               0x0030
>>>
>>> +#define TOP_CRU_BASE         0x27200000
>>> +#define TOP_CRU_SOFTRST_CON47        0x0abc
>>> +#define SOFTRST47_ARESETN_USB3OTG0   BIT(5)
>>> +
>>>    enum {
>>>        BROM_BOOTSOURCE_FSPI0 = 3,
>>>        BROM_BOOTSOURCE_FSPI1_M1 = 6,
>>> @@ -189,6 +195,18 @@ int arch_cpu_init(void)
>>>         */
>>>        writel(0xffffff00, SYS_SGRF_BASE + SYS_SGRF_SOC_CON20);
>>>
>>> +     /* If the controller was left running by the boot ROM, reset it */
>>> +     if (read_brom_bootsource_id() == BROM_BOOTSOURCE_USB) {
>>> +             /* Assert USB3OTG0 reset */
>>> +             writel(RK_SETBITS(SOFTRST47_ARESETN_USB3OTG0),
>>> +                    TOP_CRU_BASE + TOP_CRU_SOFTRST_CON47);
>>> +             udelay(1000);
>>> +             /* De-assert USB3OTG0 reset */
>>> +             writel(RK_CLRBITS(SOFTRST47_ARESETN_USB3OTG0),
>>> +                    TOP_CRU_BASE + TOP_CRU_SOFTRST_CON47);
>>> +             udelay(1000);
>>> +     }
>>> +
>>
>> Uh... Wouldn't the issue rather be that the U-Boot driver doesn't
>> actually reset the device?
>>
>> Can you try with
>>
>> diff --git a/drivers/usb/dwc3/dwc3-generic.c
>> b/drivers/usb/dwc3/dwc3-generic.c
>> index 22b9ef0b24e..1b7d845bc75 100644
>> --- a/drivers/usb/dwc3/dwc3-generic.c
>> +++ b/drivers/usb/dwc3/dwc3-generic.c
>> @@ -604,6 +604,9 @@ static int dwc3_glue_reset_init(struct udevice *dev,
>>                   * have slower sleep clocks so we'll play it safe.
>>                   */
>>                  udelay(500);
>> +       } else if (device_is_compatible(dev, "rockchip,rk3576-dwc3")) {
>> +               reset_assert_bulk(&glue->resets);
>> +               udelay(1000);
>>          }
>>          ret = reset_deassert_bulk(&glue->resets);
>>          if (ret) {
>>
>> maybe? Hunch is that every variant of this driver actually needs to do
>> this to avoid to rely on the device being out of reset already, but the
>> delay is likely silicon-implementation-specific? The driver in the Linux
>> kernel doesn't actually assert it either before deasserting it, so who
>> knows. Adding Marek in Cc.
> 
> This snippet doesn't work unfortunately, I'm getting the following
> (the same result as without any patches):
> 

Ah yeah, the issue seems to be with the USB PHY (and likely more the 
PLL) but this does the reset during the USB controller probe, which 
maybe is too late/early/wrong place in the init?

> => ums 0 mmc 0
> UMS: LUN 0, dev mmc 0, hwpart 0, sector 0x0, count 0x3a63e00
> rockchip_udphy phy at 2b010000: cmn ana lcpll lock timeout
> rockchip_udphy phy at 2b010000: failed to init usbdp combophy
> rockchip_udphy phy at 2b010000: PHY: Failed to init phy at 2b010000: -110.
> rockchip_udphy phy at 2b010000: cmn ana lcpll lock timeout
> rockchip_udphy phy at 2b010000: failed to init usbdp combophy
> rockchip_udphy phy at 2b010000: PHY: Failed to init phy at 2b010000: -110.
> No USB device found
> Couldn't init USB controller.
> 

That looks awfully similar to what we've had in the past on RK3588, c.f. 
https://lore.kernel.org/u-boot/20250721220734.1617117-1-jonas@kwiboo.se/ 
and specifically what I wrote in:

https://lore.kernel.org/u-boot/51ed7038-1069-40ed-b572-21e179e650d8@cherry.de/

So I'm wondering if we aren't missing something similar for the PHY on 
RK3576? (even though there's a patch in the series for the RK3576 and in 
the cover letter Jonas specifies this was made while working on RK3576 
OTG). Or maybe we regressed?

Cheers,
Quentin


More information about the U-Boot mailing list