[PATCH v4 3/3] rockchip: spl: Add support for booting from UFS

Quentin Schulz quentin.schulz at cherry.de
Fri Jan 16 15:50:12 CET 2026


Hi Alexey,

On 1/16/26 3:29 PM, Alexey Charkov wrote:
> On Fri, Jan 16, 2026 at 2:50 PM Quentin Schulz <quentin.schulz at cherry.de> wrote:
>>
>> Hi Alexey,
>>
>> On 1/16/26 11:08 AM, Alexey Charkov wrote:
>>> Hi Quentin,
>>>
>>> On Wed, Jan 14, 2026 at 10:05 PM Quentin Schulz
>>> <quentin.schulz at cherry.de> wrote:
>>>>
>>>> Hi Alexey,
>>>>
>>>> On 1/8/26 6:50 PM, Alexey Charkov wrote:
[...]
>>>>> +&gpio4 {
>>>>> +     /* Used for resetting the UFS device during initialization */
>>>>> +     bootph-pre-ram;
>>>>> +     bootph-some-ram;
>>>>> +};
>>>>> +
>>>>
>>>> Is it always GPIO4 for the reset GPIO for UFS? Seems like something that
>>>> should probably be put in a board -u-boot.dtsi instead?
>>>
>>> It is in fact always GPIO4 pin D0. It's multiplexed to a
>>
>> This is probably the typical Rockchip BS :) It is the "same" for SD CD
>> or WP pins. They have a hardware-controlled mode for pin A which is
>> usually a black box for SW (nothing to do, it "works"). But nothing
>> prevents you from using another GPIO for that (just have to be careful
>> about the voltage level I guess, here it seems to be 1.2V for the
>> domain, which isn't that usual I guess.
> 
> I bet that the boot ROM might get picky there, and only work with
> GPIO4_D0. But if the UFS chip is not meant to be used as the primary
> boot device - sure, can't see why not. On the other hand, there's not
> much direct gain for board designers from using a different pin, and
> people tend to just stick with Rockchip reference schematics unless
> something different is explicitly required for their design, so my
> money is on "it will be GPIO4 for all RK3576 boards".
> 
> Extra consideration in the same stream: the pin itself is defined in
> rk3576.dtsi upstream, not in board-specific .dts files.
> 

OK, I see that rk3576.dtsi specifies the reset-gpios here. I guess it 
should be seen as a default value, like we have for pinmuxes. Also, this 
is lacking a pinmux for the GPIO, so there's no guarantee the pin will 
be muxed into the GPIO function before you control it.

[...]

>>> controlled mode would also deviate from the upstream DT binding, as it
>>> stipulates a GPIO for device resets [3].
>>>
>>
>> Not asking for this, rather wondering if we should really have this at
>> the SoC level rather than the board level. If it can be any GPIO why
>> forcing all boards to have GPIO4 bank "enabled" in SPL + U-Boot proper
>> before reloc. It isn't the first SoC to have that (also see all SoC
>> u-boot.dtsi having the UART controller from the reference design
>> "enabled"), and I don't think it's planned for us to have a product on
>> it, so... not a blocker from my side :)
> 
> I believe that the boards which don't use UFS for early boot will just
> compile it out, together with the respective GPIO code. Then the only
> downside for them is a marginally larger SPL DTB - but not on a scale
> that matters for RK3576. And those that use UFS for early boot will
> likely want it to be on the pin expected by the boot ROM, then having
> the prerequisites already defined makes life easier for them (and it's
> not much different from having e.g. FSPI0/1 and eMMC enabled by
> default even for boards that don't use them).
> 

My hunch is the BootROM may not even attempt to reset the UFS chip and 
rely on it having lost power (see different ways for the PMIC to reset 
its regulators when it's itself reset in SW). But I have nothing to 
prove this :)

>>> [1] https://github.com/torvalds/linux/blob/master/drivers/ufs/host/ufs-rockchip.c#L220-L231
>>> [2] https://github.com/rockchip-linux/u-boot/blob/next-dev/drivers/ufs/ufs-rockchip.c#L222
>>> [3] https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/ufs/rockchip%2Crk3576-ufshc.yaml#L53-L58
>>>
>>>>>     &ioc_grf {
>>>>>         bootph-all;
>>>>>     };
>>>>> @@ -176,6 +182,11 @@
>>>>>         bootph-pre-ram;
>>>>>     };
>>>>>
>>>>> +&ufshc {
>>>>> +     bootph-pre-ram;
>>>>> +     bootph-some-ram;
>>>>> +};
>>>>> +
>>>>>     &xin24m {
>>>>>         bootph-all;
>>>>>     };
>>>>> diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h
>>>>> index b15938c021d6..f9ecb6858f04 100644
>>>>> --- a/arch/arm/include/asm/arch-rockchip/bootrom.h
>>>>> +++ b/arch/arm/include/asm/arch-rockchip/bootrom.h
>>>>> @@ -51,6 +51,7 @@ enum {
>>>>>         BROM_BOOTSOURCE_SPINOR = 3,
>>>>>         BROM_BOOTSOURCE_SPINAND = 4,
>>>>>         BROM_BOOTSOURCE_SD = 5,
>>>>> +     BROM_BOOTSOURCE_UFS = 7,
>>>>
>>>> Hopefully this will be the same value for all upcoming SoCs with UFS
>>>> (and not used for something else :) ).
>>>
>>> Well it's hard to guarantee (otherwise Jonas wouldn't have had to add
>>> a translation function [4] for the IDs that changed in RK3576). Maybe
>>> at some point we'll have to switch to a lookup table per each SoC
>>> variant if these keep changing, but thankfully that point is not today
>>> :)
>>>
>>
>> See
>> https://lore.kernel.org/devicetree-spec/ebc08400-c16d-4ed0-b487-9aabe13bbf0f@pengutronix.de/
> 
> Ooooh that sounds like a discussion that can potentially stretch out
> for a long time. I'd much rather use a value that works for the only

Anything to be added to the dt spec is taking months if not year, even 
when agreed upon.

> chip where it matters now (RK3576), then solve the problem whenever it
> arises (if it does). After all, bootrom.h is not ABI, and DT is, so it
> is much easier to fix up bootrom.h without stepping on too many toes.
> 

I'm saying this will solve the problem, not that we have to rely on it 
now :)

> Furthermore, I'm not even sure that /chosen/bootsource can address the

It's not /chosen/bootsource, this has merged already in the spec and 
won't be usable for this mapping (lots to read but it's explained 
somewhere in the thread).

> issue here, because boot ROM's won't magically start passing DT
> phandles to the bootloader, so there will still be an ID->node lookup
> table somewhere in early code (with potentially per-SoC overrides).

No, that's the point of the thread I linked. The idea is to provide in 
DTS the mapping between the value in the register set by the BootROM to 
a controller/flash node somehow (via phandle or something else) so that 
we don't have to have this table in code at all. After all, this is 
hardware description (albeit based on BootROM "API" but that cannot 
change anyway, it's silicon (if it does, good luck all may the odds be 
in your favor)) so there's no reason for all bootloaders to have to 
reinvent their own sauce (see barebox doing something different than 
U-Boot there).

I read the BootROM register value, I read the DT property with the 
mapping, then I know which device it is. Bonus point, you don't need to 
keep the DT node path in sync in your table, because the mapping is in 
the same DT as what it refers to.

This is not for now (and I should probably revive the topic), just 
wanted to tell you there's another way to do that and we should probably 
aim at doing that in the mid/long term (and then all this in-code 
mapping won't need to maintained anymore, and there won't be conflicts 
between SoCs having the same value for different meanings, or differnet 
values for the same meaning).

Cheers,
Quentin


More information about the U-Boot mailing list