Devicetree
 help / color / mirror / Atom feed
* Re: SoC-specific device tree aliases?
       [not found]                     ` <CAL_JsqLFjF7F1eCxL8CzyitGogB0Ee7iHLGf79RHbwTpo6za7g@mail.gmail.com>
@ 2026-05-06 11:25                       ` Quentin Schulz
  0 siblings, 0 replies; only message in thread
From: Quentin Schulz @ 2026-05-06 11:25 UTC (permalink / raw)
  To: Rob Herring, Sascha Hauer
  Cc: Ahmad Fatoum, Krzysztof Kozlowski, Matthias Schiffer,
	devicetree@vger.kernel.org, Conor Dooley, devicetree-spec,
	Marc Kleine-Budde, kernel@pengutronix.de, Krzysztof Kozlowski

Hi all,

Thanks Ahmad for starting this discussion!

Ahmad has provided the Barebox side of things, but we need something 
similar in U-Boot for Rockchip SoCs. (Probably other SoCs as well but 
I'm only involved with the Rockchip side of things in U-Boot).

Rockchip SoCs BootROM seems to be writing this info into SRAM at a 
specific, undocumented, offset, whose values are also undocumented as 
far as I know. It seems that for the RK35xx series, the BootROM also 
reports which pinmuxing was used for a specific controller (in Rockchip 
speak those are _MX suffixed, with X being the mux number). We sometimes 
discover new register values a few months or years down the line when 
new HW configuration land (e.g. how we discovered that in the RK35xx 
series of SoCs, the pinmux of the controller changes the register value).

In U-Boot we do the very ugly thing of mapping this value to a hardcoded 
Device Tree path to the controller or chip (e.g. for SPI flashes). I 
know that this "mapping" got broken a few times already, see 
42f67fb51cb4 ("rockchip: rk3568: Fix boot device detection"), 
07b5d348a6b0 ("rockchip: rk3399: boot_devices: fix eMMC node name"), 
5859bb286306 ("rockchip: fix boot_devices constants"), e8a663cc60a3 
("rk3399: boot_devices fix spinor node name"), 97de3935aabf ("rockchip: 
Fix spl mmc boot device ofpath"), 2d86ab50cee3 ("rockchip: adding the 
missing "/" in entries of boot_devices"). So clearly, we are doing 
something wrong :) (yes, a part of it was because U-Boot used to use 
completely different Device Trees and then things got renamed or finally 
synced with DTSes from the Linux kernel (which often have different node 
names or paths)). The implementation today of having an array with the 
DT path at a given index of the array based on the value in the register 
has already stopped scaling with new register values being well above a 
reasonable number (0x81 when booting from RAM via upload to it from USB 
gadget in BootROM), so we resolved ourselves to add an indirection which 
is not making things less confusing. I would like to have something more 
robust (and smaller in size) but it doesn't make sense to work on 
something U-Boot-specific if we can have something different bootloaders 
can share via the DTB for example.

The xPL stage checks the value in SRAM in board_spl_was_booted_from() 
with read_brom_bootsource_id() and use that as the offset in the 
boot_devices array that is stored in an SoC-specific C file. This is 
then used to infer the "same-as-spl" entry in u-boot,spl-boot-order 
which is used to specify to U-Boot xPL which storage medium to try first 
to load the next stage (U-Boot FIT with TF-A, OP-TEE OS and U-Boot 
proper; u-boot.itb essentially). We also insert that path into 
/chosen/bootsource for later consumption.

See read_brom_bootsource_id() and boot_devices[BROM_LAST_BOOTSOURCE + 1] 
in arch/arm/mach-rockchip/rk3576/rk3576.c, board_spl_was_booted_from() 
in arch/arm/mach-rockchip/spl.c and board_boot_order() in 
arch/arm/mach-rockchip/spl-boot-order.c for related source code.

TL;DR: U-Boot uses hardcoded mapping between BootROM register values and 
Device Tree node paths to populate /chosen/bootsource (and also decide 
which storage medium to try next for loading U-Boot FIT). This is a pain 
point and we'd like to have this mapping stored in the DT so we don't 
have to worry about keeping them in sync.

On 12/4/25 2:44 PM, Rob Herring wrote:
> On Thu, Dec 4, 2025 at 1:59 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>>
>> On Wed, Dec 03, 2025 at 11:51:28AM -0600, Rob Herring wrote:
>>> On Wed, Dec 3, 2025 at 5:37 AM Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
>>>>
>>>> Hi,
>>>>
>>>> On 12/3/25 12:08 PM, Krzysztof Kozlowski wrote:
>>>>> On 03/12/2025 11:36, Matthias Schiffer wrote:
>>>>>> On Wed, 2025-12-03 at 11:25 +0100, Krzysztof Kozlowski wrote:
>>>>>>> On 03/12/2025 11:16, Ahmad Fatoum wrote:
>>>>>>>> Hello Krzysztof,
>>>>>>>>
>>>>>>>> On 11/17/25 5:29 PM, Krzysztof Kozlowski wrote:
>>>>>>>>> On 17/11/2025 17:06, Rob Herring wrote:
>>>>>>>>>>> So you want it to be an ABI for barebox, sure, just make it a binding.
>>>>>>>>>>
>>>>>>>>>> What do you have in mind? Other than standard names for the aliases,
>>>>>>>>>> what can we check here? That a specific alias points to a specific
>>>>>>>>>> path? That would be a bit too much IMO. That would be equivalent to
>>>>>>>>>> specifying possible values in 'reg' for all devices.
>>>>>>>>>
>>>>>>>>> Binding with pattern or list of needed alias names, referenced by given
>>>>>>>>> soc-platform top-level schema.
>>>>>>>>>
>>>>>>>>> One of the points is to make it explicit and obvious (e.g. to Arnd or to
>>>>>>>>> me if I forget, because I follow the same logic of aliases per board)
>>>>>>>>> that these aliases are used outside of kernel.
>>>>>>>>>
>>>>>>>>> Just because ufs/mmc/spi can be used that way, does not mean we should
>>>>>>>>> accept any possible alias into soc.dtsi.
>>>>>>>>
>>>>>>>> I can't see how this could work. A number of boards renumber MMC devices
>>>>>>>> in a different manner than the SoC reference manual:
>>>>>>>>
>>>>>>>> - Changing the alias numbering is an ABI break, because Linux derives
>>>>>>>> its /dev/mmcblkX numbering from it
>>>>>>>
>>>>>>> First, why the alias would change? Isn't the board following the SoC
>>>>>>> numbering in 99.9% cases?
>>>>>>
>>>>>> At least for our TQ-Systems boards, we have a convention based on usage (mmc0:
>>>>>> eMMC, mmc1: SD card; serial0 is often the console) rather than following the SoC
>>>>>> numbering; that is, we're using the aliases as a form of hardware abstraction
>>>>>> rather than hardware description.
>>>>>
>>>>> Huh, does it even match numbering on the schematics / board / user-guides?
>>>>>
>>>>> I would prefer not to create bindings purely because some existing DTS
>>>>> code is not matching our expectations. However there could be a case
>>>>> where board numbering is different than soc number and we want to keep
>>>>> aliases configured for board.
>>>>>
>>>>> Basically what you propose here is the discouraged instance ID disguised
>>>>> under one more 'alias' which is not really alias. It's just an instance
>>>>> ID. There is no other use of soc-aliases beside instance ID.
>>>>>
>>>>> I see the problem you want to solve, I agree it is worth solving and I
>>>>> agree that DT is the place for this mapping between register value and
>>>>> device node. However solution of discouraged instance ID is just...
>>>>> well, discouraged, so not optimal. I don't have particular advice expect
>>>>> a dedicated property for each device in such case.
>>>>
>>>> How do we move forward here? I don't think we can change the nature of
>>>> /aliases being board-specific now without breaking users.
>>>>
>>>> Does this make the addition of /soc-aliases (or /soc/aliases?) more
>>>> palatable?
>>>
>>> No.
>>>
>>> Thinking about this some more, I'm not sure that something aliases
>>> based is even the right approach. Let's back up to the original
>>> problem instead of talking about a problem concerning a possible
>>> solution.
>>>
>>> You have a platform specific register with values (or from 1 or
>>> multiple fields) that you need to map to devices in DT. That's it.
>>> That could be solved like this:
>>>
>>> bootsource-map =
>>>    <0x2 &mmc0>,
>>>    <0x3 &mmc1>,
>>>    <0x10 &spi0>,
>>>    ...;
>>>
>>> Simple. The first value is platform specific. Maybe it is several
>>> fields (e.g. device type, instance) merged together. Doesn't matter.
>>
>> That's an interesting approach and I like it.
>>
>> I am not sure though how the platform specific value could be composed.
> 
> It's platform specific, so however it wants and not my problem.
> 

We can always have a constant for that so that it's meaning is clearer 
to the human eye. After all, we also have GPIO_ACTIVE_HIGH flag or 
RK_PXY constants for pinctrl pin numbers. I'm thinking the first value 
in the array doesn't have to be related to the value in the register(s) 
as that may actually be quite complex to represent in a stable manner in DT?

This is honestly the best suggested approach so far to me. If we really 
want to, we can make it a bitmap as well, such that multiple bootsources 
can map to the same device. I'm thinking Rockchip RK35xx series having 
different values for the same controller with different pinmuxes (see 
the BROM_BOOTSOURCE_FSPI_* enum in 
arch/arm/mach-rockchip/rk3588/rk3588.c), so that could also be handled 
by the bootloader with its own mapping.

>> The easiest way would be if it maps to some register values. This works
>> well when there's a bitfield with only a few bits which specifies the
>> bootsource, but not so when there are many bits. On TI AM62x for example
>> we have 4 bits specifying the primary bootsource, 3 bits specifying the
>> backup bootsource and 1 bit specifying if we are booting from the
>> primary or from the backup bootsource. This means we have an array with
>> potentially 256 entries with many holes and many different values
>> pointing to the same bootsource. We could reduce the number of array
>> entries by specifying a mask for each value. I am worried also that the
>> initial contributor might for example forget about the backup bootsource
>> and only upstreams primary bootsource, so we would have to modify
>> existing values for the primary bootsource when adding the backup
>> bootsource.
> 
> It's a map, not an array so there should be no holes. The entry index
> is not significant. In this example, the platform just defines the
> cell as:
> 
> <primary_or_sec:16><sec_source:15:8><primary_source:7:0>
> 
> You could fit it all in 8-bits, but I spaced it out in case the next
> SoC needs another bit.
> 
> A mask value would be okay until you have 2 different registers and
> then you need a variable number of cells. And then I could imagine
> someone will want to define the register address for each cell in the
> name of a 'generic binding'. That's not what I want to see.
> 

Yeah, I'm not convinced this is future-proof either.

>> How about only adding the phandles to bootsource-map, like
>>
>> bootsource-map = <&mmc0>, <&mmc2>, <&spi0>, ...;
>>
>> New entries must then only be added at the end, existing entries must
>> never be changed.
> 
> That would work too. Then you just have the index to register value
> lookup in code. Doesn't matter to me too much. The only downside I see
> is having to enforce that people don't try to insert entries in the
> middle.
> 

I... don't like this.

I've this nagging feeling we'll have some DTSI later removing entries in 
that property. Think a new binning variant of an SoC which removes some 
storage medium controller. They are technically mostly identical except 
I cannot have a phandle to that medium controller from the highest 
quality binning because it's not available in the lowest quality 
binning, therefore we need to remove it from bootsource-map. N-th index 
in the array means a different thing depending on the binning. Yes, 
technically it's correct, but now I need to have code that automatically 
detects the binning at runtime to then map the index to this 
bootsource-map property differently. Or have a different bootloader 
binary/DTB for that binning, which we don't necessarily need. And if we 
somehow discover this later because it was not told by the vendor ("oh 
yeah sometimes it can be there, sometimes not, so we only guarantee it's 
not but maybe you'll have it" kind of debacle we've had with the 
RK3582/RK3583 for example), then this may change.

I'm also not fond of SoC-specific aliases, because they'll end up being 
confusing to the user I think: "why are there two mmc0 aliases and they 
don't point at the same node??". I somehow am also not convinced that 
the BootROM value will necessarily be related to the controller instance 
number (I wouldn't be surprised if register value 2 means mmc controller 
0 and register value 0 means mmc controller 1, hardware people are full 
of surprises), so the order of appearance in bootsource-map may not even 
be mmc0, mmc1, mmc2. Or if it is, then we need a mapping in the 
bootloader for "mmc0 in bootsource-map is actually represented by 
register value X" and then enforcing the order doesn't make much sense 
except avoiding to break the ABI.

I couldn't think of anything new to suggest.

I'm reviving this thread because it's been 6 months since the last 
answer and I'm not sure we've agreed on how to go forward. U-Boot and 
Barebox both need this, they both implement it their own way that they 
don't like.

1) I hope we've managed to convey why this is needed and that DT 
maintainers agree with adding *something* to the DT for that purpose.

2) Format of the property needs to be defined. I'm leaning towards
bootsource-map =
   <0x2 &mmc0>,
   <0x3 &mmc1>,
   <0x10 &spi0>;

(possibly with a bitmap for matching multiple BootROM values to a 
controller within one entry in the array instead of duplicating it; 
possibly with constants instead of obscure hardcoded values like above 
(though that isn't relevant for the Device Tree spec)).

3) Location of the property. Is /chosen agreed on? A new child node in 
/options? A new child node at root node?

Anything else I'm missing that needs to be tackled before one can send 
some patches to the spec and/or Linux kernel DT bindings?

Cheers,
Quentin

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-06 11:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <aRs-DaayhtQTtFXj@pengutronix.de>
     [not found] ` <9e14fb8e-af84-4072-b0ac-9ead882782be@kernel.org>
     [not found]   ` <CAL_Jsq+=v96eP6V+5Ehi9EQT3iKKU7=t7kvJ-WSA+1WCHDuHEA@mail.gmail.com>
     [not found]     ` <07ee3540-d0c1-436e-9e1d-db1952f609a6@kernel.org>
     [not found]       ` <bcb359cf-0e8a-46ec-9f69-51c4c9e8874e@pengutronix.de>
     [not found]         ` <6638e499-2320-41c9-b720-faf4f976e476@kernel.org>
     [not found]           ` <34bd1a0d8e579aba0a6a88039006500fe822ef3d.camel@ew.tq-group.com>
     [not found]             ` <dd589476-56df-4565-b4cb-e34f0d7d5559@kernel.org>
     [not found]               ` <47903a88-8de9-4ac6-9111-c85ed1428ff0@pengutronix.de>
     [not found]                 ` <CAL_Jsq+9s7UTXU8YLsX=_z1fnc2H4PmReb+2mHx=+uuonqM7xQ@mail.gmail.com>
     [not found]                   ` <aTE_Y_JWs8kBuIE7@pengutronix.de>
     [not found]                     ` <CAL_JsqLFjF7F1eCxL8CzyitGogB0Ee7iHLGf79RHbwTpo6za7g@mail.gmail.com>
2026-05-06 11:25                       ` SoC-specific device tree aliases? Quentin Schulz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox