[PATCH] rockchip: rk3576: Properly handle USB controller takeover from BootROM
Quentin Schulz
quentin.schulz at cherry.de
Mon Apr 27 16:43:36 CEST 2026
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.
Otherwise, for sure we do not want to de-assert the signal in the rk3576
SoC C file, we don't know if the driver is even built and we should let
it do it if need be.
Cheers,
Quentin
More information about the U-Boot
mailing list