On Tue, Nov 18, 2025 at 02:43:20PM -0800, Doug Anderson wrote:
This is a continuation of the discussion that started in reply to my patch adding basic device trees for Pixel 10 phones [1].
Problem statement:
We would like an officially accepted scheme that lets us more efficiently ship compiled device trees for a handful of related products by breaking the device trees up into a common "base" device tree and then applying "overlay" device trees atop the base to make a full and complete device tree.
To make it more concrete, we'd like to build a "base" device tree that describes a SoC and then have the overlays be enough to make a full description of a board. In theory, one could also imagine wanting to expand this to 3 or more levels (perhaps SoC, baseboard, derived boards), though this is not planned at this time.
The primary reason for wanting to break device trees like this is efficiency of the shipped binary device trees. A large portion of a final device tree just describes the SoC. We save space in the final compiled device trees if they don't need to contain as much duplicated information.
Having worked on the SolidRun i.MX6 platforms, I agree with this. Within these platforms there are:
SoC SOM Platform imx6dl pre-v1.5 cubox imx6q v1.5 hummingboard v1.5 + emmc hummingboard2
On top of these, I have specific "user" extensions for hardware that I've connected - e.g. - the NoIR RPi camera needs DT modification. - for monitoring a mechanical church clock, a "gps" variant that allowed PPS to be used with a GPIO pin, and a "capture" variant that configured the hardware to allow precise event stamping. - 1-wire, for ds18b20 temperature sensors.
Without the user extensions, this adds up to 18 DTB files: arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6dl-hummingboard2.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-cubox-i.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-emmc-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2-som-v15.dts arch/arm/boot/dts/nxp/imx/imx6q-hummingboard2.dts
basically, every combination needs to be enumerated. So, having two SoC dt files, three for the SOM, and three for the platform that the boot loader combines would significantly cut this down - to 8.
However, it isn't that simple. For example, when the Hummingboard2 is used with the iMX6Q SoC, there's a SATA device present in the SoC level that needs Hummingboard2 specific properties to tune the signal waveform. However, iMX6DL doesn't have this SATA device in silicon, so the node doesn't exist in the base SoC DT file. The situation is the same for Hummingboard, but the tuning parameters, being board specific, are different.
This means is that there are DT properties that are dependent on the SoC DT component and the platform DT component which do not fit with splitting the DT files into their individual "component" levels.
The other issue would be the /model property - for example:
model = "SolidRun HummingBoard2 Solo/DualLite"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som+emmc)"; model = "SolidRun HummingBoard2 Solo/DualLite (1.5som)"; model = "SolidRun HummingBoard Solo/DualLite"; model = "SolidRun HummingBoard2 Dual/Quad"; model = "SolidRun Cubox-i Solo/DualLite";
as a set of examples. I don't see a clear way to generate these from a fragmented scheme. There's a similar problem with the board-level compatible:
compatible = "solidrun,cubox-i/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard/dl", "fsl,imx6dl"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
These don't include the SoM information.
Maybe what would work would be a high-level DT file that contains paths to the lower levels that need to be combined, along with properties that need to be merged. E.g.
/ { model = "SolidRun HummingBoard2 Dual/Quad"; compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
dts-components { compatible = "boot/dt"; component@1 { compatible = "dt"; path = "imx6q.dtbo"; };
component@2 { compatible = "dt"; path = "imx6qdl-sr-som-v1.5.dtbo"; };
component@3 { compatible = "dt"; path = "imx6qdl-hummingboard2.dtbo"; };
component@4 { compatible = "dt"; path = "imx6ql-hummingboard2-emmc.dtbo"; }; };
soc { sata@2200000 { .. sata tuning properties .. }; }; };
Or something similar. However, this would mean we would still need the 18 or so top level DT files, but also each component as well, which will increase the number of files we're having to manage on a target platform - so I'm wondering whether it's worth it.
I don't think we'll be able to get away from this problem: it's likely that there will continue to be properties that are specific across several "levels" of a split DT setup, and apart from something like the above, I don't really see a way to handle them.
I also don't see a sensible way without something like the above for a boot loader to know the filenames of each of the components for a platform - and it would need to be told the order to glue those components together.
I would have liked to use overlays for these platforms, but ISTR they either weren't supported at the time, or frowned upon, and even so I can only see them working for the simplest of cases due to the issue I mention above.