[PATCH v7 00/31] fdt: Make OF_BOARD a boolean option

With Ilias' efforts we have dropped OF_PRIOR_STAGE and OF_HOSTFILE so there are only three ways to obtain a devicetree:
- OF_SEPARATE - the normal way, where the devicetree is built and appended to U-Boot - OF_EMBED - for development purposes, the devicetree is embedded in the ELF file (also used for EFI) - OF_BOARD - the board figures it out on its own
The last one is currently set up so that no devicetree is needed at all in the U-Boot tree. Most boards do provide one, but some don't. Some don't even provide instructions on how to boot on the board.
The problems with this approach are documented in another patch in this series: "doc: Add documentation about devicetree usage"
In practice, OF_BOARD is not really distinct from OF_SEPARATE. Any board can obtain its devicetree at runtime, even it is has a devicetree built in U-Boot. This is because U-Boot may be a second-stage bootloader and its caller may have a better idea about the hardware available in the machine. This is the case with a few QEMU boards, for example.
So it makes no sense to have OF_BOARD as a 'choice'. It should be an option, available with either OF_SEPARATE or OF_EMBED. This would allow rpi3, for example, to run with the devicetree provided by the prior bootloader.
This series makes this change, adding various missing devicetree files (and placeholders) to make the build work.
It also adds a run-time message showing where the devicetree came from, as well as warnings if the board's expected flow is not being used. This comes from the 'standard passage' series, which depends on this series.
It also provides a few qemu clean-ups discovered along the way. The qemu-riscv64_spl problem is fixed.
Please see [2] for discussion on the v6 series.
I put Heinrich's Tested-by tag[3] for the series onto the three devicetree patches (ARM and RISC-V) that I think it most affects. It isn't possible to apply a tag to a whole series at present and in any case there are changes in v7.
This series is available at u-boot-dm/ofb-working
[1] https://patchwork.ozlabs.org/project/uboot/patch/20210919215111.3830278-3-sj... [2] https://lore.kernel.org/u-boot/20211205133207.GW1220664@bill-the-cat/T/#mcd8... [3] https://lore.kernel.org/u-boot/93913911-4d20-d28f-ee04-739985184c5e@canonica...
Changes in v7: - Fix 'linst' typo - Switch to using an empty file for qemu virt - Switch to using an empty file for qemu virt - Switch to using an empty file for qemu virt - Reword commit message - Bring in files from Linux instead - Bring in files from Linux instead - Rewrite the commit message - Use 'empty' instead of 'fake' - Use 'empty' instead of 'fake' - Switch to using an empty file for qemu virt - Bring in files from Linux instead - Fix 'Is' typo in commit message - Drop FDTSRC_PASSAGE for now - Drop FDTSRC_PASSAGE for now - Add new patch to add a Kconfig for boards with a prior stage
Changes in v6: - Fix description of OF_BOARD so it refers just to the current state - Explain that the 'two devicetrees' refers to two *control* devicetrees - Expand the commit message based on comments - Expand the commit message based on comments
Changes in v5: - Bring into the OF_BOARD series - Rebase to master and drop mention of OF_PRIOR_STAGE, since removed - Refer to the 'control' DTB in the first paragraph - Use QEMU instead of qemu - Merge RISC-V and ARM patches since they are similar - Add new patches to clean up fdtdec_setup() and surrounds
Changes in v3: - Clarify the 'bug' refered to at the top - Reword 'This means that there' paragraph to explain U-Boot-specific things - Move to doc/develop/devicetree now that OF_CONTROL is in the docs
Changes in v2: - Fix typos per Sean (thank you!) and a few others - Add a 'Use of U-Boot /config node' section - Drop mention of dm-verity since that actually uses the kernel cmdline - Explain that OF_BOARD will still work after these changes (in 'Once this bug is fixed...' paragraph) - Expand a bit on the reason why the 'Current situation' is bad - Clarify in a second place that Linux and U-Boot use the same devicetree in 'To be clear, while U-Boot...' - Expand on why we should have rules for other projects in 'Devicetree in another project' - Add a comment as to why devicetree in U-Boot is not 'bad design' - Reword 'in-tree U-Boot devicetree' to 'devicetree source in U-Boot' - Rewrite 'Devicetree generated on-the-fly in another project' to cover points raised on v1 - Add 'Why does U-Boot have its nodes and properties?' - Add 'Why not have two devicetrees?'
Simon Glass (31): doc: Add documentation about devicetree usage arm: qemu: Mention -nographic in the docs arm: riscv: qemu: Explain how to extract the generated dt arm: qemu: Add a devicetree file for qemu_arm arm: qemu: Add a devicetree file for qemu_arm64 virt riscv: qemu: Split devicetree files for qemu_riscv32/64 arm: rpi: Sync rpi dts files from Linux arm: vexpress: Add a devicetree files for juno arm: xenguest_arm64: Add a empty devicetree file arm: octeontx: Add an empty devicetree file arm: xilinx_versal_virt: Add a devicetree file arm: bcm7xxx: Add a devicetree file arm: qemu-ppce500: Add a devicetree file arm: highbank: Add devicetree files fdt: Make OF_BOARD a bool option Drop CONFIG_BINMAN_STANDALONE_FDT doc: Update info on devicetree update fdt: Move MULTI_DTB_FIT handling out of fdtdec_setup() fdt: Drop #ifdefs with MULTI_DTB_FIT fdt: Drop CONFIG_SPL_BUILD check in fdtdec_setup() fdt: Drop #ifdef around board_fdt_blob_setup() fdt: Use if() for fdtcontroladdr check fdt: Drop OF_CONTROL check in fdtdec_setup() fdt: Drop remaining preprocessor macros in fdtdec_setup() fdt: Don't call board_fdt_blob_setup() without OF_BOARD dm: core: Allow getting some basic stats fdt: Record where the devicetree came from fdt: Report the devicetree source fdt: Add a Kconfig for boards with a prior stage fdt: Avoid emitting an device tree when not needed fdt: Show build/runtime warnings based on devicetree source
Makefile | 12 +- arch/arm/Kconfig | 8 + arch/arm/dts/Makefile | 20 +- arch/arm/dts/bcm2711-rpi-4-b.dts | 262 ++++ arch/arm/dts/bcm2711-rpi.dtsi | 74 ++ arch/arm/dts/bcm2711.dtsi | 1100 +++++++++++++++++ arch/arm/dts/bcm2835-common.dtsi | 207 ++++ arch/arm/dts/bcm2835-rpi-a-plus.dts | 18 +- arch/arm/dts/bcm2835-rpi-a.dts | 16 +- arch/arm/dts/bcm2835-rpi-b-plus.dts | 18 +- arch/arm/dts/bcm2835-rpi-b-rev2.dts | 16 +- arch/arm/dts/bcm2835-rpi-b.dts | 16 +- arch/arm/dts/bcm2835-rpi-cm1-io1.dts | 9 + arch/arm/dts/bcm2835-rpi-cm1.dtsi | 7 +- arch/arm/dts/bcm2835-rpi-common.dtsi | 12 + arch/arm/dts/bcm2835-rpi-zero-w.dts | 20 +- arch/arm/dts/bcm2835-rpi-zero.dts | 16 +- arch/arm/dts/bcm2835-rpi.dtsi | 35 +- arch/arm/dts/bcm2835.dtsi | 2 + arch/arm/dts/bcm2836-rpi-2-b.dts | 14 +- arch/arm/dts/bcm2836.dtsi | 2 + arch/arm/dts/bcm2837-rpi-3-a-plus.dts | 9 +- arch/arm/dts/bcm2837-rpi-3-b-plus.dts | 9 +- arch/arm/dts/bcm2837-rpi-3-b.dts | 5 +- arch/arm/dts/bcm2837-rpi-cm3-io3.dts | 9 + arch/arm/dts/bcm2837-rpi-cm3.dtsi | 9 + arch/arm/dts/bcm2837.dtsi | 2 + arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi | 7 + arch/arm/dts/bcm283x.dtsi | 224 +--- arch/arm/dts/bcm7xxx.dts | 15 + arch/arm/dts/ecx-common.dtsi | 231 ++++ arch/arm/dts/highbank.dts | 158 +++ arch/arm/dts/juno-base.dtsi | 831 +++++++++++++ arch/arm/dts/juno-clocks.dtsi | 46 + arch/arm/dts/juno-cs-r1r2.dtsi | 85 ++ arch/arm/dts/juno-motherboard.dtsi | 303 +++++ arch/arm/dts/juno-r2.dts | 322 +++++ arch/arm/dts/octeontx.dts | 14 + arch/arm/dts/qemu-arm.dts | 11 + arch/arm/dts/qemu-arm64.dts | 11 + arch/arm/dts/xenguest-arm64.dts | 15 + arch/arm/dts/xilinx-versal-virt.dts | 11 + arch/arm/mach-bcm283x/Kconfig | 1 + arch/powerpc/dts/Makefile | 1 + arch/powerpc/dts/qemu-ppce500.dts | 10 + arch/riscv/dts/Makefile | 2 +- .../dts/{qemu-virt.dts => qemu-virt32.dts} | 3 + arch/riscv/dts/qemu-virt64.dts | 11 + board/emulation/qemu-riscv/Kconfig | 1 + cmd/bdinfo.c | 2 + common/board_r.c | 24 + configs/bcm7260_defconfig | 1 + configs/bcm7445_defconfig | 1 + configs/highbank_defconfig | 2 +- configs/octeontx2_95xx_defconfig | 1 + configs/octeontx2_96xx_defconfig | 1 + configs/octeontx_81xx_defconfig | 1 + configs/octeontx_83xx_defconfig | 1 + configs/qemu-ppce500_defconfig | 2 + configs/qemu-riscv32_defconfig | 1 + configs/qemu-riscv32_smode_defconfig | 1 + configs/qemu-riscv32_spl_defconfig | 4 +- configs/qemu-riscv64_defconfig | 1 + configs/qemu-riscv64_smode_defconfig | 1 + configs/qemu-riscv64_spl_defconfig | 3 +- configs/qemu_arm64_defconfig | 1 + configs/qemu_arm_defconfig | 1 + configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + configs/vexpress_aemv8a_juno_defconfig | 1 + configs/xenguest_arm64_defconfig | 2 +- configs/xilinx_versal_virt_defconfig | 1 + doc/board/emulation/qemu-arm.rst | 10 +- doc/board/emulation/qemu-riscv.rst | 3 + doc/develop/devicetree/dt_qemu.rst | 48 + doc/develop/devicetree/dt_update.rst | 495 ++++++++ doc/develop/devicetree/index.rst | 2 + drivers/core/device.c | 11 + drivers/core/root.c | 7 + drivers/core/uclass.c | 13 + dts/Kconfig | 65 +- include/asm-generic/global_data.h | 12 + include/dm/device.h | 11 +- include/dm/root.h | 8 + include/dm/uclass-internal.h | 7 + include/dt-bindings/clock/bcm2835.h | 2 + include/fdtdec.h | 53 +- lib/fdtdec.c | 141 ++- test/dm/core.c | 41 + tools/binman/binman.rst | 20 - 91 files changed, 4879 insertions(+), 366 deletions(-) create mode 100644 arch/arm/dts/bcm2711-rpi-4-b.dts create mode 100644 arch/arm/dts/bcm2711-rpi.dtsi create mode 100644 arch/arm/dts/bcm2711.dtsi create mode 100644 arch/arm/dts/bcm2835-common.dtsi create mode 100644 arch/arm/dts/bcm2835-rpi-common.dtsi create mode 100644 arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi create mode 100644 arch/arm/dts/bcm7xxx.dts create mode 100644 arch/arm/dts/ecx-common.dtsi create mode 100644 arch/arm/dts/highbank.dts create mode 100644 arch/arm/dts/juno-base.dtsi create mode 100644 arch/arm/dts/juno-clocks.dtsi create mode 100644 arch/arm/dts/juno-cs-r1r2.dtsi create mode 100644 arch/arm/dts/juno-motherboard.dtsi create mode 100644 arch/arm/dts/juno-r2.dts create mode 100644 arch/arm/dts/octeontx.dts create mode 100644 arch/arm/dts/qemu-arm.dts create mode 100644 arch/arm/dts/qemu-arm64.dts create mode 100644 arch/arm/dts/xenguest-arm64.dts create mode 100644 arch/arm/dts/xilinx-versal-virt.dts create mode 100644 arch/powerpc/dts/qemu-ppce500.dts rename arch/riscv/dts/{qemu-virt.dts => qemu-virt32.dts} (94%) create mode 100644 arch/riscv/dts/qemu-virt64.dts create mode 100644 doc/develop/devicetree/dt_qemu.rst create mode 100644 doc/develop/devicetree/dt_update.rst

At present some of the ideas and techniques behind devicetree in U-Boot are assumed, implied or unsaid. Add some documentation to cover how devicetree is build, how it can be modified and the rules about using the various CONFIG_OF_... options.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marcel Ziswiler marcel.ziswiler@toradex.com --- This patch attracted quite a bit of discussion here:
https://patchwork.ozlabs.org/project/uboot/patch/20210909201033.755713-4-sjg...
I have not included the text suggested by François. While I agree that it would be useful to have an introduction in this space, I do not agree that we should have two devicetrees or that U-Boot should not have its own things in the devicetree, so it is not clear to me what we should actually write.
The 'Devicetree Control in U-Boot' docs were recently merged and these provide some base info, for now.
Changes in v7: - Fix 'linst' typo
Changes in v6: - Fix description of OF_BOARD so it refers just to the current state - Explain that the 'two devicetrees' refers to two *control* devicetrees
Changes in v5: - Bring into the OF_BOARD series - Rebase to master and drop mention of OF_PRIOR_STAGE, since removed - Refer to the 'control' DTB in the first paragraph - Use QEMU instead of qemu
Changes in v3: - Clarify the 'bug' refered to at the top - Reword 'This means that there' paragraph to explain U-Boot-specific things - Move to doc/develop/devicetree now that OF_CONTROL is in the docs
Changes in v2: - Fix typos per Sean (thank you!) and a few others - Add a 'Use of U-Boot /config node' section - Drop mention of dm-verity since that actually uses the kernel cmdline - Explain that OF_BOARD will still work after these changes (in 'Once this bug is fixed...' paragraph) - Expand a bit on the reason why the 'Current situation' is bad - Clarify in a second place that Linux and U-Boot use the same devicetree in 'To be clear, while U-Boot...' - Expand on why we should have rules for other projects in 'Devicetree in another project' - Add a comment as to why devicetree in U-Boot is not 'bad design' - Reword 'in-tree U-Boot devicetree' to 'devicetree source in U-Boot' - Rewrite 'Devicetree generated on-the-fly in another project' to cover points raised on v1 - Add 'Why does U-Boot have its nodes and properties?' - Add 'Why not have two devicetrees?'
doc/develop/devicetree/dt_update.rst | 555 +++++++++++++++++++++++++++ doc/develop/devicetree/index.rst | 1 + 2 files changed, 556 insertions(+) create mode 100644 doc/develop/devicetree/dt_update.rst
diff --git a/doc/develop/devicetree/dt_update.rst b/doc/develop/devicetree/dt_update.rst new file mode 100644 index 00000000000..e3b65f6fa66 --- /dev/null +++ b/doc/develop/devicetree/dt_update.rst @@ -0,0 +1,555 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Updating the devicetree +======================= + +U-Boot uses devicetree for runtime configuration and storing required blobs or +any other information it needs to operate. This is called the 'control' +devicetree since it controls U-Boot. It is possible to update the control +devicetree separately from actually building U-Boot. This provides a good degree +of control and flexibility for firmware that uses U-Boot in conjunction with +other project. + +There are many reasons why it is useful to modify the devicetree after building +it: + +- Configuration can be changed, e.g. which UART to use +- A serial number can be added +- Public keys can be added to allow image verification +- Console output can be changed (e.g. to select serial or vidconsole) + +This section describes how to work with devicetree to accomplish your goals. + +See also :doc:`../devicetree/control` for a basic summary of the available +features. + + +Devicetree source +----------------- + +Every board in U-Boot must include a devicetree sufficient to build and boot +that board on suitable hardware (or emulation). This is specified using the +`CONFIG DEFAULT_DEVICE_TREE` option. + + +Current situation (October 2021) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As an aside, at present U-Boot allows `CONFIG_DEFAULT_DEVICE_TREE` to be empty, +e.g. if `CONFIG_OF_BOARD` is used. This has unfortunately created an enormous +amount of confusion and some wasted effort. This was not intended. Support for +an empty `CONFIG_DEFAULT_DEVICE_TREE` will be dropped soon. + +Some of the problems created are: + +- It is not obvious that the devicetree is coming from another project + +- There is no way to see even a sample devicetree for these platform in U-Boot, + so it is hard to know what is going on, e.g. which devices are typically + present + +- The other project may not provide a way to support U-Boot's requirements for + devicetree, such as the /config node. Note: On the U-Boot mailing list, this + was only discovered after weeks of discussion and confusion + +- For QEMU specifically, consulting two QEMU source files is required, for which + there are no references in U-Boot documentation. The code is generating a + devicetree, but it is not clear what controls affect this generation. + +Specifically on the changes in U-Bootm `CONFIG_OF_BOARD` was added in +rpi_patch_ for Raspberry Pi, which does have an in-tree devicetree, but this +feature has since been used for boards that don't + +Once this bug is fixed, CONFIG_OF_BOARD will override (at runtime) the +evicetree suppled with U-Boot, but will otherwise use CONFIG_OF_SEPARATE for the +in-tree build. So these two will become options, moving out of the 'choice' in +`dts/Kconfig`. + +This means that there is a basic devicetree build in the U-Boot tree, for +build-testing, consistency and documentation purposes, but at runtime U-Boot can +accept its devicetree from another source. The in-tree devicetree may contain +U-Boot-specific features (in u-boot*.dtsi files) and this may prove useful for +the other project, so it can ensure that U-Boot functions correctly and supports +all its expected features. + +To be clear, while U-Boot has its own copy of the devicetree source for each +board, this must match the Linux source, perhaps with some u-boot.dtsi +additions. The intent here is not to create a separate binding, just to provide +a representative devicetree in U-Boot. + +Offending boards are: + +- rpi_4 and rpi_4_32b (other rpi boards do have an in-tree devicetree) +- qemu_arm64 +- qemu_arm +- qemu-ppce500 +- qemu-riscv32 +- qemu-riscv32_smode +- qemu-riscv64 +- qemu-riscv64_smode + +All of these need to have a devicetree added in-tree. This is targeted to be +fixed in the 2022.01 release. + + +Building the devicetree +----------------------- + +U-Boot automatically builds the devicetree for a board, from the +`arch/<arch>/dts` directory. The Makefile in those directories has rules for +building devicetree files. It is preferable to avoid target-specific rules in +those files: i.e. all boards for a particular SoC should be built at once, +where practical. Apart from simplifying the Makefile, this helps to efficiently +(and immediately) ensure that changes in one board's DT do not break others that +are related. Building devicetrees is fast, so performance is seldom a concern +here. + + +Overriding the default devicetree +--------------------------------- + +When building U-Boot, the `DEVICE_TREE` environment variable allows the +default devicetree file to be overridden at build time. This can be useful if +modifications have to be made to the in-tree devicetree file, for the benefit +of a downstream build system. Note that the in-tree devicetree must be +sufficient to build and boot, so this is not a way to bypass that requirement. + + +Modifying the devicetree after building +--------------------------------------- + +While it is generally painful and hacky to modify the code or rodata of a +program after it is built, in many cases it is useful to do so, e.g. to add +configuration information like serial numbers, enabling/disabling features, etc. + +Devicetree provides a very nice solution to these problems since it is +structured data and it is relatively easy to change it, even in binary form +(see fdtput). + +U-Boot takes care that the devicetree is easily accessible after the build +process. In fact it is placed in a separate file called `u-boot.dtb`. If the +build system wants to modify or replace that file, it can do so. Then all that +is needed is to run `binman update` to update the file inside the image. If +binman is not used, then `u-boot-nodtb.bin` and the new `u-boot.dtb` can simply +be concatenated to achieve the desired result. U-Boot happily copes with the +devicetree growing or shrinking. + +The `u-boot.bin` image contains both pieces. While it is possible to locate the +devicetree within the image using the signature at the start of the file, this +is a bit messy. + +This is why `CONFIG_OF_SEPARATE` should always be used when building U-Boot. +The `CONFIG_OF_EMBED` option embeds the devicetree somewhere in the U-Boot ELF +image as rodata, meaning that it is hard to find it and it cannot increase in +size. + +When modifying the devicetree, the different cases to consider are as follows: + +- CONFIG_OF_SEPARATE + This is easy, described above. Just change, replace or rebuild the + devicetree so it suits your needs, then rerun binman or redo the `cat` + operation to join `u-boot-nodtb.bin` and the new `u-boot.dtb` + +- CONFIG_OF_EMBED + This is tricky, since the devicetree cannot easily be located. If the EFL + file is available, then the _dtb_dt_begin and __dtb_dt_end symbols can be + examined to find it. While it is possible to contract the file, it is not + possible to expand the file since that would involve re-linking + +- CONFIG_OF_BOARD + This is a board-specific situation, so needs to be considered on a + case-by-case base. + + +Use of U-Boot /config node +-------------------------- + +A common problem with firmware is that many builds are needed to deal with the +slight variations between different, related models. For example, one model may +have a TPM and another may not. Devicetree provides an excellent solution to +this problem, in that the devicetree to actually use on a platform can be +injected in the factory based on which model is being manufactured at the time. + +A related problem causing build proliferation is dealing with the differences +between development firmware, developer-friendly firmware (e.g. with all +security features present but with the ability to access the command line), +test firmware (which runs tests used in the factory), final production firmware +(before signing), signed firmware (where the signatures have been inserted) and +the like. Ideally all or most of these should use the same U-Boot build, with +just some options to determine the features available. For example, being able +to control whether the UART console or JTAG are available, on any image, is a +great debugging aid. + +When the firmware consists of multiple parts, it is helpful that all operate +the same way at runtime, regardless of how they were built. This can be achieved +by passing the runtime configuration (e.g. 'enable UART console) along the chain +through each firmware stage. It is frustrating to have to replicate a bug on +production firmware which does happen on developer firmware, because they are +completely different builds. + +The /config node provides useful functionality for this. It allows the different +controls to be 'factored out' of the U-Boot binary, so they can be controlled +separately from the initial source-code build. The node can be easily updated by +a build or factory tool and can control various features in U-Boot. It is +similar in concept to a Kconfig option, except that it can be changed after +U-Boot is built. + +The /config node is similar in concept to the `/chosen node`_ except that it is +for passing information *into* firmware instead of from firmware to the +Operating System. Also, while Linux has a (sometimes extremely long) command +line, U-Boot does not support this. The devicetree provides a more structured +approach in any case. + + +Devicetree in another project +----------------------------- + +In some cases U-Boot receive its devicetree at runtime from a program that calls +it. For example ARM's Trusted Firmware A (`TF-A`_) may have a devicetree that it +passes to U-Boot. This overrides any devicetree build by U-Boot. When packaging +the firmware, the U-Boot devicetree may in fact be left out if it can be +guaranteed that it will receive one from another project. + +In this case, the devicetree in the other project must track U-Boot's use of +device tree, for the following reasons: + +- U-Boot only has one devicetree. See `Why not have two devicetrees?`_. +- For a consistent firmware build, decisions made in early stages should be + communicated to later ones at runtime. For example, if the serial console is + enabled in an early stage, it should be enabled in U-Boot too. +- U-Boot is quite capable of managing its own copy of the devicetree. If + another project wants to bypass this (often for good reason), it is reasonable + that it should take on the (fairly small) requirements that U-Boot features + that rely on devicetree are still available +- The point here is not that *U-Boot needs this extra node*, or *U-Boot needs + to have this public key*. These features are present in U-Boot in service of + the entire firmware system. If the U-Boot features are used, but cannot be + supported in the normal way, then there is pressure to implement these + features in other ways. In the end, we would have a different mechanism for + every other project that uses U-Boot. This introduces duplicate ways of doing + the same thing, needlessly increases the complexity of the U-Boot source code, + forces authors to consider parallel implementations when writing new features, + makes U-Boot harder to test, complicates documentation and confuses the + runtime flow of U-Boot. If every board did things its own way rather than + contributing to the common code, U-Boot would lose a lot of its cross-platform + value. + +The above does not indicate *bad design* within U-Boot. Devicetree is a core +component of U-Boot and U-Boot makes use of it to the full. It solves a myriad +of problems that would otherwise need their own special C struct, binary format, +special property, tooling for viewing and updating, etc. + +Specifically, the other project must provide a way to add configuration and +other information to the devicetree for use by U-Boot, such as the /config node. +Note that the U-Boot in-tree devicetree source must be sufficient to build and +boot, so this is not a way to bypass that requirement. + +If binman is used, the devicetree source in U-Boot must contain the binman +definition so that a valid image can be build. This helps people discover what +other firmware components are needed and seek out appropriate documentation. + +If verified boot is used, the project must provide a way to inject a public key, +certificate or other material into the U-Boot devicetree so that it is available +to U-Boot at runtime. See `Signing with U-Boot devicetree`_. This may be +through tooling in the project itself or by making use of U-Boot's tooling. + + +Devicetree generated on-the-fly in another project +-------------------------------------------------- + +In some rare cases, another project may wish to create a devicetree for U-Boot +entirely on-the-fly, then pass it to U-Boot at runtime. The only known example +of this at the time of writing (2021) is QEMU, for ARM (`QEMU ARM`_) and +RISC-V (`QEMU RISC-V`_). + +In effect, when the board boots, U-Boot is *downstream* of the other project. +It is entirely reliant on that project for its correct operation. + +This does not mean to imply that the other project is creating its own, +incompatible devicetree. In fact QEMU generates a valid devicetree which is +suitable for both U-Boot and Linux. It is quite normal for a devicetree to be +present in flash and be made available to U-Boot at runtime. What matters is +where the devicetree comes from. If the other project builds a devicetree for +U-Boot then it needs to support adding the things needed by U-Boot features. +Without them, for example: + +- U-Boot may not boot because too many devices are enabled before relocation +- U-Boot may not have access to the developer or production public keys used for + signing +- U-Boot may not support controlling whether the console is enabled +- U-Boot may not be know which MMC device to boot from +- U-Boot may not be able to find other firmware components that it needs to load + +Normally, supporting U-Boot's features is trivial, since the devicetree compiler +(dtc) can compile the source, including any U-Boot pieces. So the burden is +extremely low. + +In this case, the devicetree in the other project must track U-Boot's use of +device tree, so that it remains compatible. See `Devicetree in another project`_ +for reasons why. + +If a particular version of the project is needed for a particular version of +U-Boot, that must be documented in both projects. + +Further, it must provide a way to add configuration and other information to +the devicetree for use by U-Boot, such as the `/config` node and the tags used +by driver model. Note that the U-Boot in-tree devicetree must be sufficient to +build and boot, so this is not a way to bypass that requirement. + +More specifically, tooling or command-line arguments must provide a way to +add a `/config` node or items within that node, so that U-Boot can receive a +suitable configuration. It must provide a way of adding `u-boot,dm-...` tags for +correct operation of driver model. These options can then be used as part of the +build process, which puts the firmware image together. For binman, a way must be +provided to add the binman definition into the devicetree in the same way. + +One way to do this is to allow a .dtsi file to be merged in with the generated +devicetree. + +Note that the burden goes both ways. If a new feature is added to U-Boot which +needs support in another project, then the author of the U-Boot patch must add +any required support to the other project. + + +Passing the devicetree through to Linux +--------------------------------------- + +Ideally U-Boot and Linux use the same devicetree source, even though it is +hosted in separate projects. U-Boot adds some extra pieces, such as the +`config/` node and tags like `u-boot,dm-spl`. Linux adds some extra pieces, such +as `linux,default-trigger` and `linux,code`. This should not interfere with +each other. + +In principle it is possible for U-Boot's control devicetree to be passed to +Linux. This is, after all, one of the goals of devicetree and the original +Open Firmware project, to have the firmware provide the hardware description to +the Operating System. + +For boards where this approach is used, care must be taken. U-Boot typically +needs to 'fix up' the devicetree before passing it to Linux, e.g. to add +information about the memory map, about which serial console is used, provide +the kernel address space layout randomization (KASLR) seed or select whether the +console should be silenced for a faster boot. + +Fix-ups involve modifying the devicetree. If the control devicetree is used, +that means the control devicetree could be modified, while U-Boot is using it. +Removing a device and reinserting it can cause problems if the devicetree offset +has changed, for example, since the device will be unable to locates its +devicetree properties at the expected devicetree offset, which is a fixed +integer. + +To deal with this, it is recommended to employ one or more of the following +approaches: + +- Make a copy of the devicetree and 'fix up' the copy, leaving the control + devicetree alone +- Enable `CONFIG_OF_LIVE` so that U-Boot makes its own copy of the devicetree + during relocation; fixups then happen on the original flat tree +- Ensure that fix-ups happen after all loading has happened and U-Boot has + completed image verification + +In practice,the last point is typically observed, since boot_prep_linux() is +called just before jumping to Linux, long after signature verification, for +example. But it is important to make sure that this line is not blurred, +particularly if untrusted user data is involved. + + +Devicetree use cases that must be supported +------------------------------------------- + +Regardless of how the devicetree is provided to U-Boot at runtime, various +U-Boot features must be fully supported. This section describes some of these +features and the implications for other projects. + +If U-Boot uses its own in-tree devicetree these features are supported +automatically. + + +Signing with U-Boot devicetree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +U-Boot supports signing a payload so that it can be verified to have been +created by a party owning a private key. This is called verified boot in U-Boot +(see doc/uImage.FIT/verified-boot.txt). + +Typically this works by creating a FIT and then running the `mkimage` tool to +add signatures for particular images. As part of this process, `mkimage` writes +a public key to the U-Boot devicetree, although this can be done separately. +See fdt_add_pubkey_ for patches for a suitable tool, for example. + +As with all configuration information, if another project is providing the +devicetree to U-Boot, it must provide a way to add this public key into the +devicetree it passes to U-Boot. This could be via a tooling option, making use +of `mkimage`, or allowing a .dtsi file to be merged in with what is generated in +the other project. + + +Providing the binman image definition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In complex systems U-Boot must locate and make use of other firmware components, +such as images for the user interface, files containing peripheral firmware, +multiple copies of U-Boot for use with A/B boot, etc. U-Boot uses +:doc:`Binman <../package/binman>` as a standard way of putting an image +together. + +Typically this works by running binman with the devicetree as an input, to +create the file image. Binman then outputs an updated devicetree which is +packed in the firmware image, so U-Boot can access the binman definition and +locate all the components. + +As with all configuration information, if another project is providing the +devicetree to U-Boot, it must provide a way to add this binman definition into +the devicetree it passes to U-Boot. This could be via a tooling option, making +use of `binman`, or alowing a .dtsi file to be merged in with what is generated +in the other project. + + +Protecting the devicetree +------------------------- + +U-Boot relies heavily on devicetree for correct operation. A corrupt or invalid +device can cause U-Boot to fail to start, behave incorrectly, crash (e.g. if +`CONFIG_OF_LIBFDT_ASSUME_MASK` is adjusted, or fail to boot an Operating System. +Within U-Boot, the devicetree is as important as any other part of the source +code. At ruuntime, the devicetree can be considered to be structured rodata. + +With secure systems, care must be taken that the devicetree is valid: + +- If the code / rodata has a hash or signature, the devicetree should also, if + they are packaged separately. +- If the code / rodata is write-protected when running, the devicetree should be + also. Note that U-Boot relocates its code and devicetree, so this is not as + simple as it sounds. U-Boot must write-protect these items after relocating. + + +Why does U-Boot have its nodes and properties? +---------------------------------------------- + +See also :doc:`../devicetree/intro`. + +There has been pushback at the concept that U-Boot dares have its own nodes and +properties in the devicetree. + +Apart from these nodes and properties, U-Boot uses the same bindings as Linux. +A `u-boot.dtsi` file helps to keep U-Boot-specific changes in separate files, +making it easier to keep devicetree source files in U-Boot in sync with Linux. + +As a counter-example, the Zephyr OS project takes a different approach. It uses +entirely different bindings, in general, making no effort to sync devicetree +source files with Linux. U-Boot strives to be compatible with Linux in a number +of ways, such as source code style and common APIs, to aid porting of code +between the projects. Devicetree is another way where U-Boot and Linux follow a +similar approach. + +Fundamentally, the idea that U-Boot cannot have its own tags flies in the face +of the devicetree specification (see dtspec_), which says: + + Nonstandard property names should specify a **unique string prefix**, such as + a stock ticker symbol, identifying the name of the company **or organization** + that defined the property. Examples: + + - fsl,channel-fifo-len + - ibm,ppc-interrupt-server#s + - **linux**,network-index + +It is also fundamentally unbalanced. Linux has many tags of its own (some 36 in +version 5.13) and at least one Linux-specific node, even if you ignore things +like flash partitions which clearly provide configuration information to Linux. + +Practically speaking there are many reasons why U-Boot has its own nodes and +properties. Some examples: + +- Binding every device before relocation even if it won't be used, consumes time + and memory: tags on each node can specify which are needed in SPL or before + relocation. Linux has no such constraints. + +- Requiring the full clock tree to be up and running just to get the debug UART + running is inefficient. It is also and self-defeating, since if that much + code is working properly, you probably don't need the debug UART. A devicetree + property to provide the UART input-clock frequency is a simple solution. + +- U-Boot does not have a user space to provide policy and configuration. It + cannot do what Linux does and run programs and look up filesystems to figure + out how to boot. + + +Why not have two devicetrees? +----------------------------- + +Setting aside the argument for restricting U-Boot from having its own nodes and +properties, another idea proposed is to have two devicetrees, one for the +U-Boot-specific bits (here called `special`) and one for everything else (here +called `linux`). This would mean that U-Boot would be controlled by two +devicetrees, i.e. OF_CONTROL would require/allow two devicetrees in order to +work. + +On the positive side, it might quieten the discussion alluded to in the section +above. But there are many negatives to consider and many open questions to +resolve. + +- **Bindings** - Presumably the special devicetree would have its own bindings. + It would not be necessary to put a `u-boot,` prefix on anything. People coming + across the devicetree source would wonder how it fits in with the Linux + devicetree. + +- **Access** - U-Boot has a nice `ofnode` API for accessing the devicetree. This + would need to be expanded to support two trees. Features which need to access + both (such as a device driver which reads the special devicetree to get some + configuration info) could become quite confusing to read and write. + +- **Merging** - Can the two devicetree be merged if a platform desires it? If + so, how is this managed in tooling? Does it happen during the build, in which + case they are not really separate at all. Or does U-Boot merge them at + runtime, in which case this adds time and memory? + +- **Efficiency** - A second device tree adds more code and more code paths. It + requires that both be made available to the code in U-Boot, e.g. via a + separate pointer or argument or API. Overall the separation would certainly + not speed up U-Boot, nor decrease its size. + +- **Source code** - At present `u-boot.dtsi` files provide the pieces needed for + U-Boot for a particular board. Would we use these same files for the special + devicetree? + +- **Complexity** - Two devicetrees complicates the build system since it must + build and package them both. Errors must be reported in such a way that it + is obvious which one is failing. + +- **Referencing each other** - The `u-boot,dm-xxx` tags used by driver model + are currently placed in the nodes they relate to. How would these tags + reference a node that is in a separate devicetree? What extra validation would + be needed? + +- **Storage** - How would the two devicetrees be stored in the image? At present + we simply concatenate the U-Boot binary and the devicetree. We could add the + special devicetree before the Linux one, so two are concatenated, but it is + not pretty. We could use binman to support more complex arrangements, but only + some boards use this at present, so it would be a big change. + +- **API** - How would another project provide two devicetree files to U-Boot at + runtime? Presumably this would just be too painful. But if it doesn't, it + would be unable to configure run-time features of U-Boot during the boot. + +- **Confusion** - No other project has two devicetrees used for controlling its + operation (although having multiple devicetrees to pass on to the OS is + common). U-Boot would be in the unfortunate position of having to describe + the purpose of the two control devicetrees fact to new users, along with the + (arguably contrived) reason for the arrangement. + +- **Signing flow** - The current signing flow is simple as it involves running + `mkimage` with the U-Boot devicetree. This would have to be updated to use the + special devicetree. Some way of telling the user that they have done it wrong + would have to be invented. + +Overall, adding a second devicetree would create enormous confusion and +complexity. It seems a lot cheaper to solve this by a change of attitude. + + +.. _rpi_patch: https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-deym... +.. _`TF-A`: https://www.trustedfirmware.org/projects/tf-a +.. _`QEMU ARM`: https://github.com/qemu/qemu/blob/master/hw/arm/virt.c +.. _`QEMU RISC-V`: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c +.. _`/chosen node`: https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt +.. _fdt_add_pubkey: https://patchwork.ozlabs.org/project/uboot/list/?series=157843&state=* +.. _dtspec: https://www.devicetree.org/specifications/ diff --git a/doc/develop/devicetree/index.rst b/doc/develop/devicetree/index.rst index fa5db3eb76e..b5b33dfea0f 100644 --- a/doc/develop/devicetree/index.rst +++ b/doc/develop/devicetree/index.rst @@ -11,3 +11,4 @@ build-time and runtime configuration.
intro control + dt_update

On 12/6/21 16:11, Simon Glass wrote:
At present some of the ideas and techniques behind devicetree in U-Boot are assumed, implied or unsaid. Add some documentation to cover how devicetree is build, how it can be modified and the rules about using the various CONFIG_OF_... options.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marcel Ziswiler marcel.ziswiler@toradex.com
This patch attracted quite a bit of discussion here:
https://patchwork.ozlabs.org/project/uboot/patch/20210909201033.755713-4-sjg...
I have not included the text suggested by François. While I agree that it would be useful to have an introduction in this space, I do not agree that we should have two devicetrees or that U-Boot should not have its own things in the devicetree, so it is not clear to me what we should actually write.
The 'Devicetree Control in U-Boot' docs were recently merged and these provide some base info, for now.
As you already remarked part of this text has not been agreed upon.
Please, either remove this part of the text or mark it as your private opinion.
Best regards
Heinrich
Changes in v7:
- Fix 'linst' typo
Changes in v6:
- Fix description of OF_BOARD so it refers just to the current state
- Explain that the 'two devicetrees' refers to two *control* devicetrees
Changes in v5:
- Bring into the OF_BOARD series
- Rebase to master and drop mention of OF_PRIOR_STAGE, since removed
- Refer to the 'control' DTB in the first paragraph
- Use QEMU instead of qemu
Changes in v3:
- Clarify the 'bug' refered to at the top
- Reword 'This means that there' paragraph to explain U-Boot-specific things
- Move to doc/develop/devicetree now that OF_CONTROL is in the docs
Changes in v2:
Fix typos per Sean (thank you!) and a few others
Add a 'Use of U-Boot /config node' section
Drop mention of dm-verity since that actually uses the kernel cmdline
Explain that OF_BOARD will still work after these changes (in 'Once this bug is fixed...' paragraph)
Expand a bit on the reason why the 'Current situation' is bad
Clarify in a second place that Linux and U-Boot use the same devicetree in 'To be clear, while U-Boot...'
Expand on why we should have rules for other projects in 'Devicetree in another project'
Add a comment as to why devicetree in U-Boot is not 'bad design'
Reword 'in-tree U-Boot devicetree' to 'devicetree source in U-Boot'
Rewrite 'Devicetree generated on-the-fly in another project' to cover points raised on v1
Add 'Why does U-Boot have its nodes and properties?'
Add 'Why not have two devicetrees?'
doc/develop/devicetree/dt_update.rst | 555 +++++++++++++++++++++++++++ doc/develop/devicetree/index.rst | 1 + 2 files changed, 556 insertions(+) create mode 100644 doc/develop/devicetree/dt_update.rst
diff --git a/doc/develop/devicetree/dt_update.rst b/doc/develop/devicetree/dt_update.rst new file mode 100644 index 00000000000..e3b65f6fa66 --- /dev/null +++ b/doc/develop/devicetree/dt_update.rst @@ -0,0 +1,555 @@ +.. SPDX-License-Identifier: GPL-2.0+
+Updating the devicetree +=======================
+U-Boot uses devicetree for runtime configuration and storing required blobs or +any other information it needs to operate. This is called the 'control' +devicetree since it controls U-Boot. It is possible to update the control +devicetree separately from actually building U-Boot. This provides a good degree +of control and flexibility for firmware that uses U-Boot in conjunction with +other project.
+There are many reasons why it is useful to modify the devicetree after building +it:
+- Configuration can be changed, e.g. which UART to use +- A serial number can be added +- Public keys can be added to allow image verification +- Console output can be changed (e.g. to select serial or vidconsole)
+This section describes how to work with devicetree to accomplish your goals.
+See also :doc:`../devicetree/control` for a basic summary of the available +features.
+Devicetree source +-----------------
+Every board in U-Boot must include a devicetree sufficient to build and boot +that board on suitable hardware (or emulation). This is specified using the +`CONFIG DEFAULT_DEVICE_TREE` option.
+Current situation (October 2021) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As an aside, at present U-Boot allows `CONFIG_DEFAULT_DEVICE_TREE` to be empty, +e.g. if `CONFIG_OF_BOARD` is used. This has unfortunately created an enormous +amount of confusion and some wasted effort. This was not intended. Support for +an empty `CONFIG_DEFAULT_DEVICE_TREE` will be dropped soon.
+Some of the problems created are:
+- It is not obvious that the devicetree is coming from another project
+- There is no way to see even a sample devicetree for these platform in U-Boot,
- so it is hard to know what is going on, e.g. which devices are typically
- present
+- The other project may not provide a way to support U-Boot's requirements for
- devicetree, such as the /config node. Note: On the U-Boot mailing list, this
- was only discovered after weeks of discussion and confusion
+- For QEMU specifically, consulting two QEMU source files is required, for which
- there are no references in U-Boot documentation. The code is generating a
- devicetree, but it is not clear what controls affect this generation.
+Specifically on the changes in U-Bootm `CONFIG_OF_BOARD` was added in +rpi_patch_ for Raspberry Pi, which does have an in-tree devicetree, but this +feature has since been used for boards that don't
+Once this bug is fixed, CONFIG_OF_BOARD will override (at runtime) the +evicetree suppled with U-Boot, but will otherwise use CONFIG_OF_SEPARATE for the +in-tree build. So these two will become options, moving out of the 'choice' in +`dts/Kconfig`.
+This means that there is a basic devicetree build in the U-Boot tree, for +build-testing, consistency and documentation purposes, but at runtime U-Boot can +accept its devicetree from another source. The in-tree devicetree may contain +U-Boot-specific features (in u-boot*.dtsi files) and this may prove useful for +the other project, so it can ensure that U-Boot functions correctly and supports +all its expected features.
+To be clear, while U-Boot has its own copy of the devicetree source for each +board, this must match the Linux source, perhaps with some u-boot.dtsi +additions. The intent here is not to create a separate binding, just to provide +a representative devicetree in U-Boot.
+Offending boards are:
+- rpi_4 and rpi_4_32b (other rpi boards do have an in-tree devicetree) +- qemu_arm64 +- qemu_arm +- qemu-ppce500 +- qemu-riscv32 +- qemu-riscv32_smode +- qemu-riscv64 +- qemu-riscv64_smode
+All of these need to have a devicetree added in-tree. This is targeted to be +fixed in the 2022.01 release.
+Building the devicetree +-----------------------
+U-Boot automatically builds the devicetree for a board, from the +`arch/<arch>/dts` directory. The Makefile in those directories has rules for +building devicetree files. It is preferable to avoid target-specific rules in +those files: i.e. all boards for a particular SoC should be built at once, +where practical. Apart from simplifying the Makefile, this helps to efficiently +(and immediately) ensure that changes in one board's DT do not break others that +are related. Building devicetrees is fast, so performance is seldom a concern +here.
+Overriding the default devicetree +---------------------------------
+When building U-Boot, the `DEVICE_TREE` environment variable allows the +default devicetree file to be overridden at build time. This can be useful if +modifications have to be made to the in-tree devicetree file, for the benefit +of a downstream build system. Note that the in-tree devicetree must be +sufficient to build and boot, so this is not a way to bypass that requirement.
+Modifying the devicetree after building +---------------------------------------
+While it is generally painful and hacky to modify the code or rodata of a +program after it is built, in many cases it is useful to do so, e.g. to add +configuration information like serial numbers, enabling/disabling features, etc.
+Devicetree provides a very nice solution to these problems since it is +structured data and it is relatively easy to change it, even in binary form +(see fdtput).
+U-Boot takes care that the devicetree is easily accessible after the build +process. In fact it is placed in a separate file called `u-boot.dtb`. If the +build system wants to modify or replace that file, it can do so. Then all that +is needed is to run `binman update` to update the file inside the image. If +binman is not used, then `u-boot-nodtb.bin` and the new `u-boot.dtb` can simply +be concatenated to achieve the desired result. U-Boot happily copes with the +devicetree growing or shrinking.
+The `u-boot.bin` image contains both pieces. While it is possible to locate the +devicetree within the image using the signature at the start of the file, this +is a bit messy.
+This is why `CONFIG_OF_SEPARATE` should always be used when building U-Boot. +The `CONFIG_OF_EMBED` option embeds the devicetree somewhere in the U-Boot ELF +image as rodata, meaning that it is hard to find it and it cannot increase in +size.
+When modifying the devicetree, the different cases to consider are as follows:
+- CONFIG_OF_SEPARATE
- This is easy, described above. Just change, replace or rebuild the
- devicetree so it suits your needs, then rerun binman or redo the `cat`
- operation to join `u-boot-nodtb.bin` and the new `u-boot.dtb`
+- CONFIG_OF_EMBED
- This is tricky, since the devicetree cannot easily be located. If the EFL
- file is available, then the _dtb_dt_begin and __dtb_dt_end symbols can be
- examined to find it. While it is possible to contract the file, it is not
- possible to expand the file since that would involve re-linking
+- CONFIG_OF_BOARD
- This is a board-specific situation, so needs to be considered on a
- case-by-case base.
+Use of U-Boot /config node +--------------------------
+A common problem with firmware is that many builds are needed to deal with the +slight variations between different, related models. For example, one model may +have a TPM and another may not. Devicetree provides an excellent solution to +this problem, in that the devicetree to actually use on a platform can be +injected in the factory based on which model is being manufactured at the time.
+A related problem causing build proliferation is dealing with the differences +between development firmware, developer-friendly firmware (e.g. with all +security features present but with the ability to access the command line), +test firmware (which runs tests used in the factory), final production firmware +(before signing), signed firmware (where the signatures have been inserted) and +the like. Ideally all or most of these should use the same U-Boot build, with +just some options to determine the features available. For example, being able +to control whether the UART console or JTAG are available, on any image, is a +great debugging aid.
+When the firmware consists of multiple parts, it is helpful that all operate +the same way at runtime, regardless of how they were built. This can be achieved +by passing the runtime configuration (e.g. 'enable UART console) along the chain +through each firmware stage. It is frustrating to have to replicate a bug on +production firmware which does happen on developer firmware, because they are +completely different builds.
+The /config node provides useful functionality for this. It allows the different +controls to be 'factored out' of the U-Boot binary, so they can be controlled +separately from the initial source-code build. The node can be easily updated by +a build or factory tool and can control various features in U-Boot. It is +similar in concept to a Kconfig option, except that it can be changed after +U-Boot is built.
+The /config node is similar in concept to the `/chosen node`_ except that it is +for passing information *into* firmware instead of from firmware to the +Operating System. Also, while Linux has a (sometimes extremely long) command +line, U-Boot does not support this. The devicetree provides a more structured +approach in any case.
+Devicetree in another project +-----------------------------
+In some cases U-Boot receive its devicetree at runtime from a program that calls +it. For example ARM's Trusted Firmware A (`TF-A`_) may have a devicetree that it +passes to U-Boot. This overrides any devicetree build by U-Boot. When packaging +the firmware, the U-Boot devicetree may in fact be left out if it can be +guaranteed that it will receive one from another project.
+In this case, the devicetree in the other project must track U-Boot's use of +device tree, for the following reasons:
+- U-Boot only has one devicetree. See `Why not have two devicetrees?`_. +- For a consistent firmware build, decisions made in early stages should be
- communicated to later ones at runtime. For example, if the serial console is
- enabled in an early stage, it should be enabled in U-Boot too.
+- U-Boot is quite capable of managing its own copy of the devicetree. If
- another project wants to bypass this (often for good reason), it is reasonable
- that it should take on the (fairly small) requirements that U-Boot features
- that rely on devicetree are still available
+- The point here is not that *U-Boot needs this extra node*, or *U-Boot needs
- to have this public key*. These features are present in U-Boot in service of
- the entire firmware system. If the U-Boot features are used, but cannot be
- supported in the normal way, then there is pressure to implement these
- features in other ways. In the end, we would have a different mechanism for
- every other project that uses U-Boot. This introduces duplicate ways of doing
- the same thing, needlessly increases the complexity of the U-Boot source code,
- forces authors to consider parallel implementations when writing new features,
- makes U-Boot harder to test, complicates documentation and confuses the
- runtime flow of U-Boot. If every board did things its own way rather than
- contributing to the common code, U-Boot would lose a lot of its cross-platform
- value.
+The above does not indicate *bad design* within U-Boot. Devicetree is a core +component of U-Boot and U-Boot makes use of it to the full. It solves a myriad +of problems that would otherwise need their own special C struct, binary format, +special property, tooling for viewing and updating, etc.
+Specifically, the other project must provide a way to add configuration and +other information to the devicetree for use by U-Boot, such as the /config node. +Note that the U-Boot in-tree devicetree source must be sufficient to build and +boot, so this is not a way to bypass that requirement.
+If binman is used, the devicetree source in U-Boot must contain the binman +definition so that a valid image can be build. This helps people discover what +other firmware components are needed and seek out appropriate documentation.
+If verified boot is used, the project must provide a way to inject a public key, +certificate or other material into the U-Boot devicetree so that it is available +to U-Boot at runtime. See `Signing with U-Boot devicetree`_. This may be +through tooling in the project itself or by making use of U-Boot's tooling.
+Devicetree generated on-the-fly in another project +--------------------------------------------------
+In some rare cases, another project may wish to create a devicetree for U-Boot +entirely on-the-fly, then pass it to U-Boot at runtime. The only known example +of this at the time of writing (2021) is QEMU, for ARM (`QEMU ARM`_) and +RISC-V (`QEMU RISC-V`_).
+In effect, when the board boots, U-Boot is *downstream* of the other project. +It is entirely reliant on that project for its correct operation.
+This does not mean to imply that the other project is creating its own, +incompatible devicetree. In fact QEMU generates a valid devicetree which is +suitable for both U-Boot and Linux. It is quite normal for a devicetree to be +present in flash and be made available to U-Boot at runtime. What matters is +where the devicetree comes from. If the other project builds a devicetree for +U-Boot then it needs to support adding the things needed by U-Boot features. +Without them, for example:
+- U-Boot may not boot because too many devices are enabled before relocation +- U-Boot may not have access to the developer or production public keys used for
- signing
+- U-Boot may not support controlling whether the console is enabled +- U-Boot may not be know which MMC device to boot from +- U-Boot may not be able to find other firmware components that it needs to load
+Normally, supporting U-Boot's features is trivial, since the devicetree compiler +(dtc) can compile the source, including any U-Boot pieces. So the burden is +extremely low.
+In this case, the devicetree in the other project must track U-Boot's use of +device tree, so that it remains compatible. See `Devicetree in another project`_ +for reasons why.
+If a particular version of the project is needed for a particular version of +U-Boot, that must be documented in both projects.
+Further, it must provide a way to add configuration and other information to +the devicetree for use by U-Boot, such as the `/config` node and the tags used +by driver model. Note that the U-Boot in-tree devicetree must be sufficient to +build and boot, so this is not a way to bypass that requirement.
+More specifically, tooling or command-line arguments must provide a way to +add a `/config` node or items within that node, so that U-Boot can receive a +suitable configuration. It must provide a way of adding `u-boot,dm-...` tags for +correct operation of driver model. These options can then be used as part of the +build process, which puts the firmware image together. For binman, a way must be +provided to add the binman definition into the devicetree in the same way.
+One way to do this is to allow a .dtsi file to be merged in with the generated +devicetree.
+Note that the burden goes both ways. If a new feature is added to U-Boot which +needs support in another project, then the author of the U-Boot patch must add +any required support to the other project.
+Passing the devicetree through to Linux +---------------------------------------
+Ideally U-Boot and Linux use the same devicetree source, even though it is +hosted in separate projects. U-Boot adds some extra pieces, such as the +`config/` node and tags like `u-boot,dm-spl`. Linux adds some extra pieces, such +as `linux,default-trigger` and `linux,code`. This should not interfere with +each other.
+In principle it is possible for U-Boot's control devicetree to be passed to +Linux. This is, after all, one of the goals of devicetree and the original +Open Firmware project, to have the firmware provide the hardware description to +the Operating System.
+For boards where this approach is used, care must be taken. U-Boot typically +needs to 'fix up' the devicetree before passing it to Linux, e.g. to add +information about the memory map, about which serial console is used, provide +the kernel address space layout randomization (KASLR) seed or select whether the +console should be silenced for a faster boot.
+Fix-ups involve modifying the devicetree. If the control devicetree is used, +that means the control devicetree could be modified, while U-Boot is using it. +Removing a device and reinserting it can cause problems if the devicetree offset +has changed, for example, since the device will be unable to locates its +devicetree properties at the expected devicetree offset, which is a fixed +integer.
+To deal with this, it is recommended to employ one or more of the following +approaches:
+- Make a copy of the devicetree and 'fix up' the copy, leaving the control
- devicetree alone
+- Enable `CONFIG_OF_LIVE` so that U-Boot makes its own copy of the devicetree
- during relocation; fixups then happen on the original flat tree
+- Ensure that fix-ups happen after all loading has happened and U-Boot has
- completed image verification
+In practice,the last point is typically observed, since boot_prep_linux() is +called just before jumping to Linux, long after signature verification, for +example. But it is important to make sure that this line is not blurred, +particularly if untrusted user data is involved.
+Devicetree use cases that must be supported +-------------------------------------------
+Regardless of how the devicetree is provided to U-Boot at runtime, various +U-Boot features must be fully supported. This section describes some of these +features and the implications for other projects.
+If U-Boot uses its own in-tree devicetree these features are supported +automatically.
+Signing with U-Boot devicetree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+U-Boot supports signing a payload so that it can be verified to have been +created by a party owning a private key. This is called verified boot in U-Boot +(see doc/uImage.FIT/verified-boot.txt).
+Typically this works by creating a FIT and then running the `mkimage` tool to +add signatures for particular images. As part of this process, `mkimage` writes +a public key to the U-Boot devicetree, although this can be done separately. +See fdt_add_pubkey_ for patches for a suitable tool, for example.
+As with all configuration information, if another project is providing the +devicetree to U-Boot, it must provide a way to add this public key into the +devicetree it passes to U-Boot. This could be via a tooling option, making use +of `mkimage`, or allowing a .dtsi file to be merged in with what is generated in +the other project.
+Providing the binman image definition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In complex systems U-Boot must locate and make use of other firmware components, +such as images for the user interface, files containing peripheral firmware, +multiple copies of U-Boot for use with A/B boot, etc. U-Boot uses +:doc:`Binman <../package/binman>` as a standard way of putting an image +together.
+Typically this works by running binman with the devicetree as an input, to +create the file image. Binman then outputs an updated devicetree which is +packed in the firmware image, so U-Boot can access the binman definition and +locate all the components.
+As with all configuration information, if another project is providing the +devicetree to U-Boot, it must provide a way to add this binman definition into +the devicetree it passes to U-Boot. This could be via a tooling option, making +use of `binman`, or alowing a .dtsi file to be merged in with what is generated +in the other project.
+Protecting the devicetree +-------------------------
+U-Boot relies heavily on devicetree for correct operation. A corrupt or invalid +device can cause U-Boot to fail to start, behave incorrectly, crash (e.g. if +`CONFIG_OF_LIBFDT_ASSUME_MASK` is adjusted, or fail to boot an Operating System. +Within U-Boot, the devicetree is as important as any other part of the source +code. At ruuntime, the devicetree can be considered to be structured rodata.
+With secure systems, care must be taken that the devicetree is valid:
+- If the code / rodata has a hash or signature, the devicetree should also, if
- they are packaged separately.
+- If the code / rodata is write-protected when running, the devicetree should be
- also. Note that U-Boot relocates its code and devicetree, so this is not as
- simple as it sounds. U-Boot must write-protect these items after relocating.
+Why does U-Boot have its nodes and properties? +----------------------------------------------
+See also :doc:`../devicetree/intro`.
+There has been pushback at the concept that U-Boot dares have its own nodes and +properties in the devicetree.
+Apart from these nodes and properties, U-Boot uses the same bindings as Linux. +A `u-boot.dtsi` file helps to keep U-Boot-specific changes in separate files, +making it easier to keep devicetree source files in U-Boot in sync with Linux.
+As a counter-example, the Zephyr OS project takes a different approach. It uses +entirely different bindings, in general, making no effort to sync devicetree +source files with Linux. U-Boot strives to be compatible with Linux in a number +of ways, such as source code style and common APIs, to aid porting of code +between the projects. Devicetree is another way where U-Boot and Linux follow a +similar approach.
+Fundamentally, the idea that U-Boot cannot have its own tags flies in the face +of the devicetree specification (see dtspec_), which says:
- Nonstandard property names should specify a **unique string prefix**, such as
- a stock ticker symbol, identifying the name of the company **or organization**
- that defined the property. Examples:
- fsl,channel-fifo-len
- ibm,ppc-interrupt-server#s
- **linux**,network-index
+It is also fundamentally unbalanced. Linux has many tags of its own (some 36 in +version 5.13) and at least one Linux-specific node, even if you ignore things +like flash partitions which clearly provide configuration information to Linux.
+Practically speaking there are many reasons why U-Boot has its own nodes and +properties. Some examples:
+- Binding every device before relocation even if it won't be used, consumes time
- and memory: tags on each node can specify which are needed in SPL or before
- relocation. Linux has no such constraints.
+- Requiring the full clock tree to be up and running just to get the debug UART
- running is inefficient. It is also and self-defeating, since if that much
- code is working properly, you probably don't need the debug UART. A devicetree
- property to provide the UART input-clock frequency is a simple solution.
+- U-Boot does not have a user space to provide policy and configuration. It
- cannot do what Linux does and run programs and look up filesystems to figure
- out how to boot.
+Why not have two devicetrees? +-----------------------------
+Setting aside the argument for restricting U-Boot from having its own nodes and +properties, another idea proposed is to have two devicetrees, one for the +U-Boot-specific bits (here called `special`) and one for everything else (here +called `linux`). This would mean that U-Boot would be controlled by two +devicetrees, i.e. OF_CONTROL would require/allow two devicetrees in order to +work.
+On the positive side, it might quieten the discussion alluded to in the section +above. But there are many negatives to consider and many open questions to +resolve.
+- **Bindings** - Presumably the special devicetree would have its own bindings.
- It would not be necessary to put a `u-boot,` prefix on anything. People coming
- across the devicetree source would wonder how it fits in with the Linux
- devicetree.
+- **Access** - U-Boot has a nice `ofnode` API for accessing the devicetree. This
- would need to be expanded to support two trees. Features which need to access
- both (such as a device driver which reads the special devicetree to get some
- configuration info) could become quite confusing to read and write.
+- **Merging** - Can the two devicetree be merged if a platform desires it? If
- so, how is this managed in tooling? Does it happen during the build, in which
- case they are not really separate at all. Or does U-Boot merge them at
- runtime, in which case this adds time and memory?
+- **Efficiency** - A second device tree adds more code and more code paths. It
- requires that both be made available to the code in U-Boot, e.g. via a
- separate pointer or argument or API. Overall the separation would certainly
- not speed up U-Boot, nor decrease its size.
+- **Source code** - At present `u-boot.dtsi` files provide the pieces needed for
- U-Boot for a particular board. Would we use these same files for the special
- devicetree?
+- **Complexity** - Two devicetrees complicates the build system since it must
- build and package them both. Errors must be reported in such a way that it
- is obvious which one is failing.
+- **Referencing each other** - The `u-boot,dm-xxx` tags used by driver model
- are currently placed in the nodes they relate to. How would these tags
- reference a node that is in a separate devicetree? What extra validation would
- be needed?
+- **Storage** - How would the two devicetrees be stored in the image? At present
- we simply concatenate the U-Boot binary and the devicetree. We could add the
- special devicetree before the Linux one, so two are concatenated, but it is
- not pretty. We could use binman to support more complex arrangements, but only
- some boards use this at present, so it would be a big change.
+- **API** - How would another project provide two devicetree files to U-Boot at
- runtime? Presumably this would just be too painful. But if it doesn't, it
- would be unable to configure run-time features of U-Boot during the boot.
+- **Confusion** - No other project has two devicetrees used for controlling its
- operation (although having multiple devicetrees to pass on to the OS is
- common). U-Boot would be in the unfortunate position of having to describe
- the purpose of the two control devicetrees fact to new users, along with the
- (arguably contrived) reason for the arrangement.
+- **Signing flow** - The current signing flow is simple as it involves running
- `mkimage` with the U-Boot devicetree. This would have to be updated to use the
- special devicetree. Some way of telling the user that they have done it wrong
- would have to be invented.
+Overall, adding a second devicetree would create enormous confusion and +complexity. It seems a lot cheaper to solve this by a change of attitude.
+.. _rpi_patch: https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-deym... +.. _`TF-A`: https://www.trustedfirmware.org/projects/tf-a +.. _`QEMU ARM`: https://github.com/qemu/qemu/blob/master/hw/arm/virt.c +.. _`QEMU RISC-V`: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c +.. _`/chosen node`: https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt +.. _fdt_add_pubkey: https://patchwork.ozlabs.org/project/uboot/list/?series=157843&state=* +.. _dtspec: https://www.devicetree.org/specifications/ diff --git a/doc/develop/devicetree/index.rst b/doc/develop/devicetree/index.rst index fa5db3eb76e..b5b33dfea0f 100644 --- a/doc/develop/devicetree/index.rst +++ b/doc/develop/devicetree/index.rst @@ -11,3 +11,4 @@ build-time and runtime configuration.
intro control
- dt_update

Hi Heinrich,
On Mon, 6 Dec 2021 at 17:58, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/6/21 16:11, Simon Glass wrote:
At present some of the ideas and techniques behind devicetree in U-Boot are assumed, implied or unsaid. Add some documentation to cover how devicetree is build, how it can be modified and the rules about using the various CONFIG_OF_... options.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marcel Ziswiler marcel.ziswiler@toradex.com
This patch attracted quite a bit of discussion here:
https://patchwork.ozlabs.org/project/uboot/patch/20210909201033.755713-4-sjg...
I have not included the text suggested by François. While I agree that it would be useful to have an introduction in this space, I do not agree that we should have two devicetrees or that U-Boot should not have its own things in the devicetree, so it is not clear to me what we should actually write.
The 'Devicetree Control in U-Boot' docs were recently merged and these provide some base info, for now.
As you already remarked part of this text has not been agreed upon.
Please, either remove this part of the text or mark it as your private opinion.
Do you mean the comment after the patch? It won't appear in the commit message.
Regards, SImon
Best regards
Heinrich
Changes in v7:
- Fix 'linst' typo
Changes in v6:
- Fix description of OF_BOARD so it refers just to the current state
- Explain that the 'two devicetrees' refers to two *control* devicetrees
Changes in v5:
- Bring into the OF_BOARD series
- Rebase to master and drop mention of OF_PRIOR_STAGE, since removed
- Refer to the 'control' DTB in the first paragraph
- Use QEMU instead of qemu
Changes in v3:
- Clarify the 'bug' refered to at the top
- Reword 'This means that there' paragraph to explain U-Boot-specific things
- Move to doc/develop/devicetree now that OF_CONTROL is in the docs
Changes in v2:
Fix typos per Sean (thank you!) and a few others
Add a 'Use of U-Boot /config node' section
Drop mention of dm-verity since that actually uses the kernel cmdline
Explain that OF_BOARD will still work after these changes (in 'Once this bug is fixed...' paragraph)
Expand a bit on the reason why the 'Current situation' is bad
Clarify in a second place that Linux and U-Boot use the same devicetree in 'To be clear, while U-Boot...'
Expand on why we should have rules for other projects in 'Devicetree in another project'
Add a comment as to why devicetree in U-Boot is not 'bad design'
Reword 'in-tree U-Boot devicetree' to 'devicetree source in U-Boot'
Rewrite 'Devicetree generated on-the-fly in another project' to cover points raised on v1
Add 'Why does U-Boot have its nodes and properties?'
Add 'Why not have two devicetrees?'
doc/develop/devicetree/dt_update.rst | 555 +++++++++++++++++++++++++++ doc/develop/devicetree/index.rst | 1 + 2 files changed, 556 insertions(+) create mode 100644 doc/develop/devicetree/dt_update.rst
diff --git a/doc/develop/devicetree/dt_update.rst b/doc/develop/devicetree/dt_update.rst new file mode 100644 index 00000000000..e3b65f6fa66 --- /dev/null +++ b/doc/develop/devicetree/dt_update.rst @@ -0,0 +1,555 @@ +.. SPDX-License-Identifier: GPL-2.0+
+Updating the devicetree +=======================
+U-Boot uses devicetree for runtime configuration and storing required blobs or +any other information it needs to operate. This is called the 'control' +devicetree since it controls U-Boot. It is possible to update the control +devicetree separately from actually building U-Boot. This provides a good degree +of control and flexibility for firmware that uses U-Boot in conjunction with +other project.
+There are many reasons why it is useful to modify the devicetree after building +it:
+- Configuration can be changed, e.g. which UART to use +- A serial number can be added +- Public keys can be added to allow image verification +- Console output can be changed (e.g. to select serial or vidconsole)
+This section describes how to work with devicetree to accomplish your goals.
+See also :doc:`../devicetree/control` for a basic summary of the available +features.
+Devicetree source +-----------------
+Every board in U-Boot must include a devicetree sufficient to build and boot +that board on suitable hardware (or emulation). This is specified using the +`CONFIG DEFAULT_DEVICE_TREE` option.
+Current situation (October 2021) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As an aside, at present U-Boot allows `CONFIG_DEFAULT_DEVICE_TREE` to be empty, +e.g. if `CONFIG_OF_BOARD` is used. This has unfortunately created an enormous +amount of confusion and some wasted effort. This was not intended. Support for +an empty `CONFIG_DEFAULT_DEVICE_TREE` will be dropped soon.
+Some of the problems created are:
+- It is not obvious that the devicetree is coming from another project
+- There is no way to see even a sample devicetree for these platform in U-Boot,
- so it is hard to know what is going on, e.g. which devices are typically
- present
+- The other project may not provide a way to support U-Boot's requirements for
- devicetree, such as the /config node. Note: On the U-Boot mailing list, this
- was only discovered after weeks of discussion and confusion
+- For QEMU specifically, consulting two QEMU source files is required, for which
- there are no references in U-Boot documentation. The code is generating a
- devicetree, but it is not clear what controls affect this generation.
+Specifically on the changes in U-Bootm `CONFIG_OF_BOARD` was added in +rpi_patch_ for Raspberry Pi, which does have an in-tree devicetree, but this +feature has since been used for boards that don't
+Once this bug is fixed, CONFIG_OF_BOARD will override (at runtime) the +evicetree suppled with U-Boot, but will otherwise use CONFIG_OF_SEPARATE for the +in-tree build. So these two will become options, moving out of the 'choice' in +`dts/Kconfig`.
+This means that there is a basic devicetree build in the U-Boot tree, for +build-testing, consistency and documentation purposes, but at runtime U-Boot can +accept its devicetree from another source. The in-tree devicetree may contain +U-Boot-specific features (in u-boot*.dtsi files) and this may prove useful for +the other project, so it can ensure that U-Boot functions correctly and supports +all its expected features.
+To be clear, while U-Boot has its own copy of the devicetree source for each +board, this must match the Linux source, perhaps with some u-boot.dtsi +additions. The intent here is not to create a separate binding, just to provide +a representative devicetree in U-Boot.
+Offending boards are:
+- rpi_4 and rpi_4_32b (other rpi boards do have an in-tree devicetree) +- qemu_arm64 +- qemu_arm +- qemu-ppce500 +- qemu-riscv32 +- qemu-riscv32_smode +- qemu-riscv64 +- qemu-riscv64_smode
+All of these need to have a devicetree added in-tree. This is targeted to be +fixed in the 2022.01 release.
+Building the devicetree +-----------------------
+U-Boot automatically builds the devicetree for a board, from the +`arch/<arch>/dts` directory. The Makefile in those directories has rules for +building devicetree files. It is preferable to avoid target-specific rules in +those files: i.e. all boards for a particular SoC should be built at once, +where practical. Apart from simplifying the Makefile, this helps to efficiently +(and immediately) ensure that changes in one board's DT do not break others that +are related. Building devicetrees is fast, so performance is seldom a concern +here.
+Overriding the default devicetree +---------------------------------
+When building U-Boot, the `DEVICE_TREE` environment variable allows the +default devicetree file to be overridden at build time. This can be useful if +modifications have to be made to the in-tree devicetree file, for the benefit +of a downstream build system. Note that the in-tree devicetree must be +sufficient to build and boot, so this is not a way to bypass that requirement.
+Modifying the devicetree after building +---------------------------------------
+While it is generally painful and hacky to modify the code or rodata of a +program after it is built, in many cases it is useful to do so, e.g. to add +configuration information like serial numbers, enabling/disabling features, etc.
+Devicetree provides a very nice solution to these problems since it is +structured data and it is relatively easy to change it, even in binary form +(see fdtput).
+U-Boot takes care that the devicetree is easily accessible after the build +process. In fact it is placed in a separate file called `u-boot.dtb`. If the +build system wants to modify or replace that file, it can do so. Then all that +is needed is to run `binman update` to update the file inside the image. If +binman is not used, then `u-boot-nodtb.bin` and the new `u-boot.dtb` can simply +be concatenated to achieve the desired result. U-Boot happily copes with the +devicetree growing or shrinking.
+The `u-boot.bin` image contains both pieces. While it is possible to locate the +devicetree within the image using the signature at the start of the file, this +is a bit messy.
+This is why `CONFIG_OF_SEPARATE` should always be used when building U-Boot. +The `CONFIG_OF_EMBED` option embeds the devicetree somewhere in the U-Boot ELF +image as rodata, meaning that it is hard to find it and it cannot increase in +size.
+When modifying the devicetree, the different cases to consider are as follows:
+- CONFIG_OF_SEPARATE
- This is easy, described above. Just change, replace or rebuild the
- devicetree so it suits your needs, then rerun binman or redo the `cat`
- operation to join `u-boot-nodtb.bin` and the new `u-boot.dtb`
+- CONFIG_OF_EMBED
- This is tricky, since the devicetree cannot easily be located. If the EFL
- file is available, then the _dtb_dt_begin and __dtb_dt_end symbols can be
- examined to find it. While it is possible to contract the file, it is not
- possible to expand the file since that would involve re-linking
+- CONFIG_OF_BOARD
- This is a board-specific situation, so needs to be considered on a
- case-by-case base.
+Use of U-Boot /config node +--------------------------
+A common problem with firmware is that many builds are needed to deal with the +slight variations between different, related models. For example, one model may +have a TPM and another may not. Devicetree provides an excellent solution to +this problem, in that the devicetree to actually use on a platform can be +injected in the factory based on which model is being manufactured at the time.
+A related problem causing build proliferation is dealing with the differences +between development firmware, developer-friendly firmware (e.g. with all +security features present but with the ability to access the command line), +test firmware (which runs tests used in the factory), final production firmware +(before signing), signed firmware (where the signatures have been inserted) and +the like. Ideally all or most of these should use the same U-Boot build, with +just some options to determine the features available. For example, being able +to control whether the UART console or JTAG are available, on any image, is a +great debugging aid.
+When the firmware consists of multiple parts, it is helpful that all operate +the same way at runtime, regardless of how they were built. This can be achieved +by passing the runtime configuration (e.g. 'enable UART console) along the chain +through each firmware stage. It is frustrating to have to replicate a bug on +production firmware which does happen on developer firmware, because they are +completely different builds.
+The /config node provides useful functionality for this. It allows the different +controls to be 'factored out' of the U-Boot binary, so they can be controlled +separately from the initial source-code build. The node can be easily updated by +a build or factory tool and can control various features in U-Boot. It is +similar in concept to a Kconfig option, except that it can be changed after +U-Boot is built.
+The /config node is similar in concept to the `/chosen node`_ except that it is +for passing information *into* firmware instead of from firmware to the +Operating System. Also, while Linux has a (sometimes extremely long) command +line, U-Boot does not support this. The devicetree provides a more structured +approach in any case.
+Devicetree in another project +-----------------------------
+In some cases U-Boot receive its devicetree at runtime from a program that calls +it. For example ARM's Trusted Firmware A (`TF-A`_) may have a devicetree that it +passes to U-Boot. This overrides any devicetree build by U-Boot. When packaging +the firmware, the U-Boot devicetree may in fact be left out if it can be +guaranteed that it will receive one from another project.
+In this case, the devicetree in the other project must track U-Boot's use of +device tree, for the following reasons:
+- U-Boot only has one devicetree. See `Why not have two devicetrees?`_. +- For a consistent firmware build, decisions made in early stages should be
- communicated to later ones at runtime. For example, if the serial console is
- enabled in an early stage, it should be enabled in U-Boot too.
+- U-Boot is quite capable of managing its own copy of the devicetree. If
- another project wants to bypass this (often for good reason), it is reasonable
- that it should take on the (fairly small) requirements that U-Boot features
- that rely on devicetree are still available
+- The point here is not that *U-Boot needs this extra node*, or *U-Boot needs
- to have this public key*. These features are present in U-Boot in service of
- the entire firmware system. If the U-Boot features are used, but cannot be
- supported in the normal way, then there is pressure to implement these
- features in other ways. In the end, we would have a different mechanism for
- every other project that uses U-Boot. This introduces duplicate ways of doing
- the same thing, needlessly increases the complexity of the U-Boot source code,
- forces authors to consider parallel implementations when writing new features,
- makes U-Boot harder to test, complicates documentation and confuses the
- runtime flow of U-Boot. If every board did things its own way rather than
- contributing to the common code, U-Boot would lose a lot of its cross-platform
- value.
+The above does not indicate *bad design* within U-Boot. Devicetree is a core +component of U-Boot and U-Boot makes use of it to the full. It solves a myriad +of problems that would otherwise need their own special C struct, binary format, +special property, tooling for viewing and updating, etc.
+Specifically, the other project must provide a way to add configuration and +other information to the devicetree for use by U-Boot, such as the /config node. +Note that the U-Boot in-tree devicetree source must be sufficient to build and +boot, so this is not a way to bypass that requirement.
+If binman is used, the devicetree source in U-Boot must contain the binman +definition so that a valid image can be build. This helps people discover what +other firmware components are needed and seek out appropriate documentation.
+If verified boot is used, the project must provide a way to inject a public key, +certificate or other material into the U-Boot devicetree so that it is available +to U-Boot at runtime. See `Signing with U-Boot devicetree`_. This may be +through tooling in the project itself or by making use of U-Boot's tooling.
+Devicetree generated on-the-fly in another project +--------------------------------------------------
+In some rare cases, another project may wish to create a devicetree for U-Boot +entirely on-the-fly, then pass it to U-Boot at runtime. The only known example +of this at the time of writing (2021) is QEMU, for ARM (`QEMU ARM`_) and +RISC-V (`QEMU RISC-V`_).
+In effect, when the board boots, U-Boot is *downstream* of the other project. +It is entirely reliant on that project for its correct operation.
+This does not mean to imply that the other project is creating its own, +incompatible devicetree. In fact QEMU generates a valid devicetree which is +suitable for both U-Boot and Linux. It is quite normal for a devicetree to be +present in flash and be made available to U-Boot at runtime. What matters is +where the devicetree comes from. If the other project builds a devicetree for +U-Boot then it needs to support adding the things needed by U-Boot features. +Without them, for example:
+- U-Boot may not boot because too many devices are enabled before relocation +- U-Boot may not have access to the developer or production public keys used for
- signing
+- U-Boot may not support controlling whether the console is enabled +- U-Boot may not be know which MMC device to boot from +- U-Boot may not be able to find other firmware components that it needs to load
+Normally, supporting U-Boot's features is trivial, since the devicetree compiler +(dtc) can compile the source, including any U-Boot pieces. So the burden is +extremely low.
+In this case, the devicetree in the other project must track U-Boot's use of +device tree, so that it remains compatible. See `Devicetree in another project`_ +for reasons why.
+If a particular version of the project is needed for a particular version of +U-Boot, that must be documented in both projects.
+Further, it must provide a way to add configuration and other information to +the devicetree for use by U-Boot, such as the `/config` node and the tags used +by driver model. Note that the U-Boot in-tree devicetree must be sufficient to +build and boot, so this is not a way to bypass that requirement.
+More specifically, tooling or command-line arguments must provide a way to +add a `/config` node or items within that node, so that U-Boot can receive a +suitable configuration. It must provide a way of adding `u-boot,dm-...` tags for +correct operation of driver model. These options can then be used as part of the +build process, which puts the firmware image together. For binman, a way must be +provided to add the binman definition into the devicetree in the same way.
+One way to do this is to allow a .dtsi file to be merged in with the generated +devicetree.
+Note that the burden goes both ways. If a new feature is added to U-Boot which +needs support in another project, then the author of the U-Boot patch must add +any required support to the other project.
+Passing the devicetree through to Linux +---------------------------------------
+Ideally U-Boot and Linux use the same devicetree source, even though it is +hosted in separate projects. U-Boot adds some extra pieces, such as the +`config/` node and tags like `u-boot,dm-spl`. Linux adds some extra pieces, such +as `linux,default-trigger` and `linux,code`. This should not interfere with +each other.
+In principle it is possible for U-Boot's control devicetree to be passed to +Linux. This is, after all, one of the goals of devicetree and the original +Open Firmware project, to have the firmware provide the hardware description to +the Operating System.
+For boards where this approach is used, care must be taken. U-Boot typically +needs to 'fix up' the devicetree before passing it to Linux, e.g. to add +information about the memory map, about which serial console is used, provide +the kernel address space layout randomization (KASLR) seed or select whether the +console should be silenced for a faster boot.
+Fix-ups involve modifying the devicetree. If the control devicetree is used, +that means the control devicetree could be modified, while U-Boot is using it. +Removing a device and reinserting it can cause problems if the devicetree offset +has changed, for example, since the device will be unable to locates its +devicetree properties at the expected devicetree offset, which is a fixed +integer.
+To deal with this, it is recommended to employ one or more of the following +approaches:
+- Make a copy of the devicetree and 'fix up' the copy, leaving the control
- devicetree alone
+- Enable `CONFIG_OF_LIVE` so that U-Boot makes its own copy of the devicetree
- during relocation; fixups then happen on the original flat tree
+- Ensure that fix-ups happen after all loading has happened and U-Boot has
- completed image verification
+In practice,the last point is typically observed, since boot_prep_linux() is +called just before jumping to Linux, long after signature verification, for +example. But it is important to make sure that this line is not blurred, +particularly if untrusted user data is involved.
+Devicetree use cases that must be supported +-------------------------------------------
+Regardless of how the devicetree is provided to U-Boot at runtime, various +U-Boot features must be fully supported. This section describes some of these +features and the implications for other projects.
+If U-Boot uses its own in-tree devicetree these features are supported +automatically.
+Signing with U-Boot devicetree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+U-Boot supports signing a payload so that it can be verified to have been +created by a party owning a private key. This is called verified boot in U-Boot +(see doc/uImage.FIT/verified-boot.txt).
+Typically this works by creating a FIT and then running the `mkimage` tool to +add signatures for particular images. As part of this process, `mkimage` writes +a public key to the U-Boot devicetree, although this can be done separately. +See fdt_add_pubkey_ for patches for a suitable tool, for example.
+As with all configuration information, if another project is providing the +devicetree to U-Boot, it must provide a way to add this public key into the +devicetree it passes to U-Boot. This could be via a tooling option, making use +of `mkimage`, or allowing a .dtsi file to be merged in with what is generated in +the other project.
+Providing the binman image definition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In complex systems U-Boot must locate and make use of other firmware components, +such as images for the user interface, files containing peripheral firmware, +multiple copies of U-Boot for use with A/B boot, etc. U-Boot uses +:doc:`Binman <../package/binman>` as a standard way of putting an image +together.
+Typically this works by running binman with the devicetree as an input, to +create the file image. Binman then outputs an updated devicetree which is +packed in the firmware image, so U-Boot can access the binman definition and +locate all the components.
+As with all configuration information, if another project is providing the +devicetree to U-Boot, it must provide a way to add this binman definition into +the devicetree it passes to U-Boot. This could be via a tooling option, making +use of `binman`, or alowing a .dtsi file to be merged in with what is generated +in the other project.
+Protecting the devicetree +-------------------------
+U-Boot relies heavily on devicetree for correct operation. A corrupt or invalid +device can cause U-Boot to fail to start, behave incorrectly, crash (e.g. if +`CONFIG_OF_LIBFDT_ASSUME_MASK` is adjusted, or fail to boot an Operating System. +Within U-Boot, the devicetree is as important as any other part of the source +code. At ruuntime, the devicetree can be considered to be structured rodata.
+With secure systems, care must be taken that the devicetree is valid:
+- If the code / rodata has a hash or signature, the devicetree should also, if
- they are packaged separately.
+- If the code / rodata is write-protected when running, the devicetree should be
- also. Note that U-Boot relocates its code and devicetree, so this is not as
- simple as it sounds. U-Boot must write-protect these items after relocating.
+Why does U-Boot have its nodes and properties? +----------------------------------------------
+See also :doc:`../devicetree/intro`.
+There has been pushback at the concept that U-Boot dares have its own nodes and +properties in the devicetree.
+Apart from these nodes and properties, U-Boot uses the same bindings as Linux. +A `u-boot.dtsi` file helps to keep U-Boot-specific changes in separate files, +making it easier to keep devicetree source files in U-Boot in sync with Linux.
+As a counter-example, the Zephyr OS project takes a different approach. It uses +entirely different bindings, in general, making no effort to sync devicetree +source files with Linux. U-Boot strives to be compatible with Linux in a number +of ways, such as source code style and common APIs, to aid porting of code +between the projects. Devicetree is another way where U-Boot and Linux follow a +similar approach.
+Fundamentally, the idea that U-Boot cannot have its own tags flies in the face +of the devicetree specification (see dtspec_), which says:
- Nonstandard property names should specify a **unique string prefix**, such as
- a stock ticker symbol, identifying the name of the company **or organization**
- that defined the property. Examples:
- fsl,channel-fifo-len
- ibm,ppc-interrupt-server#s
- **linux**,network-index
+It is also fundamentally unbalanced. Linux has many tags of its own (some 36 in +version 5.13) and at least one Linux-specific node, even if you ignore things +like flash partitions which clearly provide configuration information to Linux.
+Practically speaking there are many reasons why U-Boot has its own nodes and +properties. Some examples:
+- Binding every device before relocation even if it won't be used, consumes time
- and memory: tags on each node can specify which are needed in SPL or before
- relocation. Linux has no such constraints.
+- Requiring the full clock tree to be up and running just to get the debug UART
- running is inefficient. It is also and self-defeating, since if that much
- code is working properly, you probably don't need the debug UART. A devicetree
- property to provide the UART input-clock frequency is a simple solution.
+- U-Boot does not have a user space to provide policy and configuration. It
- cannot do what Linux does and run programs and look up filesystems to figure
- out how to boot.
+Why not have two devicetrees? +-----------------------------
+Setting aside the argument for restricting U-Boot from having its own nodes and +properties, another idea proposed is to have two devicetrees, one for the +U-Boot-specific bits (here called `special`) and one for everything else (here +called `linux`). This would mean that U-Boot would be controlled by two +devicetrees, i.e. OF_CONTROL would require/allow two devicetrees in order to +work.
+On the positive side, it might quieten the discussion alluded to in the section +above. But there are many negatives to consider and many open questions to +resolve.
+- **Bindings** - Presumably the special devicetree would have its own bindings.
- It would not be necessary to put a `u-boot,` prefix on anything. People coming
- across the devicetree source would wonder how it fits in with the Linux
- devicetree.
+- **Access** - U-Boot has a nice `ofnode` API for accessing the devicetree. This
- would need to be expanded to support two trees. Features which need to access
- both (such as a device driver which reads the special devicetree to get some
- configuration info) could become quite confusing to read and write.
+- **Merging** - Can the two devicetree be merged if a platform desires it? If
- so, how is this managed in tooling? Does it happen during the build, in which
- case they are not really separate at all. Or does U-Boot merge them at
- runtime, in which case this adds time and memory?
+- **Efficiency** - A second device tree adds more code and more code paths. It
- requires that both be made available to the code in U-Boot, e.g. via a
- separate pointer or argument or API. Overall the separation would certainly
- not speed up U-Boot, nor decrease its size.
+- **Source code** - At present `u-boot.dtsi` files provide the pieces needed for
- U-Boot for a particular board. Would we use these same files for the special
- devicetree?
+- **Complexity** - Two devicetrees complicates the build system since it must
- build and package them both. Errors must be reported in such a way that it
- is obvious which one is failing.
+- **Referencing each other** - The `u-boot,dm-xxx` tags used by driver model
- are currently placed in the nodes they relate to. How would these tags
- reference a node that is in a separate devicetree? What extra validation would
- be needed?
+- **Storage** - How would the two devicetrees be stored in the image? At present
- we simply concatenate the U-Boot binary and the devicetree. We could add the
- special devicetree before the Linux one, so two are concatenated, but it is
- not pretty. We could use binman to support more complex arrangements, but only
- some boards use this at present, so it would be a big change.
+- **API** - How would another project provide two devicetree files to U-Boot at
- runtime? Presumably this would just be too painful. But if it doesn't, it
- would be unable to configure run-time features of U-Boot during the boot.
+- **Confusion** - No other project has two devicetrees used for controlling its
- operation (although having multiple devicetrees to pass on to the OS is
- common). U-Boot would be in the unfortunate position of having to describe
- the purpose of the two control devicetrees fact to new users, along with the
- (arguably contrived) reason for the arrangement.
+- **Signing flow** - The current signing flow is simple as it involves running
- `mkimage` with the U-Boot devicetree. This would have to be updated to use the
- special devicetree. Some way of telling the user that they have done it wrong
- would have to be invented.
+Overall, adding a second devicetree would create enormous confusion and +complexity. It seems a lot cheaper to solve this by a change of attitude.
+.. _rpi_patch: https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-deym... +.. _`TF-A`: https://www.trustedfirmware.org/projects/tf-a +.. _`QEMU ARM`: https://github.com/qemu/qemu/blob/master/hw/arm/virt.c +.. _`QEMU RISC-V`: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c +.. _`/chosen node`: https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt +.. _fdt_add_pubkey: https://patchwork.ozlabs.org/project/uboot/list/?series=157843&state=* +.. _dtspec: https://www.devicetree.org/specifications/ diff --git a/doc/develop/devicetree/index.rst b/doc/develop/devicetree/index.rst index fa5db3eb76e..b5b33dfea0f 100644 --- a/doc/develop/devicetree/index.rst +++ b/doc/develop/devicetree/index.rst @@ -11,3 +11,4 @@ build-time and runtime configuration.
intro control
- dt_update

On Tue, Dec 07, 2021 at 08:09:03AM -0700, Simon Glass wrote:
Hi Heinrich,
On Mon, 6 Dec 2021 at 17:58, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/6/21 16:11, Simon Glass wrote:
At present some of the ideas and techniques behind devicetree in U-Boot are assumed, implied or unsaid. Add some documentation to cover how devicetree is build, how it can be modified and the rules about using the various CONFIG_OF_... options.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marcel Ziswiler marcel.ziswiler@toradex.com
This patch attracted quite a bit of discussion here:
https://patchwork.ozlabs.org/project/uboot/patch/20210909201033.755713-4-sjg...
I have not included the text suggested by François. While I agree that it would be useful to have an introduction in this space, I do not agree that we should have two devicetrees or that U-Boot should not have its own things in the devicetree, so it is not clear to me what we should actually write.
The 'Devicetree Control in U-Boot' docs were recently merged and these provide some base info, for now.
As you already remarked part of this text has not been agreed upon.
Please, either remove this part of the text or mark it as your private opinion.
Do you mean the comment after the patch? It won't appear in the commit message.
I believe he's referring to that section of the document itself, which is still not agreed on / to.

On Mon, Dec 06, 2021 at 05:11:39PM -0700, Simon Glass wrote:
[snip]
+Updating the devicetree +=======================
The first thing here is that the subject says dt usage, but the file is dt_update and starts out talking about updates, not usage. So there's not a great place for my next comment, in reply to this patch. The second thing is I've already gotten one novel written so far, and I've got more comments on the rest of the document, so I'm splitting this reply up.
What this seems to miss it that the intention of device tree usage in U-Boot is similar to the usage of device trees in an OS. That is to allow for the run-time binary to be data-driven and determine what peripherals or even SoC is present at run-time rather than build time. A sufficiently abstracted build can support not just rev A vs rev B of a given hardware platform but platform A and platform B using the same SoC but different designs and peripherals or platform A and platform C where there are different SoCs present entirely.
+U-Boot uses devicetree for runtime configuration and storing required blobs or +any other information it needs to operate. This is called the 'control' +devicetree since it controls U-Boot. It is possible to update the control +devicetree separately from actually building U-Boot. This provides a good degree +of control and flexibility for firmware that uses U-Boot in conjunction with +other project.
+There are many reasons why it is useful to modify the devicetree after building +it:
+- Configuration can be changed, e.g. which UART to use +- A serial number can be added +- Public keys can be added to allow image verification +- Console output can be changed (e.g. to select serial or vidconsole)
+This section describes how to work with devicetree to accomplish your goals.
+See also :doc:`../devicetree/control` for a basic summary of the available +features.
This implies that the control device tree is separate from the OS device tree. You certainly can't put "blobs" in to the device tree that will be in the upstream dts repository. So this needs to be clarified / expanded more to be clear we aren't talking about the OS device tree but rather we're using the device tree format to define what we're making as an output, with binman, and spell out binman, and probably link to those docs too.
+Devicetree source +-----------------
+Every board in U-Boot must include a devicetree sufficient to build and boot +that board on suitable hardware (or emulation). This is specified using the +`CONFIG DEFAULT_DEVICE_TREE` option.
No, this is wrong. As has been explained over and over, a device tree that can _boot_ the hardware is not always statically possible. I'll go further and note that in the cases where you cannot do this, you _need_ to do what the platform specific method of modifying the device tree is, in order to do that, in order to test things. But this really feels like making the doorway to later on say "Now we can have U-Boot override the device tree for everyone" rather than just developer developing and testing things locally.
+Current situation (October 2021) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As an aside, at present U-Boot allows `CONFIG_DEFAULT_DEVICE_TREE` to be empty, +e.g. if `CONFIG_OF_BOARD` is used. This has unfortunately created an enormous +amount of confusion and some wasted effort. This was not intended. Support for +an empty `CONFIG_DEFAULT_DEVICE_TREE` will be dropped soon.
It's intentional and required. When you support more than one distinct SoC and a prior stage that takes care of enough low level configuration that, just like an OS, U-Boot can be data-driven rather than hard-coded, it is NOT possible to include a default that will work for everyone. So it doesn't make sense to include a default that will fail for some.
+Some of the problems created are:
+- It is not obvious that the devicetree is coming from another project
+- There is no way to see even a sample devicetree for these platform in U-Boot,
- so it is hard to know what is going on, e.g. which devices are typically
- present
Board documentation has been sporadic at best historically but thanks to Heinrich and others, we've seen huge improvements more recently. Getting information such as this included would make life easier.
+- The other project may not provide a way to support U-Boot's requirements for
- devicetree, such as the /config node. Note: On the U-Boot mailing list, this
- was only discovered after weeks of discussion and confusion
In that there is a problem there it's because we need to document the binding (which yes, you're doing and it's time to push again on Rob about) and then it's on the board to update their device tree. Not on U-Boot to provide this information.
+- For QEMU specifically, consulting two QEMU source files is required, for which
- there are no references in U-Boot documentation. The code is generating a
- devicetree, but it is not clear what controls affect this generation.
QEMU generates a device tree, we consume the device tree. Device trees are generated against the bindings. If a property needs to be present, it needs to be in the bindings. If a board won't populate the binding, it won't get the feature supported.
+Specifically on the changes in U-Bootm `CONFIG_OF_BOARD` was added in +rpi_patch_ for Raspberry Pi, which does have an in-tree devicetree, but this +feature has since been used for boards that don't
Yes, historically there's been some funny stuff with Pi and unfortunately we've not handled things as best as could be. We really should just have rpi_arm64 and see if we can do an rpi_arm32, both of which rely on the provided device tree.
+Once this bug is fixed, CONFIG_OF_BOARD will override (at runtime) the +evicetree suppled with U-Boot, but will otherwise use CONFIG_OF_SEPARATE for the +in-tree build. So these two will become options, moving out of the 'choice' in +`dts/Kconfig`.
+This means that there is a basic devicetree build in the U-Boot tree, for +build-testing, consistency and documentation purposes, but at runtime U-Boot can
No. We already accept that for build-testing binaries won't be functional. There's huge swaths of the codebase today that print some form of "this builds but will not run". Device trees aren't an exception to that. For documentation purposes, boards should have more extensive documentation than they do today and can / should point to where their device trees come from as part of that. Or at least point to their documentation that covers such topics.
+accept its devicetree from another source. The in-tree devicetree may contain +U-Boot-specific features (in u-boot*.dtsi files) and this may prove useful for +the other project, so it can ensure that U-Boot functions correctly and supports +all its expected features.
Frankly, I think I made a mistake with -u-boot.dtsi as it let us go for too long without getting our bindings upstream, so we got very far down the road of requiring properties that would only be present in our generated device tree. This was really only noticeable as a problem on Pi where we kept having to do things to deal with "provided device tree got updated, we need to something-something to keep working / not break the OS now".
+To be clear, while U-Boot has its own copy of the devicetree source for each +board, this must match the Linux source, perhaps with some u-boot.dtsi +additions. The intent here is not to create a separate binding, just to provide +a representative devicetree in U-Boot.
In that it can be helpful to not have to swap to another project to look at files, and that I'm sure "git submodules" is out of the question for us, we would first need to re-organize our device tree structure so that it's a clear import of Linux's arch/${ARCH}/boot/dts -> something/${ARCH}/dts in U-Boot, and deal with ARMv8+ here being under ARCH=arm but ARCH=arm64 in Linux. That would not be where any -u-boot.dtsi files live.
But I don't see it as our role to try and be where all the device trees that want to live somewhere public live. There's another projects and people trying to sort that out, for quite some time.

On Mon, Dec 06, 2021 at 05:11:39PM -0700, Simon Glass wrote:
[snip]
+Building the devicetree +-----------------------
+U-Boot automatically builds the devicetree for a board, from the +`arch/<arch>/dts` directory. The Makefile in those directories has rules for +building devicetree files. It is preferable to avoid target-specific rules in +those files: i.e. all boards for a particular SoC should be built at once, +where practical. Apart from simplifying the Makefile, this helps to efficiently +(and immediately) ensure that changes in one board's DT do not break others that +are related. Building devicetrees is fast, so performance is seldom a concern +here.
In that it makes our Makefile more like the Linux one, yes, this is fine. But that's why we're doing it, familiarity with Linux. Device trees shouldn't be changing all the time!
+Overriding the default devicetree +---------------------------------
+When building U-Boot, the `DEVICE_TREE` environment variable allows the +default devicetree file to be overridden at build time. This can be useful if +modifications have to be made to the in-tree devicetree file, for the benefit +of a downstream build system.
This is fine.
Note that the in-tree devicetree must be +sufficient to build and boot, so this is not a way to bypass that requirement.
This doesn't make sense. Either we're CONFIG_OF_BOARD=n and so yes, the device tree must work or we're CONFIG_OF_BOARD=y and this will never ever be used by anything. We shouldn't even be needing to build it.
+Modifying the devicetree after building +---------------------------------------
+While it is generally painful and hacky to modify the code or rodata of a +program after it is built, in many cases it is useful to do so, e.g. to add +configuration information like serial numbers, enabling/disabling features, etc.
+Devicetree provides a very nice solution to these problems since it is +structured data and it is relatively easy to change it, even in binary form +(see fdtput).
+U-Boot takes care that the devicetree is easily accessible after the build +process. In fact it is placed in a separate file called `u-boot.dtb`. If the +build system wants to modify or replace that file, it can do so. Then all that +is needed is to run `binman update` to update the file inside the image. If +binman is not used, then `u-boot-nodtb.bin` and the new `u-boot.dtb` can simply +be concatenated to achieve the desired result. U-Boot happily copes with the +devicetree growing or shrinking.
This can be handy, yes. But it's also an optional thing because CONFIG_OF_BOARD=y means we're always going to use that run time provided tree. If we're going to support something like this with CONFIG_OF_BOARD=y we'll need to come up with some solution, probably doing one of the things you've listed later on as being too complex, but I believe we already do in at least one case (rcar3 applies an overlay to dtb passed in from TF-A).
+The `u-boot.bin` image contains both pieces. While it is possible to locate the +devicetree within the image using the signature at the start of the file, this +is a bit messy.
+This is why `CONFIG_OF_SEPARATE` should always be used when building U-Boot. +The `CONFIG_OF_EMBED` option embeds the devicetree somewhere in the U-Boot ELF +image as rodata, meaning that it is hard to find it and it cannot increase in +size.
We should really figure out and fix up / remove CONFIG_OF_EMBED. But that needs to be another thread with the relevant board maintainers to see why they did what they did to start with.
+When modifying the devicetree, the different cases to consider are as follows:
+- CONFIG_OF_SEPARATE
- This is easy, described above. Just change, replace or rebuild the
- devicetree so it suits your needs, then rerun binman or redo the `cat`
- operation to join `u-boot-nodtb.bin` and the new `u-boot.dtb`
Yes.
+- CONFIG_OF_EMBED
- This is tricky, since the devicetree cannot easily be located. If the EFL
- file is available, then the _dtb_dt_begin and __dtb_dt_end symbols can be
- examined to find it. While it is possible to contract the file, it is not
- possible to expand the file since that would involve re-linking
We should remove this, I believe.
+- CONFIG_OF_BOARD
- This is a board-specific situation, so needs to be considered on a
- case-by-case base.
No. Or rather, maybe we need to rename this so it's clear that this is the case where the device tree we use is passed in at run-time in some manner.
+Use of U-Boot /config node +--------------------------
This should just be a link to the binding documentation, yes?
[snip]
+Devicetree in another project +-----------------------------
+In some cases U-Boot receive its devicetree at runtime from a program that calls +it. For example ARM's Trusted Firmware A (`TF-A`_) may have a devicetree that it +passes to U-Boot. This overrides any devicetree build by U-Boot. When packaging +the firmware, the U-Boot devicetree may in fact be left out if it can be +guaranteed that it will receive one from another project.
Yes.
+In this case, the devicetree in the other project must track U-Boot's use of +device tree, for the following reasons:
Well, no? That's not right, or at least reads much more confrontational that needed. At heart, U-Boot has documented and upstreamed properties, as part of the appropriate bindings. They need to be put in to the device tree in order for features to work. If they aren't there, they won't work. But if they needed to be there for the platform to work, they'd have been present anyhow. It's only a gray area in that we have bindings to upstream still.
[snip]
+Note that the U-Boot in-tree devicetree source must be sufficient to build and +boot, so this is not a way to bypass that requirement.
But this is wrong because we cannot have a static device tee in many cases that would work.
+If binman is used, the devicetree source in U-Boot must contain the binman +definition so that a valid image can be build. This helps people discover what +other firmware components are needed and seek out appropriate documentation.
This is probably a little awkward as I'm not sure if we have systems that are both CONFIG_OF_BOARD=y and using binman to generate the image that flashes to hardware. That may be a little tricky and we need to see what the examples and usage there is.
+If verified boot is used, the project must provide a way to inject a public key, +certificate or other material into the U-Boot devicetree so that it is available +to U-Boot at runtime. See `Signing with U-Boot devicetree`_. This may be +through tooling in the project itself or by making use of U-Boot's tooling.
This is fine.
+Devicetree generated on-the-fly in another project +--------------------------------------------------
+In some rare cases, another project may wish to create a devicetree for U-Boot
We don't need to quantify here, just "In some cases".
+entirely on-the-fly, then pass it to U-Boot at runtime.
True.
The only known example +of this at the time of writing (2021) is QEMU, for ARM (`QEMU ARM`_) and +RISC-V (`QEMU RISC-V`_).
Also Xen, and I'm not sure it's helpful to attempt to enumerate all of them, just an example is probably fine.
+In effect, when the board boots, U-Boot is *downstream* of the other project. +It is entirely reliant on that project for its correct operation.
+This does not mean to imply that the other project is creating its own, +incompatible devicetree. In fact QEMU generates a valid devicetree which is +suitable for both U-Boot and Linux. It is quite normal for a devicetree to be +present in flash and be made available to U-Boot at runtime. What matters is +where the devicetree comes from. If the other project builds a devicetree for +U-Boot then it needs to support adding the things needed by U-Boot features. +Without them, for example:
Everything I said above about making device trees that comply with bindings goes here. And then that makes this not a special case at all worth mentioning. There's nothing special about this case compared to any other case where we get the device tree at run time.
[snip]
+Passing the devicetree through to Linux +---------------------------------------
+Ideally U-Boot and Linux use the same devicetree source, even though it is +hosted in separate projects. U-Boot adds some extra pieces, such as the +`config/` node and tags like `u-boot,dm-spl`. Linux adds some extra pieces, such +as `linux,default-trigger` and `linux,code`. This should not interfere with +each other.
+In principle it is possible for U-Boot's control devicetree to be passed to +Linux. This is, after all, one of the goals of devicetree and the original +Open Firmware project, to have the firmware provide the hardware description to +the Operating System.
This reads a bit more confrontational than intended perhaps?
+For boards where this approach is used, care must be taken. U-Boot typically +needs to 'fix up' the devicetree before passing it to Linux, e.g. to add +information about the memory map, about which serial console is used, provide +the kernel address space layout randomization (KASLR) seed or select whether the +console should be silenced for a faster boot.
We should note / explain that this is something we've been doing almost since DT inception. And then we need to document which hooks / paths happen at boot the OS stage, and which paths happen sooner and can change U-Boot as well at run time.
+Fix-ups involve modifying the devicetree. If the control devicetree is used, +that means the control devicetree could be modified, while U-Boot is using it. +Removing a device and reinserting it can cause problems if the devicetree offset +has changed, for example, since the device will be unable to locates its +devicetree properties at the expected devicetree offset, which is a fixed +integer.
+To deal with this, it is recommended to employ one or more of the following +approaches:
+- Make a copy of the devicetree and 'fix up' the copy, leaving the control
- devicetree alone
+- Enable `CONFIG_OF_LIVE` so that U-Boot makes its own copy of the devicetree
- during relocation; fixups then happen on the original flat tree
+- Ensure that fix-ups happen after all loading has happened and U-Boot has
- completed image verification
+In practice,the last point is typically observed, since boot_prep_linux() is +called just before jumping to Linux, long after signature verification, for +example. But it is important to make sure that this line is not blurred, +particularly if untrusted user data is involved.
In addition to what I said above, we should explain which paths are best for which cases.
+Devicetree use cases that must be supported +-------------------------------------------
+Regardless of how the devicetree is provided to U-Boot at runtime, various +U-Boot features must be fully supported. This section describes some of these +features and the implications for other projects.
"must" is pretty strong for some of these cases. A whole lot of U-Boot is opt-in if you need it.
+If U-Boot uses its own in-tree devicetree these features are supported +automatically.
This is both confrontational (again, you write vs the binding) and over simplifies. We don't automatically know where to shove u-boot,dm-pre-reloc but it's not likely to be passed in to us yet because it's not upstreamedd. But but it's also potentially not needed, if we can just deal with having something not probe until a bit later.
+Signing with U-Boot devicetree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This should link to the documentation for this feature, and is not mandatory for all platforms.
[snip]
+Providing the binman image definition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Not mandatory, and should link to more extensive documentation on how this works, along with just a brief summary here.
[snip]
+Protecting the devicetree +-------------------------
+U-Boot relies heavily on devicetree for correct operation. A corrupt or invalid +device can cause U-Boot to fail to start, behave incorrectly, crash (e.g. if +`CONFIG_OF_LIBFDT_ASSUME_MASK` is adjusted, or fail to boot an Operating System.
This is a true statement, but doesn't describe a feaature.
+Within U-Boot, the devicetree is as important as any other part of the source +code. At ruuntime, the devicetree can be considered to be structured rodata.
+With secure systems, care must be taken that the devicetree is valid:
With all systems care must be taken, or everything blows up, or is compromised more easily. We _do_ attempt to take care of the device tree via the LMB mechanism, and should mention that here. And double check that we're covering it :)
+- If the code / rodata has a hash or signature, the devicetree should also, if
- they are packaged separately.
This should be part of the verification documentation.
+- If the code / rodata is write-protected when running, the devicetree should be
- also. Note that U-Boot relocates its code and devicetree, so this is not as
- simple as it sounds. U-Boot must write-protect these items after relocating.
This is a general design / implementation issue, yes. This should be more "If you have the ability to protect memory, then .." I think.
+Why does U-Boot have its nodes and properties? +----------------------------------------------
This is the part I think that causes the most objection / confusion in general as it's written in a way that reads as an argument, to me. I'd like to strike the whole section, honestly, as it reads to me as "we argued a lot on the mailing list, now I'm making my part of that the documentation".
+See also :doc:`../devicetree/intro`.
+There has been pushback at the concept that U-Boot dares have its own nodes and +properties in the devicetree.
+Apart from these nodes and properties, U-Boot uses the same bindings as Linux. +A `u-boot.dtsi` file helps to keep U-Boot-specific changes in separate files, +making it easier to keep devicetree source files in U-Boot in sync with Linux.
As I said in my other reply, I think the -u-boot.dtsi was a mistake, in hindsight as it let us not try and upstream bindings / properties for far too long. And now we're at this point where platforms are coming in, wanting to use a run-time provided device tree, and hitting the wall on what to do exactly about some of our nodes and properties.
+As a counter-example, the Zephyr OS project takes a different approach. It uses +entirely different bindings, in general, making no effort to sync devicetree +source files with Linux. U-Boot strives to be compatible with Linux in a number +of ways, such as source code style and common APIs, to aid porting of code +between the projects. Devicetree is another way where U-Boot and Linux follow a +similar approach.
I don't think it's helpful to mention Zephyr at all. They're doing exactly what they intended to do and document that they do. I believe no one is surprised when they go in to Zephyr-land at what they see.
+Fundamentally, the idea that U-Boot cannot have its own tags flies in the face +of the devicetree specification (see dtspec_), which says:
- Nonstandard property names should specify a **unique string prefix**, such as
- a stock ticker symbol, identifying the name of the company **or organization**
- that defined the property. Examples:
- fsl,channel-fifo-len
- ibm,ppc-interrupt-server#s
- **linux**,network-index
+It is also fundamentally unbalanced. Linux has many tags of its own (some 36 in +version 5.13) and at least one Linux-specific node, even if you ignore things +like flash partitions which clearly provide configuration information to Linux.
What we can't have is properties that aren't documented and upstreamed, and that part of the equation isn't spelled out or emphasized in this document nearly enough.
+Practically speaking there are many reasons why U-Boot has its own nodes and +properties. Some examples:
+- Binding every device before relocation even if it won't be used, consumes time
- and memory: tags on each node can specify which are needed in SPL or before
- relocation. Linux has no such constraints.
Documenting how and why we make this special one-off DTB for SPL needs to happen. And then maybe we need to think of something more clever? I'm not sure. Because yes, I see this as one of the harder to upstream properties. But maybe I'm just over-worrying.
+- Requiring the full clock tree to be up and running just to get the debug UART
- running is inefficient. It is also and self-defeating, since if that much
- code is working properly, you probably don't need the debug UART. A devicetree
- property to provide the UART input-clock frequency is a simple solution.
This is because of that discussion we had a long time ago about how that property got dropped from some devices, yes? I _think_ things have evolved and as it's a valid property should be able to be in the dts, upstream, again/still.
+- U-Boot does not have a user space to provide policy and configuration. It
- cannot do what Linux does and run programs and look up filesystems to figure
- out how to boot.
This is the /config node, which is being documented / upstreamed and it's time to poke Rob again.
With that said, replacing this section with something that points to our upstream bindings would be helpful.
+Why not have two devicetrees? +-----------------------------
+Setting aside the argument for restricting U-Boot from having its own nodes and +properties, another idea proposed is to have two devicetrees, one for the +U-Boot-specific bits (here called `special`) and one for everything else (here +called `linux`). This would mean that U-Boot would be controlled by two +devicetrees, i.e. OF_CONTROL would require/allow two devicetrees in order to +work.
+On the positive side, it might quieten the discussion alluded to in the section +above. But there are many negatives to consider and many open questions to +resolve.
So, this reads as another argument-by-documentation section, please drop it.

Without this option QEMU appears to hang. Add it to avoid confusion.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/board/emulation/qemu-arm.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst index 584ef0a7e15..8bd7b60cdb4 100644 --- a/doc/board/emulation/qemu-arm.rst +++ b/doc/board/emulation/qemu-arm.rst @@ -41,14 +41,15 @@ The minimal QEMU command line to get U-Boot up and running is:
- For ARM::
- qemu-system-arm -machine virt -bios u-boot.bin + qemu-system-arm -machine virt -nographic -bios u-boot.bin
- For AArch64::
- qemu-system-aarch64 -machine virt -cpu cortex-a57 -bios u-boot.bin + qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin
Note that for some odd reason qemu-system-aarch64 needs to be explicitly -told to use a 64-bit CPU or it will boot in 32-bit mode. +told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic argument +ensures that output appears on the terminal. Use Ctrl-A X to quit.
Additional persistent U-boot environment support can be added as follows:

On 12/6/21 16:11, Simon Glass wrote:
Without this option QEMU appears to hang. Add it to avoid confusion.
Signed-off-by: Simon Glass sjg@chromium.org
I think there was some work to get a virtio framebuffer working. But adding -nographic is ok.
Reviewed-by: Heinrich Schuchardt xypron.glpk@gmx.de
(no changes since v1)
doc/board/emulation/qemu-arm.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst index 584ef0a7e15..8bd7b60cdb4 100644 --- a/doc/board/emulation/qemu-arm.rst +++ b/doc/board/emulation/qemu-arm.rst @@ -41,14 +41,15 @@ The minimal QEMU command line to get U-Boot up and running is:
For ARM::
qemu-system-arm -machine virt -bios u-boot.bin
qemu-system-arm -machine virt -nographic -bios u-boot.bin
- For AArch64::
- qemu-system-aarch64 -machine virt -cpu cortex-a57 -bios u-boot.bin
qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin
Note that for some odd reason qemu-system-aarch64 needs to be explicitly
-told to use a 64-bit CPU or it will boot in 32-bit mode. +told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic argument +ensures that output appears on the terminal. Use Ctrl-A X to quit.
Additional persistent U-boot environment support can be added as follows:

QEMU currently generates a devicetree for use with U-Boot. Explain how to obtain it.
Also explain how to merge it to produce a devicetree with the U-Boot features included.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v5)
Changes in v5: - Merge RISC-V and ARM patches since they are similar
doc/board/emulation/qemu-arm.rst | 3 ++ doc/board/emulation/qemu-riscv.rst | 3 ++ doc/develop/devicetree/dt_qemu.rst | 48 ++++++++++++++++++++++++++++++ doc/develop/devicetree/index.rst | 1 + 4 files changed, 55 insertions(+) create mode 100644 doc/develop/devicetree/dt_qemu.rst
diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst index 8bd7b60cdb4..ff64ec08c3e 100644 --- a/doc/board/emulation/qemu-arm.rst +++ b/doc/board/emulation/qemu-arm.rst @@ -21,6 +21,9 @@ The 'virt' platform provides the following as the basic functionality:
Additionally, a number of optional peripherals can be added to the PCI bus.
+See :doc:`../../develop/devicetree/dt_qemu` for information on how to see +the devicetree actually generated by QEMU. + Building U-Boot --------------- Set the CROSS_COMPILE environment variable as usual, and run: diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index 4b8e104a215..3409fff8117 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -13,6 +13,9 @@ The QEMU virt machine models a generic RISC-V virtual machine with support for the VirtIO standard networking and block storage devices. It has CLINT, PLIC, 16550A UART devices in addition to VirtIO and it also uses device-tree to pass configuration information to guest software. It implements RISC-V privileged + +See :doc:`../../develop/devicetree/dt_qemu` for information on how to see +the devicetree actually generated by QEMU. architecture spec v1.10.
Building U-Boot diff --git a/doc/develop/devicetree/dt_qemu.rst b/doc/develop/devicetree/dt_qemu.rst new file mode 100644 index 00000000000..1392a2cae97 --- /dev/null +++ b/doc/develop/devicetree/dt_qemu.rst @@ -0,0 +1,48 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Devicetree in QEMU +================== + +For QEMU on ARM, RISC-V and one PPC target, the devicetree is created on the +fly by QEMU. It is intended for use in Linux but can be used by U-Boot also, +so long as any nodes/properties needed by U-Boot are merged in. + +When `CONFIG_OF_BOARD` is enabled + + +Obtaining the QEMU devicetree +----------------------------- + +Where QEMU generates its own devicetree to pass to U-Boot tou can use +`-dtb u-boot.dtb` to force QEMU to use U-Boot's in-tree version. + +To obtain the devicetree that qemu generates, add `-machine dumpdtb=qemu.dtb`, +e.g.:: + + qemu-system-arm -machine virt -machine dumpdtb=qemu.dtb + + qemu-system-aarch64 -machine virt -machine dumpdtb=qemu.dtb + + qemu-system-riscv64 -machine virt -machine dumpdtb=qemu.dtb + + +Merging in U-Boot nodes/properties +---------------------------------- + +Various U-Boot features require nodes and properties in the U-Boot devicetree +and at present QEMU is unaware of these. To use these you must manually merge +in the appropriate pieces. + +One way to do this is with dtc. This command runs dtc on each .dtb file in turn, +to produce a text file. It drops the duplicate header on the qemu one. Then it +joins them up and runs them through dtc to compile the output:: + + qemu-system-arm -machine virt -machine dumpdtb=qemu.dtb + cat <(dtc -I dtb qemu.dtb) <(dtc -I dtb u-boot.dtb |grep -v /dts-v1/) |dtc - -o merged.dtb + +You can then run qemu with the merged devicetree, e.g.:: + + qemu-system-arm -machine virt -nographic -bios u-boot.bin -dtb merged.dtb + +Note that there seems to be a bug in some versions of qemu where the output of +dumpdtb does not quite match what is provided to U-Boot. diff --git a/doc/develop/devicetree/index.rst b/doc/develop/devicetree/index.rst index b5b33dfea0f..fc2fb41b1bb 100644 --- a/doc/develop/devicetree/index.rst +++ b/doc/develop/devicetree/index.rst @@ -12,3 +12,4 @@ build-time and runtime configuration. intro control dt_update + dt_qemu

This uses QEMU virt which creates its own devicetree.
Add an empty version of this file, so that we can at least build this board when devicetrees are required.
Tested-by: Heinrich Schuchardt heinrich.schuchardt@canaonical.com Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Switch to using an empty file for qemu virt
Changes in v6: - Expand the commit message based on comments
arch/arm/dts/Makefile | 2 ++ arch/arm/dts/qemu-arm.dts | 11 +++++++++++ configs/qemu_arm_defconfig | 1 + 3 files changed, 14 insertions(+) create mode 100644 arch/arm/dts/qemu-arm.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7f622fedbda..eaad3b679cc 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1162,6 +1162,8 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) += imx8mm-cl-iot-gate-optee.dtb
dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
+dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb + targets += $(dtb-y)
# Add any required device tree compiler flags here diff --git a/arch/arm/dts/qemu-arm.dts b/arch/arm/dts/qemu-arm.dts new file mode 100644 index 00000000000..230c630f04f --- /dev/null +++ b/arch/arm/dts/qemu-arm.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Empty device tree for qemu_arm + + * Copyright 2021 Google LLC + */ + +/dts-v1/; + +/ { +}; diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index d4f6d0b4373..a644a5f3e79 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_LEN=0x1000000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x40000 CONFIG_ENV_SECT_SIZE=0x40000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-arm" CONFIG_TARGET_QEMU_ARM_32BIT=y CONFIG_DEBUG_UART_BASE=0x9000000 CONFIG_DEBUG_UART_CLOCK=0

This uses QEMU virt which creates its own devicetree.
Add an empty version of this file, so that we can at least build this board when devicetrees are required.
Tested-by: Heinrich Schuchardt heinrich.schuchardt@canaonical.com Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Switch to using an empty file for qemu virt
Changes in v6: - Expand the commit message based on comments
arch/arm/dts/Makefile | 2 +- arch/arm/dts/qemu-arm64.dts | 11 +++++++++++ configs/qemu_arm64_defconfig | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/qemu-arm64.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index eaad3b679cc..2d92b2f940d 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1162,7 +1162,7 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) += imx8mm-cl-iot-gate-optee.dtb
dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
-dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb +dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb qemu-arm64.dtb
targets += $(dtb-y)
diff --git a/arch/arm/dts/qemu-arm64.dts b/arch/arm/dts/qemu-arm64.dts new file mode 100644 index 00000000000..096b3910728 --- /dev/null +++ b/arch/arm/dts/qemu-arm64.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Empty device tree for qemu_arm64 + + * Copyright 2021 Google LLC + */ + +/dts-v1/; + +/ { +}; diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 02a5e940c41..a8652f871ca 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -8,6 +8,7 @@ CONFIG_ENV_SECT_SIZE=0x40000 CONFIG_DEBUG_UART_BASE=0x9000000 CONFIG_DEBUG_UART_CLOCK=0 CONFIG_DEBUG_UART=y +CONFIG_DEFAULT_DEVICE_TREE="qemu-arm64" CONFIG_AHCI=y CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x40200000

This uses QEMU virt which creates its own devicetree.
Copy the existing empty version of this file, so splitting the existing qemu-virt into two, since anyone actually trying to use this will need a different devicetree for 32- and 64-bit machines.
Tested-by: Heinrich Schuchardt heinrich.schuchardt@canaonical.com Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Switch to using an empty file for qemu virt - Reword commit message
arch/riscv/dts/Makefile | 2 +- arch/riscv/dts/{qemu-virt.dts => qemu-virt32.dts} | 3 +++ arch/riscv/dts/qemu-virt64.dts | 11 +++++++++++ configs/qemu-riscv32_defconfig | 1 + configs/qemu-riscv32_smode_defconfig | 1 + configs/qemu-riscv32_spl_defconfig | 2 +- configs/qemu-riscv64_defconfig | 1 + configs/qemu-riscv64_smode_defconfig | 1 + configs/qemu-riscv64_spl_defconfig | 2 +- 9 files changed, 21 insertions(+), 3 deletions(-) rename arch/riscv/dts/{qemu-virt.dts => qemu-virt32.dts} (94%) create mode 100644 arch/riscv/dts/qemu-virt64.dts
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index b6e9166767b..90d3f35e6e3 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -2,7 +2,7 @@
dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += microchip-mpfs-icicle-kit.dtb -dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt.dtb +dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNMATCHED) += hifive-unmatched-a00.dtb diff --git a/arch/riscv/dts/qemu-virt.dts b/arch/riscv/dts/qemu-virt32.dts similarity index 94% rename from arch/riscv/dts/qemu-virt.dts rename to arch/riscv/dts/qemu-virt32.dts index fecff542b91..17e2f0dea41 100644 --- a/arch/riscv/dts/qemu-virt.dts +++ b/arch/riscv/dts/qemu-virt32.dts @@ -6,3 +6,6 @@ /dts-v1/;
#include "binman.dtsi" + +/ { +}; diff --git a/arch/riscv/dts/qemu-virt64.dts b/arch/riscv/dts/qemu-virt64.dts new file mode 100644 index 00000000000..17e2f0dea41 --- /dev/null +++ b/arch/riscv/dts/qemu-virt64.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021, Bin Meng bmeng.cn@gmail.com + */ + +/dts-v1/; + +#include "binman.dtsi" + +/ { +}; diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig index 0b8cd191618..4c0f51bd2aa 100644 --- a/configs/qemu-riscv32_defconfig +++ b/configs/qemu-riscv32_defconfig @@ -2,6 +2,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-virt32" CONFIG_TARGET_QEMU_VIRT=y CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x80200000 diff --git a/configs/qemu-riscv32_smode_defconfig b/configs/qemu-riscv32_smode_defconfig index 4d65104f7b4..19406080100 100644 --- a/configs/qemu-riscv32_smode_defconfig +++ b/configs/qemu-riscv32_smode_defconfig @@ -2,6 +2,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-virt32" CONFIG_TARGET_QEMU_VIRT=y CONFIG_RISCV_SMODE=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/qemu-riscv32_spl_defconfig b/configs/qemu-riscv32_spl_defconfig index eb64c51a214..c4422969c61 100644 --- a/configs/qemu-riscv32_spl_defconfig +++ b/configs/qemu-riscv32_spl_defconfig @@ -2,7 +2,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="qemu-virt" +CONFIG_DEFAULT_DEVICE_TREE="qemu-virt32" CONFIG_SPL=y CONFIG_TARGET_QEMU_VIRT=y CONFIG_RISCV_SMODE=y diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig index 4faa6dad8d6..cba975d703d 100644 --- a/configs/qemu-riscv64_defconfig +++ b/configs/qemu-riscv64_defconfig @@ -2,6 +2,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-virt64" CONFIG_TARGET_QEMU_VIRT=y CONFIG_ARCH_RV64I=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/qemu-riscv64_smode_defconfig b/configs/qemu-riscv64_smode_defconfig index f575c127b7c..6b7771488fe 100644 --- a/configs/qemu-riscv64_smode_defconfig +++ b/configs/qemu-riscv64_smode_defconfig @@ -2,6 +2,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-virt64" CONFIG_TARGET_QEMU_VIRT=y CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y diff --git a/configs/qemu-riscv64_spl_defconfig b/configs/qemu-riscv64_spl_defconfig index 0fbdb7564c6..e02ca3a1465 100644 --- a/configs/qemu-riscv64_spl_defconfig +++ b/configs/qemu-riscv64_spl_defconfig @@ -2,7 +2,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="qemu-virt" +CONFIG_DEFAULT_DEVICE_TREE="qemu-virt64" CONFIG_SPL=y CONFIG_TARGET_QEMU_VIRT=y CONFIG_ARCH_RV64I=y

Sync these files, obtained from Linux v5.15.
This adds a devicetree file for rpi_4 which was not there before.
Testing shows no change so far as I can see: - boots to U-Boot prompt on rpi0, rpi2 - boots to distro on rpi3 - boots to distro on rpi4
I am assuming that syncing with Linux is safe, but the maintainer should know for sure.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Bring in files from Linux instead
arch/arm/dts/Makefile | 3 +- arch/arm/dts/bcm2711-rpi-4-b.dts | 262 +++++ arch/arm/dts/bcm2711-rpi.dtsi | 74 ++ arch/arm/dts/bcm2711.dtsi | 1100 ++++++++++++++++++ arch/arm/dts/bcm2835-common.dtsi | 207 ++++ arch/arm/dts/bcm2835-rpi-a-plus.dts | 18 +- arch/arm/dts/bcm2835-rpi-a.dts | 16 +- arch/arm/dts/bcm2835-rpi-b-plus.dts | 18 +- arch/arm/dts/bcm2835-rpi-b-rev2.dts | 16 +- arch/arm/dts/bcm2835-rpi-b.dts | 16 +- arch/arm/dts/bcm2835-rpi-cm1-io1.dts | 9 + arch/arm/dts/bcm2835-rpi-cm1.dtsi | 7 +- arch/arm/dts/bcm2835-rpi-common.dtsi | 12 + arch/arm/dts/bcm2835-rpi-zero-w.dts | 20 +- arch/arm/dts/bcm2835-rpi-zero.dts | 16 +- arch/arm/dts/bcm2835-rpi.dtsi | 35 +- arch/arm/dts/bcm2835.dtsi | 2 + arch/arm/dts/bcm2836-rpi-2-b.dts | 14 +- arch/arm/dts/bcm2836.dtsi | 2 + arch/arm/dts/bcm2837-rpi-3-a-plus.dts | 9 +- arch/arm/dts/bcm2837-rpi-3-b-plus.dts | 9 +- arch/arm/dts/bcm2837-rpi-3-b.dts | 5 +- arch/arm/dts/bcm2837-rpi-cm3-io3.dts | 9 + arch/arm/dts/bcm2837-rpi-cm3.dtsi | 9 + arch/arm/dts/bcm2837.dtsi | 2 + arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi | 7 + arch/arm/dts/bcm283x.dtsi | 224 +--- configs/rpi_4_32b_defconfig | 1 + configs/rpi_4_defconfig | 1 + configs/rpi_arm64_defconfig | 1 + include/dt-bindings/clock/bcm2835.h | 2 + 31 files changed, 1878 insertions(+), 248 deletions(-) create mode 100644 arch/arm/dts/bcm2711-rpi-4-b.dts create mode 100644 arch/arm/dts/bcm2711-rpi.dtsi create mode 100644 arch/arm/dts/bcm2711.dtsi create mode 100644 arch/arm/dts/bcm2835-common.dtsi create mode 100644 arch/arm/dts/bcm2835-rpi-common.dtsi create mode 100644 arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2d92b2f940d..9cddab37207 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1077,7 +1077,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \ bcm2837-rpi-3-a-plus.dtb \ bcm2837-rpi-3-b.dtb \ bcm2837-rpi-3-b-plus.dtb \ - bcm2837-rpi-cm3-io3.dtb + bcm2837-rpi-cm3-io3.dtb \ + bcm2711-rpi-4-b.dtb
dtb-$(CONFIG_ARCH_BCM63158) += \ bcm963158.dtb diff --git a/arch/arm/dts/bcm2711-rpi-4-b.dts b/arch/arm/dts/bcm2711-rpi-4-b.dts new file mode 100644 index 00000000000..72ce80fbf26 --- /dev/null +++ b/arch/arm/dts/bcm2711-rpi-4-b.dts @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +#include "bcm2711.dtsi" +#include "bcm2711-rpi.dtsi" +#include "bcm283x-rpi-usb-peripheral.dtsi" + +/ { + compatible = "raspberrypi,4-model-b", "brcm,bcm2711"; + model = "Raspberry Pi 4 Model B"; + + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; + + leds { + led-act { + gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; + }; + + led-pwr { + label = "PWR"; + gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + default-state = "keep"; + linux,default-trigger = "default-on"; + }; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; + }; + + sd_io_1v8_reg: sd_io_1v8_reg { + compatible = "regulator-gpio"; + regulator-name = "vdd-sd-io"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + regulator-settling-time-us = <5000>; + gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; + states = <1800000 0x1>, + <3300000 0x0>; + status = "okay"; + }; + + sd_vcc_reg: sd_vcc_reg { + compatible = "regulator-fixed"; + regulator-name = "vcc-sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + enable-active-high; + gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>; + }; +}; + +&ddc0 { + status = "okay"; +}; + +&ddc1 { + status = "okay"; +}; + +&expgpio { + gpio-line-names = "BT_ON", + "WL_ON", + "PWR_LED_OFF", + "GLOBAL_RESET", + "VDD_SD_IO_SEL", + "CAM_GPIO", + "SD_PWR_ON", + ""; +}; + +&gpio { + /* + * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and + * the official GPU firmware DT blob. + * + * Legend: + * "FOO" = GPIO line named "FOO" on the schematic + * "FOO_N" = GPIO line named "FOO" on schematic, active low + */ + gpio-line-names = "ID_SDA", + "ID_SCL", + "SDA1", + "SCL1", + "GPIO_GCLK", + "GPIO5", + "GPIO6", + "SPI_CE1_N", + "SPI_CE0_N", + "SPI_MISO", + "SPI_MOSI", + "SPI_SCLK", + "GPIO12", + "GPIO13", + /* Serial port */ + "TXD1", + "RXD1", + "GPIO16", + "GPIO17", + "GPIO18", + "GPIO19", + "GPIO20", + "GPIO21", + "GPIO22", + "GPIO23", + "GPIO24", + "GPIO25", + "GPIO26", + "GPIO27", + "RGMII_MDIO", + "RGMIO_MDC", + /* Used by BT module */ + "CTS0", + "RTS0", + "TXD0", + "RXD0", + /* Used by Wifi */ + "SD1_CLK", + "SD1_CMD", + "SD1_DATA0", + "SD1_DATA1", + "SD1_DATA2", + "SD1_DATA3", + /* Shared with SPI flash */ + "PWM0_MISO", + "PWM1_MOSI", + "STATUS_LED_G_CLK", + "SPIFLASH_CE_N", + "SDA0", + "SCL0", + "RGMII_RXCLK", + "RGMII_RXCTL", + "RGMII_RXD0", + "RGMII_RXD1", + "RGMII_RXD2", + "RGMII_RXD3", + "RGMII_TXCLK", + "RGMII_TXCTL", + "RGMII_TXD0", + "RGMII_TXD1", + "RGMII_TXD2", + "RGMII_TXD3"; +}; + +&hdmi0 { + status = "okay"; +}; + +&hdmi1 { + status = "okay"; +}; + +&pixelvalve0 { + status = "okay"; +}; + +&pixelvalve1 { + status = "okay"; +}; + +&pixelvalve2 { + status = "okay"; +}; + +&pixelvalve4 { + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; + status = "okay"; +}; + +/* SDHCI is used to control the SDIO for wireless */ +&sdhci { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_gpio34>; + bus-width = <4>; + non-removable; + mmc-pwrseq = <&wifi_pwrseq>; + status = "okay"; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* EMMC2 is used to drive the SD card */ +&emmc2 { + vqmmc-supply = <&sd_io_1v8_reg>; + vmmc-supply = <&sd_vcc_reg>; + broken-cd; + status = "okay"; +}; + +&genet { + phy-handle = <&phy1>; + phy-mode = "rgmii-rxid"; + status = "okay"; +}; + +&genet_mdio { + phy1: ethernet-phy@1 { + /* No PHY interrupt */ + reg = <0x1>; + }; +}; + +&pcie0 { + pci@0,0 { + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + reg = <0 0 0 0 0>; + + usb@0,0 { + reg = <0 0 0 0 0>; + resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; + }; + }; +}; + +/* uart0 communicates with the BT module */ +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <2000000>; + shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; + }; +}; + +/* uart1 is mapped to the pin header */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_gpio14>; + status = "okay"; +}; + +&vc4 { + status = "okay"; +}; + +&vec { + status = "disabled"; +}; diff --git a/arch/arm/dts/bcm2711-rpi.dtsi b/arch/arm/dts/bcm2711-rpi.dtsi new file mode 100644 index 00000000000..ca266c5d9f9 --- /dev/null +++ b/arch/arm/dts/bcm2711-rpi.dtsi @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "bcm2835-rpi.dtsi" + +#include <dt-bindings/reset/raspberrypi,firmware-reset.h> + +/ { + /* Will be filled by the bootloader */ + memory@0 { + device_type = "memory"; + reg = <0 0 0>; + }; + + aliases { + emmc2bus = &emmc2bus; + ethernet0 = &genet; + pcie0 = &pcie0; + blconfig = &blconfig; + }; +}; + +&firmware { + firmware_clocks: clocks { + compatible = "raspberrypi,firmware-clocks"; + #clock-cells = <1>; + }; + + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <2>; + status = "okay"; + }; + + reset: reset { + compatible = "raspberrypi,firmware-reset"; + #reset-cells = <1>; + }; +}; + +&hdmi0 { + clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>; + clock-names = "hdmi", "bvb", "audio", "cec"; + wifi-2.4ghz-coexistence; +}; + +&hdmi1 { + clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; + clock-names = "hdmi", "bvb", "audio", "cec"; + wifi-2.4ghz-coexistence; +}; + +&hvs { + clocks = <&firmware_clocks 4>; +}; + +&rmem { + /* + * RPi4's co-processor will copy the board's bootloader configuration + * into memory for the OS to consume. It'll also update this node with + * its placement information. + */ + blconfig: nvram@0 { + compatible = "raspberrypi,bootloader-config", "nvmem-rmem"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0 0x0 0x0>; + no-map; + status = "disabled"; + }; +}; + +&vchiq { + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; +}; diff --git a/arch/arm/dts/bcm2711.dtsi b/arch/arm/dts/bcm2711.dtsi new file mode 100644 index 00000000000..3b60297af7f --- /dev/null +++ b/arch/arm/dts/bcm2711.dtsi @@ -0,0 +1,1100 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "bcm283x.dtsi" + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/soc/bcm2835-pm.h> + +/ { + compatible = "brcm,bcm2711"; + + #address-cells = <2>; + #size-cells = <1>; + + interrupt-parent = <&gicv2>; + + vc4: gpu { + compatible = "brcm,bcm2711-vc5"; + status = "disabled"; + }; + + clk_27MHz: clk-27M { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <27000000>; + clock-output-names = "27MHz-clock"; + }; + + clk_108MHz: clk-108M { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <108000000>; + clock-output-names = "108MHz-clock"; + }; + + soc { + /* + * Defined ranges: + * Common BCM283x peripherals + * BCM2711-specific peripherals + * ARM-local peripherals + */ + ranges = <0x7e000000 0x0 0xfe000000 0x01800000>, + <0x7c000000 0x0 0xfc000000 0x02000000>, + <0x40000000 0x0 0xff800000 0x00800000>; + /* Emulate a contiguous 30-bit address range for DMA */ + dma-ranges = <0xc0000000 0x0 0x00000000 0x40000000>; + + /* + * This node is the provider for the enable-method for + * bringing up secondary cores. + */ + local_intc: local_intc@40000000 { + compatible = "brcm,bcm2836-l1-intc"; + reg = <0x40000000 0x100>; + }; + + gicv2: interrupt-controller@40041000 { + interrupt-controller; + #interrupt-cells = <3>; + compatible = "arm,gic-400"; + reg = <0x40041000 0x1000>, + <0x40042000 0x2000>, + <0x40044000 0x2000>, + <0x40046000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_HIGH)>; + }; + + avs_monitor: avs-monitor@7d5d2000 { + compatible = "brcm,bcm2711-avs-monitor", + "syscon", "simple-mfd"; + reg = <0x7d5d2000 0xf00>; + + thermal: thermal { + compatible = "brcm,bcm2711-thermal"; + #thermal-sensor-cells = <0>; + }; + }; + + dma: dma@7e007000 { + compatible = "brcm,bcm2835-dma"; + reg = <0x7e007000 0xb00>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, + /* DMA lite 7 - 10 */ + <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dma0", + "dma1", + "dma2", + "dma3", + "dma4", + "dma5", + "dma6", + "dma7", + "dma8", + "dma9", + "dma10"; + #dma-cells = <1>; + brcm,dma-channel-mask = <0x07f5>; + }; + + pm: watchdog@7e100000 { + compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; + #power-domain-cells = <1>; + #reset-cells = <1>; + reg = <0x7e100000 0x114>, + <0x7e00a000 0x24>, + <0x7ec11000 0x20>; + clocks = <&clocks BCM2835_CLOCK_V3D>, + <&clocks BCM2835_CLOCK_PERI_IMAGE>, + <&clocks BCM2835_CLOCK_H264>, + <&clocks BCM2835_CLOCK_ISP>; + clock-names = "v3d", "peri_image", "h264", "isp"; + system-power-controller; + }; + + rng@7e104000 { + compatible = "brcm,bcm2711-rng200"; + reg = <0x7e104000 0x28>; + }; + + uart2: serial@7e201400 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201400 0x200>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_UART>, + <&clocks BCM2835_CLOCK_VPU>; + clock-names = "uartclk", "apb_pclk"; + arm,primecell-periphid = <0x00241011>; + status = "disabled"; + }; + + uart3: serial@7e201600 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201600 0x200>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_UART>, + <&clocks BCM2835_CLOCK_VPU>; + clock-names = "uartclk", "apb_pclk"; + arm,primecell-periphid = <0x00241011>; + status = "disabled"; + }; + + uart4: serial@7e201800 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201800 0x200>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_UART>, + <&clocks BCM2835_CLOCK_VPU>; + clock-names = "uartclk", "apb_pclk"; + arm,primecell-periphid = <0x00241011>; + status = "disabled"; + }; + + uart5: serial@7e201a00 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201a00 0x200>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_UART>, + <&clocks BCM2835_CLOCK_VPU>; + clock-names = "uartclk", "apb_pclk"; + arm,primecell-periphid = <0x00241011>; + status = "disabled"; + }; + + spi3: spi@7e204600 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204600 0x0200>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi4: spi@7e204800 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204800 0x0200>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi5: spi@7e204a00 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204a00 0x0200>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi6: spi@7e204c00 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204c00 0x0200>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@7e205600 { + compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; + reg = <0x7e205600 0x200>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@7e205800 { + compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; + reg = <0x7e205800 0x200>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@7e205a00 { + compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; + reg = <0x7e205a00 0x200>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@7e205c00 { + compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; + reg = <0x7e205c00 0x200>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pixelvalve0: pixelvalve@7e206000 { + compatible = "brcm,bcm2711-pixelvalve0"; + reg = <0x7e206000 0x100>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + pixelvalve1: pixelvalve@7e207000 { + compatible = "brcm,bcm2711-pixelvalve1"; + reg = <0x7e207000 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + pixelvalve2: pixelvalve@7e20a000 { + compatible = "brcm,bcm2711-pixelvalve2"; + reg = <0x7e20a000 0x100>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + pwm1: pwm@7e20c800 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c800 0x28>; + clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clock-rates = <10000000>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pixelvalve4: pixelvalve@7e216000 { + compatible = "brcm,bcm2711-pixelvalve4"; + reg = <0x7e216000 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hvs: hvs@7e400000 { + compatible = "brcm,bcm2711-hvs"; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + }; + + pixelvalve3: pixelvalve@7ec12000 { + compatible = "brcm,bcm2711-pixelvalve3"; + reg = <0x7ec12000 0x100>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + vec: vec@7ec13000 { + compatible = "brcm,bcm2711-vec"; + reg = <0x7ec13000 0x1000>; + clocks = <&clocks BCM2835_CLOCK_VEC>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + dvp: clock@7ef00000 { + compatible = "brcm,brcm2711-dvp"; + reg = <0x7ef00000 0x10>; + clocks = <&clk_108MHz>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + aon_intr: interrupt-controller@7ef00100 { + compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc"; + reg = <0x7ef00100 0x30>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + hdmi0: hdmi@7ef00700 { + compatible = "brcm,bcm2711-hdmi0"; + reg = <0x7ef00700 0x300>, + <0x7ef00300 0x200>, + <0x7ef00f00 0x80>, + <0x7ef00f80 0x80>, + <0x7ef01b00 0x200>, + <0x7ef01f00 0x400>, + <0x7ef00200 0x80>, + <0x7ef04300 0x100>, + <0x7ef20000 0x100>; + reg-names = "hdmi", + "dvp", + "phy", + "rm", + "packet", + "metadata", + "csc", + "cec", + "hd"; + clock-names = "hdmi", "bvb", "audio", "cec"; + resets = <&dvp 0>; + interrupt-parent = <&aon_intr>; + interrupts = <0>, <1>, <2>, + <3>, <4>, <5>; + interrupt-names = "cec-tx", "cec-rx", "cec-low", + "wakeup", "hpd-connected", "hpd-removed"; + ddc = <&ddc0>; + dmas = <&dma 10>; + dma-names = "audio-rx"; + status = "disabled"; + }; + + ddc0: i2c@7ef04500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>; + reg-names = "bsc", "auto-i2c"; + clock-frequency = <97500>; + status = "disabled"; + }; + + hdmi1: hdmi@7ef05700 { + compatible = "brcm,bcm2711-hdmi1"; + reg = <0x7ef05700 0x300>, + <0x7ef05300 0x200>, + <0x7ef05f00 0x80>, + <0x7ef05f80 0x80>, + <0x7ef06b00 0x200>, + <0x7ef06f00 0x400>, + <0x7ef00280 0x80>, + <0x7ef09300 0x100>, + <0x7ef20000 0x100>; + reg-names = "hdmi", + "dvp", + "phy", + "rm", + "packet", + "metadata", + "csc", + "cec", + "hd"; + ddc = <&ddc1>; + clock-names = "hdmi", "bvb", "audio", "cec"; + resets = <&dvp 1>; + interrupt-parent = <&aon_intr>; + interrupts = <8>, <7>, <6>, + <9>, <10>, <11>; + interrupt-names = "cec-tx", "cec-rx", "cec-low", + "wakeup", "hpd-connected", "hpd-removed"; + dmas = <&dma 17>; + dma-names = "audio-rx"; + status = "disabled"; + }; + + ddc1: i2c@7ef09500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>; + reg-names = "bsc", "auto-i2c"; + clock-frequency = <97500>; + status = "disabled"; + }; + }; + + /* + * emmc2 has different DMA constraints based on SoC revisions. It was + * moved into its own bus, so as for RPi4's firmware to update them. + * The firmware will find whether the emmc2bus alias is defined, and if + * so, it'll edit the dma-ranges property below accordingly. + */ + emmc2bus: emmc2bus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; + dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; + + emmc2: mmc@7e340000 { + compatible = "brcm,bcm2711-emmc2"; + reg = <0x0 0x7e340000 0x100>; + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clocks BCM2711_CLOCK_EMMC2>; + status = "disabled"; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a72-pmu", "arm,armv8-pmuv3"; + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_LOW)>; + /* This only applies to the ARMv7 stub */ + arm,cpu-registers-not-fw-configured; + }; + + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x000000d8>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x000000e0>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x000000e8>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x000000f0>; + }; + }; + + scb { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <0x0 0x7c000000 0x0 0xfc000000 0x03800000>, + <0x6 0x00000000 0x6 0x00000000 0x40000000>; + + pcie0: pcie@7d500000 { + compatible = "brcm,bcm2711-pcie"; + reg = <0x0 0x7d500000 0x9310>; + device_type = "pci"; + #address-cells = <3>; + #interrupt-cells = <1>; + #size-cells = <2>; + interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "pcie", "msi"; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 + IRQ_TYPE_LEVEL_HIGH>; + msi-controller; + msi-parent = <&pcie0>; + + ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 + 0x0 0x04000000>; + /* + * The wrapper around the PCIe block has a bug + * preventing it from accessing beyond the first 3GB of + * memory. + */ + dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 + 0x0 0xc0000000>; + brcm,enable-ssc; + }; + + genet: ethernet@7d580000 { + compatible = "brcm,bcm2711-genet-v5"; + reg = <0x0 0x7d580000 0x10000>; + #address-cells = <0x1>; + #size-cells = <0x1>; + interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + + genet_mdio: mdio@e14 { + compatible = "brcm,genet-mdio-v5"; + reg = <0xe14 0x8>; + reg-names = "mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + }; + }; + }; +}; + +&clk_osc { + clock-frequency = <54000000>; +}; + +&clocks { + compatible = "brcm,bcm2711-cprman"; +}; + +&cpu_thermal { + coefficients = <(-487) 410040>; + thermal-sensors = <&thermal>; +}; + +&dsi0 { + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; +}; + +&dsi1 { + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + compatible = "brcm,bcm2711-dsi1"; +}; + +&gpio { + compatible = "brcm,bcm2711-gpio"; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + + gpclk0_gpio49: gpclk0_gpio49 { + pin-gpclk { + pins = "gpio49"; + function = "alt1"; + bias-disable; + }; + }; + gpclk1_gpio50: gpclk1_gpio50 { + pin-gpclk { + pins = "gpio50"; + function = "alt1"; + bias-disable; + }; + }; + gpclk2_gpio51: gpclk2_gpio51 { + pin-gpclk { + pins = "gpio51"; + function = "alt1"; + bias-disable; + }; + }; + + i2c0_gpio46: i2c0_gpio46 { + pin-sda { + function = "alt0"; + pins = "gpio46"; + bias-pull-up; + }; + pin-scl { + function = "alt0"; + pins = "gpio47"; + bias-disable; + }; + }; + i2c1_gpio46: i2c1_gpio46 { + pin-sda { + function = "alt1"; + pins = "gpio46"; + bias-pull-up; + }; + pin-scl { + function = "alt1"; + pins = "gpio47"; + bias-disable; + }; + }; + i2c3_gpio2: i2c3_gpio2 { + pin-sda { + function = "alt5"; + pins = "gpio2"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio3"; + bias-disable; + }; + }; + i2c3_gpio4: i2c3_gpio4 { + pin-sda { + function = "alt5"; + pins = "gpio4"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio5"; + bias-disable; + }; + }; + i2c4_gpio6: i2c4_gpio6 { + pin-sda { + function = "alt5"; + pins = "gpio6"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio7"; + bias-disable; + }; + }; + i2c4_gpio8: i2c4_gpio8 { + pin-sda { + function = "alt5"; + pins = "gpio8"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio9"; + bias-disable; + }; + }; + i2c5_gpio10: i2c5_gpio10 { + pin-sda { + function = "alt5"; + pins = "gpio10"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio11"; + bias-disable; + }; + }; + i2c5_gpio12: i2c5_gpio12 { + pin-sda { + function = "alt5"; + pins = "gpio12"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio13"; + bias-disable; + }; + }; + i2c6_gpio0: i2c6_gpio0 { + pin-sda { + function = "alt5"; + pins = "gpio0"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio1"; + bias-disable; + }; + }; + i2c6_gpio22: i2c6_gpio22 { + pin-sda { + function = "alt5"; + pins = "gpio22"; + bias-pull-up; + }; + pin-scl { + function = "alt5"; + pins = "gpio23"; + bias-disable; + }; + }; + i2c_slave_gpio8: i2c_slave_gpio8 { + pins-i2c-slave { + pins = "gpio8", + "gpio9", + "gpio10", + "gpio11"; + function = "alt3"; + }; + }; + + jtag_gpio48: jtag_gpio48 { + pins-jtag { + pins = "gpio48", + "gpio49", + "gpio50", + "gpio51", + "gpio52", + "gpio53"; + function = "alt4"; + }; + }; + + mii_gpio28: mii_gpio28 { + pins-mii { + pins = "gpio28", + "gpio29", + "gpio30", + "gpio31"; + function = "alt4"; + }; + }; + mii_gpio36: mii_gpio36 { + pins-mii { + pins = "gpio36", + "gpio37", + "gpio38", + "gpio39"; + function = "alt5"; + }; + }; + + pcm_gpio50: pcm_gpio50 { + pins-pcm { + pins = "gpio50", + "gpio51", + "gpio52", + "gpio53"; + function = "alt2"; + }; + }; + + pwm0_0_gpio12: pwm0_0_gpio12 { + pin-pwm { + pins = "gpio12"; + function = "alt0"; + bias-disable; + }; + }; + pwm0_0_gpio18: pwm0_0_gpio18 { + pin-pwm { + pins = "gpio18"; + function = "alt5"; + bias-disable; + }; + }; + pwm1_0_gpio40: pwm1_0_gpio40 { + pin-pwm { + pins = "gpio40"; + function = "alt0"; + bias-disable; + }; + }; + pwm0_1_gpio13: pwm0_1_gpio13 { + pin-pwm { + pins = "gpio13"; + function = "alt0"; + bias-disable; + }; + }; + pwm0_1_gpio19: pwm0_1_gpio19 { + pin-pwm { + pins = "gpio19"; + function = "alt5"; + bias-disable; + }; + }; + pwm1_1_gpio41: pwm1_1_gpio41 { + pin-pwm { + pins = "gpio41"; + function = "alt0"; + bias-disable; + }; + }; + pwm0_1_gpio45: pwm0_1_gpio45 { + pin-pwm { + pins = "gpio45"; + function = "alt0"; + bias-disable; + }; + }; + pwm0_0_gpio52: pwm0_0_gpio52 { + pin-pwm { + pins = "gpio52"; + function = "alt1"; + bias-disable; + }; + }; + pwm0_1_gpio53: pwm0_1_gpio53 { + pin-pwm { + pins = "gpio53"; + function = "alt1"; + bias-disable; + }; + }; + + rgmii_gpio35: rgmii_gpio35 { + pin-start-stop { + pins = "gpio35"; + function = "alt4"; + }; + pin-rx-ok { + pins = "gpio36"; + function = "alt4"; + }; + }; + rgmii_irq_gpio34: rgmii_irq_gpio34 { + pin-irq { + pins = "gpio34"; + function = "alt5"; + }; + }; + rgmii_irq_gpio39: rgmii_irq_gpio39 { + pin-irq { + pins = "gpio39"; + function = "alt4"; + }; + }; + rgmii_mdio_gpio28: rgmii_mdio_gpio28 { + pins-mdio { + pins = "gpio28", + "gpio29"; + function = "alt5"; + }; + }; + rgmii_mdio_gpio37: rgmii_mdio_gpio37 { + pins-mdio { + pins = "gpio37", + "gpio38"; + function = "alt4"; + }; + }; + + spi0_gpio46: spi0_gpio46 { + pins-spi { + pins = "gpio46", + "gpio47", + "gpio48", + "gpio49"; + function = "alt2"; + }; + }; + spi2_gpio46: spi2_gpio46 { + pins-spi { + pins = "gpio46", + "gpio47", + "gpio48", + "gpio49", + "gpio50"; + function = "alt5"; + }; + }; + spi3_gpio0: spi3_gpio0 { + pins-spi { + pins = "gpio0", + "gpio1", + "gpio2", + "gpio3"; + function = "alt3"; + }; + }; + spi4_gpio4: spi4_gpio4 { + pins-spi { + pins = "gpio4", + "gpio5", + "gpio6", + "gpio7"; + function = "alt3"; + }; + }; + spi5_gpio12: spi5_gpio12 { + pins-spi { + pins = "gpio12", + "gpio13", + "gpio14", + "gpio15"; + function = "alt3"; + }; + }; + spi6_gpio18: spi6_gpio18 { + pins-spi { + pins = "gpio18", + "gpio19", + "gpio20", + "gpio21"; + function = "alt3"; + }; + }; + + uart2_gpio0: uart2_gpio0 { + pin-tx { + pins = "gpio0"; + function = "alt4"; + bias-disable; + }; + pin-rx { + pins = "gpio1"; + function = "alt4"; + bias-pull-up; + }; + }; + uart2_ctsrts_gpio2: uart2_ctsrts_gpio2 { + pin-cts { + pins = "gpio2"; + function = "alt4"; + bias-pull-up; + }; + pin-rts { + pins = "gpio3"; + function = "alt4"; + bias-disable; + }; + }; + uart3_gpio4: uart3_gpio4 { + pin-tx { + pins = "gpio4"; + function = "alt4"; + bias-disable; + }; + pin-rx { + pins = "gpio5"; + function = "alt4"; + bias-pull-up; + }; + }; + uart3_ctsrts_gpio6: uart3_ctsrts_gpio6 { + pin-cts { + pins = "gpio6"; + function = "alt4"; + bias-pull-up; + }; + pin-rts { + pins = "gpio7"; + function = "alt4"; + bias-disable; + }; + }; + uart4_gpio8: uart4_gpio8 { + pin-tx { + pins = "gpio8"; + function = "alt4"; + bias-disable; + }; + pin-rx { + pins = "gpio9"; + function = "alt4"; + bias-pull-up; + }; + }; + uart4_ctsrts_gpio10: uart4_ctsrts_gpio10 { + pin-cts { + pins = "gpio10"; + function = "alt4"; + bias-pull-up; + }; + pin-rts { + pins = "gpio11"; + function = "alt4"; + bias-disable; + }; + }; + uart5_gpio12: uart5_gpio12 { + pin-tx { + pins = "gpio12"; + function = "alt4"; + bias-disable; + }; + pin-rx { + pins = "gpio13"; + function = "alt4"; + bias-pull-up; + }; + }; + uart5_ctsrts_gpio14: uart5_ctsrts_gpio14 { + pin-cts { + pins = "gpio14"; + function = "alt4"; + bias-pull-up; + }; + pin-rts { + pins = "gpio15"; + function = "alt4"; + bias-disable; + }; + }; +}; + +&rmem { + #address-cells = <2>; +}; + +&cma { + /* + * arm64 reserves the CMA by default somewhere in ZONE_DMA32, + * that's not good enough for the BCM2711 as some devices can + * only address the lower 1G of memory (ZONE_DMA). + */ + alloc-ranges = <0x0 0x00000000 0x40000000>; +}; + +&i2c0 { + compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; +}; + +&i2c1 { + compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c"; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; +}; + +&mailbox { + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; +}; + +&sdhci { + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; +}; + +&sdhost { + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; +}; + +&spi { + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; +}; + +&spi1 { + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; +}; + +&spi2 { + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; +}; + +&system_timer { + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; +}; + +&txp { + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; +}; + +&uart0 { + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; +}; + +&uart1 { + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; +}; + +&usb { + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; +}; + +&vec { + compatible = "brcm,bcm2711-vec"; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; +}; diff --git a/arch/arm/dts/bcm2835-common.dtsi b/arch/arm/dts/bcm2835-common.dtsi new file mode 100644 index 00000000000..c25e797b906 --- /dev/null +++ b/arch/arm/dts/bcm2835-common.dtsi @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* This include file covers the common peripherals and configuration between + * bcm2835, bcm2836 and bcm2837 implementations. + */ + +/ { + interrupt-parent = <&intc>; + + soc { + dma: dma@7e007000 { + compatible = "brcm,bcm2835-dma"; + reg = <0x7e007000 0xf00>; + interrupts = <1 16>, + <1 17>, + <1 18>, + <1 19>, + <1 20>, + <1 21>, + <1 22>, + <1 23>, + <1 24>, + <1 25>, + <1 26>, + /* dma channel 11-14 share one irq */ + <1 27>, + <1 27>, + <1 27>, + <1 27>, + /* unused shared irq for all channels */ + <1 28>; + interrupt-names = "dma0", + "dma1", + "dma2", + "dma3", + "dma4", + "dma5", + "dma6", + "dma7", + "dma8", + "dma9", + "dma10", + "dma11", + "dma12", + "dma13", + "dma14", + "dma-shared-all"; + #dma-cells = <1>; + brcm,dma-channel-mask = <0x7f35>; + }; + + intc: interrupt-controller@7e00b200 { + compatible = "brcm,bcm2835-armctrl-ic"; + reg = <0x7e00b200 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pm: watchdog@7e100000 { + compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; + #power-domain-cells = <1>; + #reset-cells = <1>; + reg = <0x7e100000 0x114>, + <0x7e00a000 0x24>; + clocks = <&clocks BCM2835_CLOCK_V3D>, + <&clocks BCM2835_CLOCK_PERI_IMAGE>, + <&clocks BCM2835_CLOCK_H264>, + <&clocks BCM2835_CLOCK_ISP>; + clock-names = "v3d", "peri_image", "h264", "isp"; + system-power-controller; + }; + + rng@7e104000 { + compatible = "brcm,bcm2835-rng"; + reg = <0x7e104000 0x10>; + interrupts = <2 29>; + }; + + pixelvalve@7e206000 { + compatible = "brcm,bcm2835-pixelvalve0"; + reg = <0x7e206000 0x100>; + interrupts = <2 13>; /* pwa0 */ + }; + + pixelvalve@7e207000 { + compatible = "brcm,bcm2835-pixelvalve1"; + reg = <0x7e207000 0x100>; + interrupts = <2 14>; /* pwa1 */ + }; + + thermal: thermal@7e212000 { + compatible = "brcm,bcm2835-thermal"; + reg = <0x7e212000 0x8>; + clocks = <&clocks BCM2835_CLOCK_TSENS>; + #thermal-sensor-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@7e805000 { + compatible = "brcm,bcm2835-i2c"; + reg = <0x7e805000 0x1000>; + interrupts = <2 21>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + }; + + vec: vec@7e806000 { + compatible = "brcm,bcm2835-vec"; + reg = <0x7e806000 0x1000>; + clocks = <&clocks BCM2835_CLOCK_VEC>; + interrupts = <2 27>; + status = "disabled"; + }; + + pixelvalve@7e807000 { + compatible = "brcm,bcm2835-pixelvalve2"; + reg = <0x7e807000 0x100>; + interrupts = <2 10>; /* pixelvalve */ + }; + + hdmi: hdmi@7e902000 { + compatible = "brcm,bcm2835-hdmi"; + reg = <0x7e902000 0x600>, + <0x7e808000 0x100>; + interrupts = <2 8>, <2 9>; + ddc = <&i2c2>; + clocks = <&clocks BCM2835_PLLH_PIX>, + <&clocks BCM2835_CLOCK_HSM>; + clock-names = "pixel", "hdmi"; + dmas = <&dma 17>; + dma-names = "audio-rx"; + status = "disabled"; + }; + + v3d: v3d@7ec00000 { + compatible = "brcm,bcm2835-v3d"; + reg = <0x7ec00000 0x1000>; + interrupts = <1 10>; + }; + + vc4: gpu { + compatible = "brcm,bcm2835-vc4"; + }; + }; +}; + +&cpu_thermal { + thermal-sensors = <&thermal>; +}; + +&gpio { + i2c_slave_gpio18: i2c_slave_gpio18 { + brcm,pins = <18 19 20 21>; + brcm,function = <BCM2835_FSEL_ALT3>; + }; + + jtag_gpio4: jtag_gpio4 { + brcm,pins = <4 5 6 12 13>; + brcm,function = <BCM2835_FSEL_ALT5>; + }; + + pwm0_gpio12: pwm0_gpio12 { + brcm,pins = <12>; + brcm,function = <BCM2835_FSEL_ALT0>; + }; + pwm0_gpio18: pwm0_gpio18 { + brcm,pins = <18>; + brcm,function = <BCM2835_FSEL_ALT5>; + }; + pwm0_gpio40: pwm0_gpio40 { + brcm,pins = <40>; + brcm,function = <BCM2835_FSEL_ALT0>; + }; + pwm1_gpio13: pwm1_gpio13 { + brcm,pins = <13>; + brcm,function = <BCM2835_FSEL_ALT0>; + }; + pwm1_gpio19: pwm1_gpio19 { + brcm,pins = <19>; + brcm,function = <BCM2835_FSEL_ALT5>; + }; + pwm1_gpio41: pwm1_gpio41 { + brcm,pins = <41>; + brcm,function = <BCM2835_FSEL_ALT0>; + }; + pwm1_gpio45: pwm1_gpio45 { + brcm,pins = <45>; + brcm,function = <BCM2835_FSEL_ALT0>; + }; +}; + +&i2s { + dmas = <&dma 2>, <&dma 3>; + dma-names = "tx", "rx"; +}; + +&sdhost { + dmas = <&dma 13>; + dma-names = "rx-tx"; +}; + +&spi { + dmas = <&dma 6>, <&dma 7>; + dma-names = "tx", "rx"; +}; diff --git a/arch/arm/dts/bcm2835-rpi-a-plus.dts b/arch/arm/dts/bcm2835-rpi-a-plus.dts index db8a6017f22..40b9405f1a8 100644 --- a/arch/arm/dts/bcm2835-rpi-a-plus.dts +++ b/arch/arm/dts/bcm2835-rpi-a-plus.dts @@ -8,12 +8,17 @@ compatible = "raspberrypi,model-a-plus", "brcm,bcm2835"; model = "Raspberry Pi Model A+";
+ memory@0 { + device_type = "memory"; + reg = <0 0x10000000>; + }; + leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; };
- pwr { + led-pwr { label = "PWR"; gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; default-state = "keep"; @@ -99,6 +104,8 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { @@ -107,6 +114,13 @@ status = "okay"; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio14>; diff --git a/arch/arm/dts/bcm2835-rpi-a.dts b/arch/arm/dts/bcm2835-rpi-a.dts index 067d1f07a2d..11edb581dba 100644 --- a/arch/arm/dts/bcm2835-rpi-a.dts +++ b/arch/arm/dts/bcm2835-rpi-a.dts @@ -8,8 +8,13 @@ compatible = "raspberrypi,model-a", "brcm,bcm2835"; model = "Raspberry Pi Model A";
+ memory@0 { + device_type = "memory"; + reg = <0 0x10000000>; + }; + leds { - act { + led-act { gpios = <&gpio 16 GPIO_ACTIVE_LOW>; }; }; @@ -94,6 +99,8 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { @@ -102,6 +109,13 @@ status = "okay"; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio14>; diff --git a/arch/arm/dts/bcm2835-rpi-b-plus.dts b/arch/arm/dts/bcm2835-rpi-b-plus.dts index 1e40d672b05..1b435c64bd9 100644 --- a/arch/arm/dts/bcm2835-rpi-b-plus.dts +++ b/arch/arm/dts/bcm2835-rpi-b-plus.dts @@ -9,12 +9,17 @@ compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; model = "Raspberry Pi Model B+";
+ memory@0 { + device_type = "memory"; + reg = <0 0x20000000>; + }; + leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; };
- pwr { + led-pwr { label = "PWR"; gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; default-state = "keep"; @@ -101,6 +106,8 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { @@ -109,6 +116,13 @@ status = "okay"; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio14>; diff --git a/arch/arm/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/dts/bcm2835-rpi-b-rev2.dts index 28e7513ce61..a23c25c00ee 100644 --- a/arch/arm/dts/bcm2835-rpi-b-rev2.dts +++ b/arch/arm/dts/bcm2835-rpi-b-rev2.dts @@ -9,8 +9,13 @@ compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835"; model = "Raspberry Pi Model B rev2";
+ memory@0 { + device_type = "memory"; + reg = <0 0x10000000>; + }; + leds { - act { + led-act { gpios = <&gpio 16 GPIO_ACTIVE_LOW>; }; }; @@ -94,6 +99,8 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { @@ -102,6 +109,13 @@ status = "okay"; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio14>; diff --git a/arch/arm/dts/bcm2835-rpi-b.dts b/arch/arm/dts/bcm2835-rpi-b.dts index 31ff602e2cd..1b63d6b1975 100644 --- a/arch/arm/dts/bcm2835-rpi-b.dts +++ b/arch/arm/dts/bcm2835-rpi-b.dts @@ -9,8 +9,13 @@ compatible = "raspberrypi,model-b", "brcm,bcm2835"; model = "Raspberry Pi Model B";
+ memory@0 { + device_type = "memory"; + reg = <0 0x10000000>; + }; + leds { - act { + led-act { gpios = <&gpio 16 GPIO_ACTIVE_LOW>; }; }; @@ -89,6 +94,8 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { @@ -97,6 +104,13 @@ status = "okay"; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio14>; diff --git a/arch/arm/dts/bcm2835-rpi-cm1-io1.dts b/arch/arm/dts/bcm2835-rpi-cm1-io1.dts index 4764a25585a..a75c882e657 100644 --- a/arch/arm/dts/bcm2835-rpi-cm1-io1.dts +++ b/arch/arm/dts/bcm2835-rpi-cm1-io1.dts @@ -79,6 +79,15 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; +}; + +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; };
&uart0 { diff --git a/arch/arm/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/dts/bcm2835-rpi-cm1.dtsi index ef22c2da783..e4e6b6abbfc 100644 --- a/arch/arm/dts/bcm2835-rpi-cm1.dtsi +++ b/arch/arm/dts/bcm2835-rpi-cm1.dtsi @@ -5,11 +5,16 @@
/ { leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_LOW>; }; };
+ memory@0 { + device_type = "memory"; + reg = <0 0x20000000>; + }; + reg_3v3: fixed-regulator { compatible = "regulator-fixed"; regulator-name = "3V3"; diff --git a/arch/arm/dts/bcm2835-rpi-common.dtsi b/arch/arm/dts/bcm2835-rpi-common.dtsi new file mode 100644 index 00000000000..8a55b6cded5 --- /dev/null +++ b/arch/arm/dts/bcm2835-rpi-common.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This include file covers the common peripherals and configuration between + * bcm2835, bcm2836 and bcm2837 implementations that interact with RPi's + * firmware interface. + */ + +#include <dt-bindings/power/raspberrypi-power.h> + +&v3d { + power-domains = <&power RPI_POWER_DOMAIN_V3D>; +}; diff --git a/arch/arm/dts/bcm2835-rpi-zero-w.dts b/arch/arm/dts/bcm2835-rpi-zero-w.dts index ba0167df6c5..33b2b77aa47 100644 --- a/arch/arm/dts/bcm2835-rpi-zero-w.dts +++ b/arch/arm/dts/bcm2835-rpi-zero-w.dts @@ -12,14 +12,19 @@ compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; model = "Raspberry Pi Zero W";
+ memory@0 { + device_type = "memory"; + reg = <0 0x20000000>; + }; + chosen { /* 8250 auxiliary UART instead of pl011 */ stdout-path = "serial1:115200n8"; };
leds { - act { - gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + led-act { + gpios = <&gpio 47 GPIO_ACTIVE_LOW>; }; };
@@ -100,12 +105,16 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&sdhci { #address-cells = <1>; #size-cells = <0>; + pinctrl-names = "default"; pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>; + bus-width = <4>; mmc-pwrseq = <&wifi_pwrseq>; non-removable; status = "okay"; @@ -116,6 +125,13 @@ }; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>; diff --git a/arch/arm/dts/bcm2835-rpi-zero.dts b/arch/arm/dts/bcm2835-rpi-zero.dts index 3b35a8a4a55..6f9b3a908f2 100644 --- a/arch/arm/dts/bcm2835-rpi-zero.dts +++ b/arch/arm/dts/bcm2835-rpi-zero.dts @@ -12,8 +12,13 @@ compatible = "raspberrypi,model-zero", "brcm,bcm2835"; model = "Raspberry Pi Zero";
+ memory@0 { + device_type = "memory"; + reg = <0 0x20000000>; + }; + leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; }; }; @@ -96,6 +101,15 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; +}; + +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; };
&uart0 { diff --git a/arch/arm/dts/bcm2835-rpi.dtsi b/arch/arm/dts/bcm2835-rpi.dtsi index 715d50c6452..87ddcad7608 100644 --- a/arch/arm/dts/bcm2835-rpi.dtsi +++ b/arch/arm/dts/bcm2835-rpi.dtsi @@ -1,15 +1,10 @@ #include <dt-bindings/power/raspberrypi-power.h>
/ { - memory@0 { - device_type = "memory"; - reg = <0 0x10000000>; - }; - leds { compatible = "gpio-leds";
- act { + led-act { label = "ACT"; default-state = "keep"; linux,default-trigger = "heartbeat"; @@ -18,8 +13,12 @@
soc { firmware: firmware { - compatible = "raspberrypi,bcm2835-firmware", "simple-bus"; + compatible = "raspberrypi,bcm2835-firmware", "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + mboxes = <&mailbox>; + dma-ranges; };
power: power { @@ -64,32 +63,10 @@ clock-frequency = <100000>; };
-&i2c2 { - status = "okay"; -}; - -&sdhci { - pinctrl-names = "default"; - pinctrl-0 = <&emmc_gpio48>; - bus-width = <4>; -}; - -&sdhost { - pinctrl-names = "default"; - pinctrl-0 = <&sdhost_gpio48>; - status = "okay"; - bus-width = <4>; -}; - &usb { power-domains = <&power RPI_POWER_DOMAIN_USB>; };
-&hdmi { - power-domains = <&power RPI_POWER_DOMAIN_HDMI>; - status = "okay"; -}; - &vec { power-domains = <&power RPI_POWER_DOMAIN_VEC>; status = "okay"; diff --git a/arch/arm/dts/bcm2835.dtsi b/arch/arm/dts/bcm2835.dtsi index a5c3824c805..0549686134e 100644 --- a/arch/arm/dts/bcm2835.dtsi +++ b/arch/arm/dts/bcm2835.dtsi @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "bcm283x.dtsi" +#include "bcm2835-common.dtsi" +#include "bcm2835-rpi-common.dtsi"
/ { compatible = "brcm,bcm2835"; diff --git a/arch/arm/dts/bcm2836-rpi-2-b.dts b/arch/arm/dts/bcm2836-rpi-2-b.dts index 7b4e651bafd..d8af8eeac7b 100644 --- a/arch/arm/dts/bcm2836-rpi-2-b.dts +++ b/arch/arm/dts/bcm2836-rpi-2-b.dts @@ -10,15 +10,16 @@ model = "Raspberry Pi 2 Model B";
memory@0 { + device_type = "memory"; reg = <0 0x40000000>; };
leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; };
- pwr { + led-pwr { label = "PWR"; gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; default-state = "keep"; @@ -105,6 +106,8 @@
&hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { @@ -113,6 +116,13 @@ status = "okay"; };
+&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_gpio14>; diff --git a/arch/arm/dts/bcm2836.dtsi b/arch/arm/dts/bcm2836.dtsi index c933e841388..b390006aef7 100644 --- a/arch/arm/dts/bcm2836.dtsi +++ b/arch/arm/dts/bcm2836.dtsi @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "bcm283x.dtsi" +#include "bcm2835-common.dtsi" +#include "bcm2835-rpi-common.dtsi"
/ { compatible = "brcm,bcm2836"; diff --git a/arch/arm/dts/bcm2837-rpi-3-a-plus.dts b/arch/arm/dts/bcm2837-rpi-3-a-plus.dts index 7f4437a8eed..77099a7871b 100644 --- a/arch/arm/dts/bcm2837-rpi-3-a-plus.dts +++ b/arch/arm/dts/bcm2837-rpi-3-a-plus.dts @@ -14,17 +14,20 @@ };
memory@0 { + device_type = "memory"; reg = <0 0x20000000>; };
leds { - act { + led-act { gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; };
- pwr { + led-pwr { label = "PWR"; gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + default-state = "keep"; + linux,default-trigger = "default-on"; }; }; }; @@ -117,6 +120,8 @@
&hdmi { hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { diff --git a/arch/arm/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/dts/bcm2837-rpi-3-b-plus.dts index c6fa34c2410..61010266ca9 100644 --- a/arch/arm/dts/bcm2837-rpi-3-b-plus.dts +++ b/arch/arm/dts/bcm2837-rpi-3-b-plus.dts @@ -15,17 +15,20 @@ };
memory@0 { + device_type = "memory"; reg = <0 0x40000000>; };
leds { - act { + led-act { gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; };
- pwr { + led-pwr { label = "PWR"; gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + default-state = "keep"; + linux,default-trigger = "default-on"; }; };
@@ -124,6 +127,8 @@
&hdmi { hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
&pwm { diff --git a/arch/arm/dts/bcm2837-rpi-3-b.dts b/arch/arm/dts/bcm2837-rpi-3-b.dts index ce71f578c51..dd4a4860409 100644 --- a/arch/arm/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/dts/bcm2837-rpi-3-b.dts @@ -15,11 +15,12 @@ };
memory@0 { + device_type = "memory"; reg = <0 0x40000000>; };
leds { - act { + led-act { gpios = <&expgpio 2 GPIO_ACTIVE_HIGH>; }; }; @@ -125,6 +126,8 @@
&hdmi { hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; };
/* uart0 communicates with the BT module */ diff --git a/arch/arm/dts/bcm2837-rpi-cm3-io3.dts b/arch/arm/dts/bcm2837-rpi-cm3-io3.dts index 6c8233a36d8..588d9411ceb 100644 --- a/arch/arm/dts/bcm2837-rpi-cm3-io3.dts +++ b/arch/arm/dts/bcm2837-rpi-cm3-io3.dts @@ -78,6 +78,15 @@
&hdmi { hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; +}; + +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; };
&uart0 { diff --git a/arch/arm/dts/bcm2837-rpi-cm3.dtsi b/arch/arm/dts/bcm2837-rpi-cm3.dtsi index 81399b2c5af..828a20561b9 100644 --- a/arch/arm/dts/bcm2837-rpi-cm3.dtsi +++ b/arch/arm/dts/bcm2837-rpi-cm3.dtsi @@ -5,9 +5,18 @@
/ { memory@0 { + device_type = "memory"; reg = <0 0x40000000>; };
+ leds { + /* + * Since there is no upstream GPIO driver yet, + * remove the incomplete node. + */ + /delete-node/ led-act; + }; + reg_3v3: fixed-regulator { compatible = "regulator-fixed"; regulator-name = "3V3"; diff --git a/arch/arm/dts/bcm2837.dtsi b/arch/arm/dts/bcm2837.dtsi index beb6c502dad..0199ec98cd6 100644 --- a/arch/arm/dts/bcm2837.dtsi +++ b/arch/arm/dts/bcm2837.dtsi @@ -1,4 +1,6 @@ #include "bcm283x.dtsi" +#include "bcm2835-common.dtsi" +#include "bcm2835-rpi-common.dtsi"
/ { compatible = "brcm,bcm2837"; diff --git a/arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi b/arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi new file mode 100644 index 00000000000..0ff0e9e2532 --- /dev/null +++ b/arch/arm/dts/bcm283x-rpi-usb-peripheral.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +&usb { + dr_mode = "peripheral"; + g-rx-fifo-size = <256>; + g-np-tx-fifo-size = <32>; + g-tx-fifo-size = <256 256 512 512 512 768 768>; +}; diff --git a/arch/arm/dts/bcm283x.dtsi b/arch/arm/dts/bcm283x.dtsi index 9777644c6c2..a3e06b68094 100644 --- a/arch/arm/dts/bcm283x.dtsi +++ b/arch/arm/dts/bcm283x.dtsi @@ -18,7 +18,6 @@ / { compatible = "brcm,bcm2835"; model = "BCM2835"; - interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>;
@@ -31,16 +30,27 @@ stdout-path = "serial0:115200n8"; };
+ rmem: reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + cma: linux,cma { + compatible = "shared-dma-pool"; + size = <0x4000000>; /* 64MB */ + reusable; + linux,cma-default; + }; + }; + thermal-zones { cpu_thermal: cpu-thermal { polling-delay-passive = <0>; polling-delay = <1000>;
- thermal-sensors = <&thermal>; - trips { cpu-crit { - temperature = <80000>; + temperature = <90000>; hysteresis = <0>; type = "critical"; }; @@ -56,7 +66,7 @@ #address-cells = <1>; #size-cells = <1>;
- timer@7e003000 { + system_timer: timer@7e003000 { compatible = "brcm,bcm2835-system-timer"; reg = <0x7e003000 0x1000>; interrupts = <1 0>, <1 1>, <1 2>, <1 3>; @@ -67,74 +77,12 @@ clock-frequency = <1000000>; };
- txp@7e004000 { + txp: txp@7e004000 { compatible = "brcm,bcm2835-txp"; reg = <0x7e004000 0x20>; interrupts = <1 11>; };
- dma: dma@7e007000 { - compatible = "brcm,bcm2835-dma"; - reg = <0x7e007000 0xf00>; - interrupts = <1 16>, - <1 17>, - <1 18>, - <1 19>, - <1 20>, - <1 21>, - <1 22>, - <1 23>, - <1 24>, - <1 25>, - <1 26>, - /* dma channel 11-14 share one irq */ - <1 27>, - <1 27>, - <1 27>, - <1 27>, - /* unused shared irq for all channels */ - <1 28>; - interrupt-names = "dma0", - "dma1", - "dma2", - "dma3", - "dma4", - "dma5", - "dma6", - "dma7", - "dma8", - "dma9", - "dma10", - "dma11", - "dma12", - "dma13", - "dma14", - "dma-shared-all"; - #dma-cells = <1>; - brcm,dma-channel-mask = <0x7f35>; - }; - - intc: interrupt-controller@7e00b200 { - compatible = "brcm,bcm2835-armctrl-ic"; - reg = <0x7e00b200 0x200>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pm: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; - #power-domain-cells = <1>; - #reset-cells = <1>; - reg = <0x7e100000 0x114>, - <0x7e00a000 0x24>; - clocks = <&clocks BCM2835_CLOCK_V3D>, - <&clocks BCM2835_CLOCK_PERI_IMAGE>, - <&clocks BCM2835_CLOCK_H264>, - <&clocks BCM2835_CLOCK_ISP>; - clock-names = "v3d", "peri_image", "h264", "isp"; - system-power-controller; - }; - clocks: cprman@7e101000 { compatible = "brcm,bcm2835-cprman"; #clock-cells = <1>; @@ -149,12 +97,6 @@ <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; };
- rng@7e104000 { - compatible = "brcm,bcm2835-rng"; - reg = <0x7e104000 0x10>; - interrupts = <2 29>; - }; - mailbox: mailbox@7e00b880 { compatible = "brcm,bcm2835-mbox"; reg = <0x7e00b880 0x40>; @@ -184,8 +126,7 @@ interrupt-controller; #interrupt-cells = <2>;
- /* Defines pin muxing groups according to - * BCM2835-ARM-Peripherals.pdf page 102. + /* Defines common pin muxing groups * * While each pin can have its mux selected * for various functions individually, some @@ -263,15 +204,7 @@ brcm,pins = <44 45>; brcm,function = <BCM2835_FSEL_ALT2>; }; - i2c_slave_gpio18: i2c_slave_gpio18 { - brcm,pins = <18 19 20 21>; - brcm,function = <BCM2835_FSEL_ALT3>; - };
- jtag_gpio4: jtag_gpio4 { - brcm,pins = <4 5 6 12 13>; - brcm,function = <BCM2835_FSEL_ALT5>; - }; jtag_gpio22: jtag_gpio22 { brcm,pins = <22 23 24 25 26 27>; brcm,function = <BCM2835_FSEL_ALT4>; @@ -286,35 +219,6 @@ brcm,function = <BCM2835_FSEL_ALT2>; };
- pwm0_gpio12: pwm0_gpio12 { - brcm,pins = <12>; - brcm,function = <BCM2835_FSEL_ALT0>; - }; - pwm0_gpio18: pwm0_gpio18 { - brcm,pins = <18>; - brcm,function = <BCM2835_FSEL_ALT5>; - }; - pwm0_gpio40: pwm0_gpio40 { - brcm,pins = <40>; - brcm,function = <BCM2835_FSEL_ALT0>; - }; - pwm1_gpio13: pwm1_gpio13 { - brcm,pins = <13>; - brcm,function = <BCM2835_FSEL_ALT0>; - }; - pwm1_gpio19: pwm1_gpio19 { - brcm,pins = <19>; - brcm,function = <BCM2835_FSEL_ALT5>; - }; - pwm1_gpio41: pwm1_gpio41 { - brcm,pins = <41>; - brcm,function = <BCM2835_FSEL_ALT0>; - }; - pwm1_gpio45: pwm1_gpio45 { - brcm,pins = <45>; - brcm,function = <BCM2835_FSEL_ALT0>; - }; - sdhost_gpio48: sdhost_gpio48 { brcm,pins = <48 49 50 51 52 53>; brcm,function = <BCM2835_FSEL_ALT0>; @@ -396,8 +300,8 @@ };
uart0: serial@7e201000 { - compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; + compatible = "arm,pl011", "arm,primecell"; + reg = <0x7e201000 0x200>; interrupts = <2 25>; clocks = <&clocks BCM2835_CLOCK_UART>, <&clocks BCM2835_CLOCK_VPU>; @@ -410,8 +314,6 @@ reg = <0x7e202000 0x100>; interrupts = <2 24>; clocks = <&clocks BCM2835_CLOCK_VPU>; - dmas = <&dma 13>; - dma-names = "rx-tx"; status = "disabled"; };
@@ -419,16 +321,12 @@ compatible = "brcm,bcm2835-i2s"; reg = <0x7e203000 0x24>; clocks = <&clocks BCM2835_CLOCK_PCM>; - - dmas = <&dma 2>, - <&dma 3>; - dma-names = "tx", "rx"; status = "disabled"; };
spi: spi@7e204000 { compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; + reg = <0x7e204000 0x200>; interrupts = <2 22>; clocks = <&clocks BCM2835_CLOCK_VPU>; #address-cells = <1>; @@ -438,7 +336,7 @@
i2c0: i2c@7e205000 { compatible = "brcm,bcm2835-i2c"; - reg = <0x7e205000 0x1000>; + reg = <0x7e205000 0x200>; interrupts = <2 21>; clocks = <&clocks BCM2835_CLOCK_VPU>; #address-cells = <1>; @@ -446,18 +344,6 @@ status = "disabled"; };
- pixelvalve@7e206000 { - compatible = "brcm,bcm2835-pixelvalve0"; - reg = <0x7e206000 0x100>; - interrupts = <2 13>; /* pwa0 */ - }; - - pixelvalve@7e207000 { - compatible = "brcm,bcm2835-pixelvalve1"; - reg = <0x7e207000 0x100>; - interrupts = <2 14>; /* pwa1 */ - }; - dpi: dpi@7e208000 { compatible = "brcm,bcm2835-dpi"; reg = <0x7e208000 0x8c>; @@ -486,13 +372,6 @@ "dsi0_ddr2", "dsi0_ddr";
- }; - - thermal: thermal@7e212000 { - compatible = "brcm,bcm2835-thermal"; - reg = <0x7e212000 0x8>; - clocks = <&clocks BCM2835_CLOCK_TSENS>; - #thermal-sensor-cells = <0>; status = "disabled"; };
@@ -541,7 +420,7 @@ status = "disabled"; };
- sdhci: sdhci@7e300000 { + sdhci: mmc@7e300000 { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; interrupts = <2 30>; @@ -585,44 +464,6 @@ status = "disabled"; };
- i2c2: i2c@7e805000 { - compatible = "brcm,bcm2835-i2c"; - reg = <0x7e805000 0x1000>; - interrupts = <2 21>; - clocks = <&clocks BCM2835_CLOCK_VPU>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - vec: vec@7e806000 { - compatible = "brcm,bcm2835-vec"; - reg = <0x7e806000 0x1000>; - clocks = <&clocks BCM2835_CLOCK_VEC>; - interrupts = <2 27>; - status = "disabled"; - }; - - pixelvalve@7e807000 { - compatible = "brcm,bcm2835-pixelvalve2"; - reg = <0x7e807000 0x100>; - interrupts = <2 10>; /* pixelvalve */ - }; - - hdmi: hdmi@7e902000 { - compatible = "brcm,bcm2835-hdmi"; - reg = <0x7e902000 0x600>, - <0x7e808000 0x100>; - interrupts = <2 8>, <2 9>; - ddc = <&i2c2>; - clocks = <&clocks BCM2835_PLLH_PIX>, - <&clocks BCM2835_CLOCK_HSM>; - clock-names = "pixel", "hdmi"; - dmas = <&dma 17>; - dma-names = "audio-rx"; - status = "disabled"; - }; - usb: usb@7e980000 { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; @@ -634,36 +475,19 @@ phys = <&usbphy>; phy-names = "usb2-phy"; }; - - v3d: v3d@7ec00000 { - compatible = "brcm,bcm2835-v3d"; - reg = <0x7ec00000 0x1000>; - interrupts = <1 10>; - power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>; - }; - - vc4: gpu { - compatible = "brcm,bcm2835-vc4"; - }; };
clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - /* The oscillator is the root of the clock tree. */ - clk_osc: clock@3 { + clk_osc: clk-osc { compatible = "fixed-clock"; - reg = <3>; #clock-cells = <0>; clock-output-names = "osc"; clock-frequency = <19200000>; };
- clk_usb: clock@4 { + clk_usb: clk-usb { compatible = "fixed-clock"; - reg = <4>; #clock-cells = <0>; clock-output-names = "otg"; clock-frequency = <480000000>; diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig index 88f7504a60f..0d534b8a28d 100644 --- a/configs/rpi_4_32b_defconfig +++ b/configs/rpi_4_32b_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x00008000 CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_TARGET_RPI_4_32B=y CONFIG_ENV_SIZE=0x4000 +CONFIG_DEFAULT_DEVICE_TREE="bcm2711-rpi-4-b" CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x1000000 CONFIG_OF_BOARD_SETUP=y diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig index 59a71031540..0b3cadaced2 100644 --- a/configs/rpi_4_defconfig +++ b/configs/rpi_4_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x00080000 CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_TARGET_RPI_4=y CONFIG_ENV_SIZE=0x4000 +CONFIG_DEFAULT_DEVICE_TREE="bcm2711-rpi-4-b" CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x1000000 CONFIG_OF_BOARD_SETUP=y diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig index 67dbf094ef7..07f67394ac2 100644 --- a/configs/rpi_arm64_defconfig +++ b/configs/rpi_arm64_defconfig @@ -6,6 +6,7 @@ CONFIG_TARGET_RPI_ARM64=y CONFIG_ENV_SIZE=0x4000 CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x1000000 +CONFIG_DEFAULT_DEVICE_TREE="bcm2711-rpi-4-b" CONFIG_OF_BOARD_SETUP=y CONFIG_USE_PREBOOT=y CONFIG_PREBOOT="pci enum; usb start;" diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h index 2cec01f9689..b60c03430cf 100644 --- a/include/dt-bindings/clock/bcm2835.h +++ b/include/dt-bindings/clock/bcm2835.h @@ -58,3 +58,5 @@ #define BCM2835_CLOCK_DSI1E 48 #define BCM2835_CLOCK_DSI0P 49 #define BCM2835_CLOCK_DSI1P 50 + +#define BCM2711_CLOCK_EMMC2 51

Sync these file, obtained from Linux v5.15.
Add a note for the maintainer, and SPDX lines where they are missing. The added lines are:
SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
Note, this matches the text in those files, but is not the same as the GPL-2.0 of some files.
[1] https://releases.linaro.org/android/reference-lcr/juno/7.1-17.05/
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Bring in files from Linux instead - Rewrite the commit message
arch/arm/dts/Makefile | 3 + arch/arm/dts/juno-base.dtsi | 831 +++++++++++++++++++++++++ arch/arm/dts/juno-clocks.dtsi | 46 ++ arch/arm/dts/juno-cs-r1r2.dtsi | 85 +++ arch/arm/dts/juno-motherboard.dtsi | 303 +++++++++ arch/arm/dts/juno-r2.dts | 322 ++++++++++ configs/vexpress_aemv8a_juno_defconfig | 1 + 7 files changed, 1591 insertions(+) create mode 100644 arch/arm/dts/juno-base.dtsi create mode 100644 arch/arm/dts/juno-clocks.dtsi create mode 100644 arch/arm/dts/juno-cs-r1r2.dtsi create mode 100644 arch/arm/dts/juno-motherboard.dtsi create mode 100644 arch/arm/dts/juno-r2.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 9cddab37207..d53bae2c350 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1149,7 +1149,10 @@ dtb-$(CONFIG_TARGET_GE_BX50V3) += \ dtb-$(CONFIG_TARGET_GE_B1X5V2) += imx6dl-b1x5v2.dtb dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
+# TODO(Linus Walleij linus.walleij@linaro.org): Should us a single vexpress +# Kconfig option to build all of these. See examples above. dtb-$(CONFIG_TARGET_VEXPRESS_CA9X4) += vexpress-v2p-ca9.dtb +dtb-$(CONFIG_TARGET_VEXPRESS64_JUNO) += juno-r2.dtb
dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
diff --git a/arch/arm/dts/juno-base.dtsi b/arch/arm/dts/juno-base.dtsi new file mode 100644 index 00000000000..6288e104a08 --- /dev/null +++ b/arch/arm/dts/juno-base.dtsi @@ -0,0 +1,831 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "juno-clocks.dtsi" +#include "juno-motherboard.dtsi" + +/ { + /* + * Devices shared by all Juno boards + */ + + memtimer: timer@2a810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x2a810000 0x0 0x10000>; + clock-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x2a820000 0x20000>; + status = "disabled"; + frame@2a830000 { + frame-number = <1>; + interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x10000 0x10000>; + }; + }; + + mailbox: mhu@2b1f0000 { + compatible = "arm,mhu", "arm,primecell"; + reg = <0x0 0x2b1f0000 0x0 0x1000>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <1>; + clocks = <&soc_refclk100mhz>; + clock-names = "apb_pclk"; + }; + + smmu_gpu: iommu@2b400000 { + compatible = "arm,mmu-400", "arm,smmu-v1"; + reg = <0x0 0x2b400000 0x0 0x10000>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + power-domains = <&scpi_devpd 1>; + dma-coherent; + status = "disabled"; + }; + + smmu_pcie: iommu@2b500000 { + compatible = "arm,mmu-401", "arm,smmu-v1"; + reg = <0x0 0x2b500000 0x0 0x10000>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + dma-coherent; + status = "disabled"; + }; + + smmu_etr: iommu@2b600000 { + compatible = "arm,mmu-401", "arm,smmu-v1"; + reg = <0x0 0x2b600000 0x0 0x10000>; + interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + dma-coherent; + power-domains = <&scpi_devpd 0>; + }; + + gic: interrupt-controller@2c010000 { + compatible = "arm,gic-400", "arm,cortex-a15-gic"; + reg = <0x0 0x2c010000 0 0x1000>, + <0x0 0x2c02f000 0 0x2000>, + <0x0 0x2c04f000 0 0x2000>, + <0x0 0x2c06f000 0 0x2000>; + #address-cells = <1>; + #interrupt-cells = <3>; + #size-cells = <1>; + interrupt-controller; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>; + ranges = <0 0 0x2c1c0000 0x40000>; + + v2m_0: v2m@0 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0 0x10000>; + }; + + v2m@10000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x10000 0x10000>; + }; + + v2m@20000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x20000 0x10000>; + }; + + v2m@30000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x30000 0x10000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + }; + + /* + * Juno TRMs specify the size for these coresight components as 64K. + * The actual size is just 4K though 64K is reserved. Access to the + * unmapped reserved region results in a DECERR response. + */ + etf@20010000 { /* etf0 */ + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0 0x20010000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + + in-ports { + port { + etf0_in_port: endpoint { + remote-endpoint = <&main_funnel_out_port>; + }; + }; + }; + + out-ports { + port { + etf0_out_port: endpoint { + }; + }; + }; + }; + + tpiu@20030000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + reg = <0 0x20030000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + in-ports { + port { + tpiu_in_port: endpoint { + remote-endpoint = <&replicator_out_port0>; + }; + }; + }; + }; + + /* main funnel on Juno r0, cssys0 funnel on Juno r1/r2 as per TRM*/ + main_funnel: funnel@20040000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x20040000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + + out-ports { + port { + main_funnel_out_port: endpoint { + remote-endpoint = <&etf0_in_port>; + }; + }; + }; + + main_funnel_in_ports: in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + main_funnel_in_port0: endpoint { + remote-endpoint = <&cluster0_funnel_out_port>; + }; + }; + + port@1 { + reg = <1>; + main_funnel_in_port1: endpoint { + remote-endpoint = <&cluster1_funnel_out_port>; + }; + }; + }; + }; + + etr@20070000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0 0x20070000 0 0x1000>; + iommus = <&smmu_etr 0>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + arm,scatter-gather; + in-ports { + port { + etr_in_port: endpoint { + remote-endpoint = <&replicator_out_port1>; + }; + }; + }; + }; + + stm@20100000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0 0x20100000 0 0x1000>, + <0 0x28000000 0 0x1000000>; + reg-names = "stm-base", "stm-stimulus-base"; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + stm_out_port: endpoint { + }; + }; + }; + }; + + replicator@20120000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0 0x20120000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + /* replicator output ports */ + port@0 { + reg = <0>; + replicator_out_port0: endpoint { + remote-endpoint = <&tpiu_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator_out_port1: endpoint { + remote-endpoint = <&etr_in_port>; + }; + }; + }; + in-ports { + port { + replicator_in_port0: endpoint { + }; + }; + }; + }; + + cpu_debug0: cpu-debug@22010000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x0 0x22010000 0x0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + }; + + etm0: etm@22040000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x22040000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster0_etm0_out_port: endpoint { + remote-endpoint = <&cluster0_funnel_in_port0>; + }; + }; + }; + }; + + funnel@220c0000 { /* cluster0 funnel */ + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x220c0000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster0_funnel_out_port: endpoint { + remote-endpoint = <&main_funnel_in_port0>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + cluster0_funnel_in_port0: endpoint { + remote-endpoint = <&cluster0_etm0_out_port>; + }; + }; + + port@1 { + reg = <1>; + cluster0_funnel_in_port1: endpoint { + remote-endpoint = <&cluster0_etm1_out_port>; + }; + }; + }; + }; + + cpu_debug1: cpu-debug@22110000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x0 0x22110000 0x0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + }; + + etm1: etm@22140000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x22140000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster0_etm1_out_port: endpoint { + remote-endpoint = <&cluster0_funnel_in_port1>; + }; + }; + }; + }; + + cpu_debug2: cpu-debug@23010000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x0 0x23010000 0x0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + }; + + etm2: etm@23040000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x23040000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster1_etm0_out_port: endpoint { + remote-endpoint = <&cluster1_funnel_in_port0>; + }; + }; + }; + }; + + funnel@230c0000 { /* cluster1 funnel */ + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x230c0000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster1_funnel_out_port: endpoint { + remote-endpoint = <&main_funnel_in_port1>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + cluster1_funnel_in_port0: endpoint { + remote-endpoint = <&cluster1_etm0_out_port>; + }; + }; + + port@1 { + reg = <1>; + cluster1_funnel_in_port1: endpoint { + remote-endpoint = <&cluster1_etm1_out_port>; + }; + }; + port@2 { + reg = <2>; + cluster1_funnel_in_port2: endpoint { + remote-endpoint = <&cluster1_etm2_out_port>; + }; + }; + port@3 { + reg = <3>; + cluster1_funnel_in_port3: endpoint { + remote-endpoint = <&cluster1_etm3_out_port>; + }; + }; + }; + }; + + cpu_debug3: cpu-debug@23110000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x0 0x23110000 0x0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + }; + + etm3: etm@23140000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x23140000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster1_etm1_out_port: endpoint { + remote-endpoint = <&cluster1_funnel_in_port1>; + }; + }; + }; + }; + + cpu_debug4: cpu-debug@23210000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x0 0x23210000 0x0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + }; + + etm4: etm@23240000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x23240000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster1_etm2_out_port: endpoint { + remote-endpoint = <&cluster1_funnel_in_port2>; + }; + }; + }; + }; + + cpu_debug5: cpu-debug@23310000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x0 0x23310000 0x0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + }; + + etm5: etm@23340000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x23340000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + cluster1_etm3_out_port: endpoint { + remote-endpoint = <&cluster1_funnel_in_port3>; + }; + }; + }; + }; + + gpu: gpu@2d000000 { + compatible = "arm,juno-mali", "arm,mali-t624"; + reg = <0 0x2d000000 0 0x10000>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&scpi_dvfs 2>; + power-domains = <&scpi_devpd 1>; + dma-coherent; + /* The SMMU is only really of interest to bare-metal hypervisors */ + /* iommus = <&smmu_gpu 0>; */ + status = "disabled"; + }; + + sram: sram@2e000000 { + compatible = "arm,juno-sram-ns", "mmio-sram"; + reg = <0x0 0x2e000000 0x0 0x8000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x2e000000 0x8000>; + + cpu_scp_lpri: scp-sram@0 { + compatible = "arm,juno-scp-shmem"; + reg = <0x0 0x200>; + }; + + cpu_scp_hpri: scp-sram@200 { + compatible = "arm,juno-scp-shmem"; + reg = <0x200 0x200>; + }; + }; + + pcie_ctlr: pcie@40000000 { + compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; + device_type = "pci"; + reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ + bus-range = <0 255>; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x00000000 0x00 0x5f800000 0x0 0x00800000>, + <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, + <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; + /* Standard AXI Translation entries as programmed by EDK2 */ + dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>, + <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>, + <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; + msi-parent = <&v2m_0>; + status = "disabled"; + iommu-map-mask = <0x0>; /* RC has no means to output PCI RID */ + iommu-map = <0x0 &smmu_pcie 0x0 0x1>; + }; + + scpi { + compatible = "arm,scpi"; + mboxes = <&mailbox 1>; + shmem = <&cpu_scp_hpri>; + + clocks { + compatible = "arm,scpi-clocks"; + + scpi_dvfs: clocks-0 { + compatible = "arm,scpi-dvfs-clocks"; + #clock-cells = <1>; + clock-indices = <0>, <1>, <2>; + clock-output-names = "atlclk", "aplclk","gpuclk"; + }; + scpi_clk: clocks-1 { + compatible = "arm,scpi-variable-clocks"; + #clock-cells = <1>; + clock-indices = <3>; + clock-output-names = "pxlclk"; + }; + }; + + scpi_devpd: power-controller { + compatible = "arm,scpi-power-domains"; + num-domains = <2>; + #power-domain-cells = <1>; + }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; + }; + + thermal-zones { + pmic { + polling-delay = <1000>; + polling-delay-passive = <100>; + thermal-sensors = <&scpi_sensors0 0>; + }; + + soc { + polling-delay = <1000>; + polling-delay-passive = <100>; + thermal-sensors = <&scpi_sensors0 3>; + }; + + big_cluster_thermal_zone: big-cluster { + polling-delay = <1000>; + polling-delay-passive = <100>; + thermal-sensors = <&scpi_sensors0 21>; + status = "disabled"; + }; + + little_cluster_thermal_zone: little-cluster { + polling-delay = <1000>; + polling-delay-passive = <100>; + thermal-sensors = <&scpi_sensors0 22>; + status = "disabled"; + }; + + gpu0_thermal_zone: gpu0 { + polling-delay = <1000>; + polling-delay-passive = <100>; + thermal-sensors = <&scpi_sensors0 23>; + status = "disabled"; + }; + + gpu1_thermal_zone: gpu1 { + polling-delay = <1000>; + polling-delay-passive = <100>; + thermal-sensors = <&scpi_sensors0 24>; + status = "disabled"; + }; + }; + + smmu_dma: iommu@7fb00000 { + compatible = "arm,mmu-401", "arm,smmu-v1"; + reg = <0x0 0x7fb00000 0x0 0x10000>; + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + dma-coherent; + }; + + smmu_hdlcd1: iommu@7fb10000 { + compatible = "arm,mmu-401", "arm,smmu-v1"; + reg = <0x0 0x7fb10000 0x0 0x10000>; + interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + }; + + smmu_hdlcd0: iommu@7fb20000 { + compatible = "arm,mmu-401", "arm,smmu-v1"; + reg = <0x0 0x7fb20000 0x0 0x10000>; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + }; + + smmu_usb: iommu@7fb30000 { + compatible = "arm,mmu-401", "arm,smmu-v1"; + reg = <0x0 0x7fb30000 0x0 0x10000>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + #global-interrupts = <1>; + dma-coherent; + }; + + dma@7ff00000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0x7ff00000 0 0x1000>; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; + interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&smmu_dma 0>, + <&smmu_dma 1>, + <&smmu_dma 2>, + <&smmu_dma 3>, + <&smmu_dma 4>, + <&smmu_dma 5>, + <&smmu_dma 6>, + <&smmu_dma 7>, + <&smmu_dma 8>; + clocks = <&soc_faxiclk>; + clock-names = "apb_pclk"; + }; + + hdlcd@7ff50000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff50000 0 0x1000>; + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&smmu_hdlcd1 0>; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd1_output: endpoint { + remote-endpoint = <&tda998x_1_input>; + }; + }; + }; + + hdlcd@7ff60000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff60000 0 0x1000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&smmu_hdlcd0 0>; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd0_output: endpoint { + remote-endpoint = <&tda998x_0_input>; + }; + }; + }; + + soc_uart0: serial@7ff80000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x7ff80000 0x0 0x1000>; + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&soc_uartclk>, <&soc_refclk100mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + i2c@7ffa0000 { + compatible = "snps,designware-i2c"; + reg = <0x0 0x7ffa0000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <400000>; + i2c-sda-hold-time-ns = <500>; + clocks = <&soc_smc50mhz>; + + hdmi-transmitter@70 { + compatible = "nxp,tda998x"; + reg = <0x70>; + port { + tda998x_0_input: endpoint { + remote-endpoint = <&hdlcd0_output>; + }; + }; + }; + + hdmi-transmitter@71 { + compatible = "nxp,tda998x"; + reg = <0x71>; + port { + tda998x_1_input: endpoint { + remote-endpoint = <&hdlcd1_output>; + }; + }; + }; + }; + + usb@7ffb0000 { + compatible = "generic-ohci"; + reg = <0x0 0x7ffb0000 0x0 0x10000>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&smmu_usb 0>; + clocks = <&soc_usb48mhz>; + }; + + usb@7ffc0000 { + compatible = "generic-ehci"; + reg = <0x0 0x7ffc0000 0x0 0x10000>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&smmu_usb 0>; + clocks = <&soc_usb48mhz>; + }; + + memory-controller@7ffd0000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0 0x7ffd0000 0 0x1000>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + }; + + memory@80000000 { + device_type = "memory"; + /* last 16MB of the first memory area is reserved for secure world use by firmware */ + reg = <0x00000000 0x80000000 0x0 0x7f000000>, + <0x00000008 0x80000000 0x1 0x80000000>; + }; + + bus@8000000 { + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 15>; + interrupt-map = <0 0 0 &gic 0 GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, + <0 0 1 &gic 0 GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, + <0 0 2 &gic 0 GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, + <0 0 3 &gic 0 GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, + <0 0 4 &gic 0 GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, + <0 0 5 &gic 0 GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <0 0 6 &gic 0 GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <0 0 7 &gic 0 GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <0 0 8 &gic 0 GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <0 0 9 &gic 0 GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, + <0 0 10 &gic 0 GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, + <0 0 11 &gic 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <0 0 12 &gic 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + }; + + site2: tlx-bus@60000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x60000000 0x10000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0>; + interrupt-map = <0 0 &gic 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>; + }; +}; diff --git a/arch/arm/dts/juno-clocks.dtsi b/arch/arm/dts/juno-clocks.dtsi new file mode 100644 index 00000000000..b0f8ccaac9e --- /dev/null +++ b/arch/arm/dts/juno-clocks.dtsi @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * ARM Juno Platform clocks + * + * Copyright (c) 2013-2014 ARM Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ +/ { + /* SoC fixed clocks */ + soc_uartclk: refclk7372800hz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <7372800>; + clock-output-names = "juno:uartclk"; + }; + + soc_usb48mhz: clk48mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + clock-output-names = "clk48mhz"; + }; + + soc_smc50mhz: clk50mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "smc_clk"; + }; + + soc_refclk100mhz: refclk100mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "apb_pclk"; + }; + + soc_faxiclk: refclk400mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <400000000>; + clock-output-names = "faxi_clk"; + }; +}; diff --git a/arch/arm/dts/juno-cs-r1r2.dtsi b/arch/arm/dts/juno-cs-r1r2.dtsi new file mode 100644 index 00000000000..eda3d9e18af --- /dev/null +++ b/arch/arm/dts/juno-cs-r1r2.dtsi @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 +/ { + funnel@20130000 { /* cssys1 */ + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x20130000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + csys1_funnel_out_port: endpoint { + remote-endpoint = <&etf1_in_port>; + }; + }; + }; + in-ports { + port { + csys1_funnel_in_port0: endpoint { + }; + }; + + }; + }; + + etf@20140000 { /* etf1 */ + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0 0x20140000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + in-ports { + port { + etf1_in_port: endpoint { + remote-endpoint = <&csys1_funnel_out_port>; + }; + }; + }; + out-ports { + port { + etf1_out_port: endpoint { + remote-endpoint = <&csys2_funnel_in_port1>; + }; + }; + }; + }; + + funnel@20150000 { /* cssys2 */ + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x20150000 0 0x1000>; + + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + power-domains = <&scpi_devpd 0>; + out-ports { + port { + csys2_funnel_out_port: endpoint { + remote-endpoint = <&replicator_in_port0>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csys2_funnel_in_port0: endpoint { + slave-mode; + remote-endpoint = <&etf0_out_port>; + }; + }; + + port@1 { + reg = <1>; + csys2_funnel_in_port1: endpoint { + slave-mode; + remote-endpoint = <&etf1_out_port>; + }; + }; + + }; + }; +}; diff --git a/arch/arm/dts/juno-motherboard.dtsi b/arch/arm/dts/juno-motherboard.dtsi new file mode 100644 index 00000000000..42b17542ab1 --- /dev/null +++ b/arch/arm/dts/juno-motherboard.dtsi @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * ARM Juno Platform motherboard peripherals + * + * Copyright (c) 2013-2014 ARM Ltd + * + * This file is licensed under a dual GPLv2 or BSD license. + * + */ + +/ { + mb_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "juno_mb:clk24mhz"; + }; + + mb_clk25mhz: clk25mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "juno_mb:clk25mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "juno_mb:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "juno_mb:refclk32khz"; + }; + + mb_fixed_3v3: mcc-sb-3v3 { + compatible = "regulator-fixed"; + regulator-name = "MCC_SB_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + gpio-keys { + compatible = "gpio-keys"; + + power-button { + debounce-interval = <50>; + wakeup-source; + linux,code = <116>; + label = "POWER"; + gpios = <&iofpga_gpio0 0 0x4>; + }; + home-button { + debounce-interval = <50>; + wakeup-source; + linux,code = <102>; + label = "HOME"; + gpios = <&iofpga_gpio0 1 0x4>; + }; + rlock-button { + debounce-interval = <50>; + wakeup-source; + linux,code = <152>; + label = "RLOCK"; + gpios = <&iofpga_gpio0 2 0x4>; + }; + vol-up-button { + debounce-interval = <50>; + wakeup-source; + linux,code = <115>; + label = "VOL+"; + gpios = <&iofpga_gpio0 3 0x4>; + }; + vol-down-button { + debounce-interval = <50>; + wakeup-source; + linux,code = <114>; + label = "VOL-"; + gpios = <&iofpga_gpio0 4 0x4>; + }; + nmi-button { + debounce-interval = <50>; + wakeup-source; + linux,code = <99>; + label = "NMI"; + gpios = <&iofpga_gpio0 5 0x4>; + }; + }; + + bus@8000000 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0x8000000 0 0x8000000 0x18000000>; + + motherboard-bus@8000000 { + compatible = "arm,vexpress,v2p-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + arm,hbi = <0x252>; + arm,vexpress,site = <0>; + + flash@0 { + /* 2 * 32MiB NOR Flash memory mounted on CS0 */ + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>; + bank-width = <4>; + /* + * Unfortunately, accessing the flash disturbs + * the CPU idle states (suspend) and CPU + * hotplug of the platform. For this reason, + * flash hardware access is disabled by default. + */ + status = "disabled"; + partitions { + compatible = "arm,arm-firmware-suite"; + }; + }; + + ethernet@200000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <2 0x00000000 0x10000>; + interrupts = <3>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + clocks = <&mb_clk25mhz>; + vdd33a-supply = <&mb_fixed_3v3>; + vddvario-supply = <&mb_fixed_3v3>; + }; + + iofpga-bus@300000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysctl: sysctl@20000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&mb_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>; + assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>; + }; + + apbregs@10000 { + compatible = "syscon", "simple-mfd"; + reg = <0x010000 0x1000>; + + led0 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x01>; + label = "vexpress:0"; + linux,default-trigger = "heartbeat"; + default-state = "on"; + }; + led1 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x02>; + label = "vexpress:1"; + linux,default-trigger = "mmc0"; + default-state = "off"; + }; + led2 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x04>; + label = "vexpress:2"; + linux,default-trigger = "cpu0"; + default-state = "off"; + }; + led3 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x08>; + label = "vexpress:3"; + linux,default-trigger = "cpu1"; + default-state = "off"; + }; + led4 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x10>; + label = "vexpress:4"; + linux,default-trigger = "cpu2"; + default-state = "off"; + }; + led5 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x20>; + label = "vexpress:5"; + linux,default-trigger = "cpu3"; + default-state = "off"; + }; + led6 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x40>; + label = "vexpress:6"; + default-state = "off"; + }; + led7 { + compatible = "register-bit-led"; + offset = <0x08>; + mask = <0x80>; + label = "vexpress:7"; + default-state = "off"; + }; + }; + + mmc@50000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <5>; + /* cd-gpios = <&v2m_mmc_gpios 0 0>; + wp-gpios = <&v2m_mmc_gpios 1 0>; */ + max-frequency = <12000000>; + vmmc-supply = <&mb_fixed_3v3>; + clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@60000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <8>; + clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@70000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <8>; + clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + watchdog@f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x10000>; + interrupts = <7>; + clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; + clock-names = "wdog_clk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x10000>; + interrupts = <9>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&mb_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x10000>; + interrupts = <9>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&mb_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x10000>; + interrupts = <0>; + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + }; + + iofpga_gpio0: gpio@1d0000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x1d0000 0x1000>; + interrupts = <6>; + clocks = <&soc_smc50mhz>; + clock-names = "apb_pclk"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + }; + }; +}; diff --git a/arch/arm/dts/juno-r2.dts b/arch/arm/dts/juno-r2.dts new file mode 100644 index 00000000000..52a6517d165 --- /dev/null +++ b/arch/arm/dts/juno-r2.dts @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * ARM Ltd. Juno Platform + * + * Copyright (c) 2015 ARM Ltd. + * + * This file is licensed under a dual GPLv2 or BSD license. + */ + +/dts-v1/; + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include "juno-base.dtsi" +#include "juno-cs-r1r2.dtsi" + +/ { + model = "ARM Juno development board (r2)"; + compatible = "arm,juno-r2", "arm,juno", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &soc_uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&A72_0>; + }; + core1 { + cpu = <&A72_1>; + }; + }; + + cluster1 { + core0 { + cpu = <&A53_0>; + }; + core1 { + cpu = <&A53_1>; + }; + core2 { + cpu = <&A53_2>; + }; + core3 { + cpu = <&A53_3>; + }; + }; + }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <400>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + + A72_0: cpu@0 { + compatible = "arm,cortex-a72"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <450>; + }; + + A72_1: cpu@1 { + compatible = "arm,cortex-a72"; + reg = <0x0 0x1>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <450>; + }; + + A53_0: cpu@100 { + compatible = "arm,cortex-a53"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <485>; + dynamic-power-coefficient = <140>; + }; + + A53_1: cpu@101 { + compatible = "arm,cortex-a53"; + reg = <0x0 0x101>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <485>; + dynamic-power-coefficient = <140>; + }; + + A53_2: cpu@102 { + compatible = "arm,cortex-a53"; + reg = <0x0 0x102>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <485>; + dynamic-power-coefficient = <140>; + }; + + A53_3: cpu@103 { + compatible = "arm,cortex-a53"; + reg = <0x0 0x103>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <485>; + dynamic-power-coefficient = <140>; + }; + + A72_L2: l2-cache0 { + compatible = "cache"; + cache-size = <0x200000>; + cache-line-size = <64>; + cache-sets = <2048>; + }; + + A53_L2: l2-cache1 { + compatible = "cache"; + cache-size = <0x100000>; + cache-line-size = <64>; + cache-sets = <1024>; + }; + }; + + pmu-a72 { + compatible = "arm,cortex-a72-pmu"; + interrupts = <GIC_SPI 02 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&A72_0>, + <&A72_1>; + }; + + pmu-a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&A53_0>, + <&A53_1>, + <&A53_2>, + <&A53_3>; + }; +}; + +&memtimer { + status = "okay"; +}; + +&pcie_ctlr { + status = "okay"; +}; + +&smmu_pcie { + status = "okay"; +}; + +&etm0 { + cpu = <&A72_0>; +}; + +&etm1 { + cpu = <&A72_1>; +}; + +&etm2 { + cpu = <&A53_0>; +}; + +&etm3 { + cpu = <&A53_1>; +}; + +&etm4 { + cpu = <&A53_2>; +}; + +&etm5 { + cpu = <&A53_3>; +}; + +&big_cluster_thermal_zone { + status = "okay"; +}; + +&little_cluster_thermal_zone { + status = "okay"; +}; + +&gpu0_thermal_zone { + status = "okay"; +}; + +&gpu1_thermal_zone { + status = "okay"; +}; + +&etf0_out_port { + remote-endpoint = <&csys2_funnel_in_port0>; +}; + +&replicator_in_port0 { + remote-endpoint = <&csys2_funnel_out_port>; +}; + +&csys1_funnel_in_port0 { + remote-endpoint = <&stm_out_port>; +}; + +&stm_out_port { + remote-endpoint = <&csys1_funnel_in_port0>; +}; + +&cpu_debug0 { + cpu = <&A72_0>; +}; + +&cpu_debug1 { + cpu = <&A72_1>; +}; + +&cpu_debug2 { + cpu = <&A53_0>; +}; + +&cpu_debug3 { + cpu = <&A53_1>; +}; + +&cpu_debug4 { + cpu = <&A53_2>; +}; + +&cpu_debug5 { + cpu = <&A53_3>; +}; diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig index f6ff0e0a569..0d9914c32bf 100644 --- a/configs/vexpress_aemv8a_juno_defconfig +++ b/configs/vexpress_aemv8a_juno_defconfig @@ -51,3 +51,4 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_GENERIC=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_GENERIC=y +CONFIG_DEFAULT_DEVICE_TREE="juno-r2"

On Tue, Dec 7, 2021 at 1:12 AM Simon Glass sjg@chromium.org wrote:
Sync these file, obtained from Linux v5.15.
Add a note for the maintainer, and SPDX lines where they are missing. The added lines are:
SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
Note, this matches the text in those files, but is not the same as the GPL-2.0 of some files.
[1] https://releases.linaro.org/android/reference-lcr/juno/7.1-17.05/
Signed-off-by: Simon Glass sjg@chromium.org
Overall fine!
But:
+++ b/arch/arm/dts/juno-motherboard.dtsi
(...)
bus@8000000 {
compatible = "simple-bus";
(...)
motherboard-bus@8000000 {
compatible = "arm,vexpress,v2p-p1", "simple-bus";
(...)
flash@0 {
/* 2 * 32MiB NOR Flash memory mounted on CS0 */
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>;
bank-width = <4>;
/*
* Unfortunately, accessing the flash disturbs
* the CPU idle states (suspend) and CPU
* hotplug of the platform. For this reason,
* flash hardware access is disabled by default.
*/
status = "disabled";
partitions {
compatible = "arm,arm-firmware-suite";
};
};
This should not be marked "disabled" in U-boot. The boot loader is not using some CPU idle states and hotplug but may be very interested in accessing the flash.
Yours, Linus Walleij

On Mon, 6 Dec 2021 17:11:46 -0700 Simon Glass sjg@chromium.org wrote:
Hi,
Sync these file, obtained from Linux v5.15.
So just for the records: Here you have the same problem as with the other platforms: There are three different revisions of the board, all out in the wild and heavily used. The platform firmware (some STM32 controller on the board) sorts out which board you have, and places the right DTB in the NOR flash. So by reading that from there, you get the correct information.
So as it stands right now, having the Juno DTBs in the tree does not help in any way, as they are not packaged. Actually just u-boot.bin is becoming part of the TF-A FIP image, and then this fip.bin is copied to the board's SD card, along with all three DTBs. I can write up some instructions on how to deploy the firmware on the board, if that helps.
If you want to tweak the DTB, for experimentation or testing, just copy something to the SD card, from where it gets automatically copied to the NOR flash on board bootup.
So I would rather just avoid the duplicated .dts copies in the U-Boot tree, given that they won't be used in any way.
Cheers, Andre
Add a note for the maintainer, and SPDX lines where they are missing. The added lines are:
SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
Note, this matches the text in those files, but is not the same as the GPL-2.0 of some files.
[1] https://releases.linaro.org/android/reference-lcr/juno/7.1-17.05/
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v7:
- Bring in files from Linux instead
- Rewrite the commit message
arch/arm/dts/Makefile | 3 + arch/arm/dts/juno-base.dtsi | 831 +++++++++++++++++++++++++ arch/arm/dts/juno-clocks.dtsi | 46 ++ arch/arm/dts/juno-cs-r1r2.dtsi | 85 +++ arch/arm/dts/juno-motherboard.dtsi | 303 +++++++++ arch/arm/dts/juno-r2.dts | 322 ++++++++++ configs/vexpress_aemv8a_juno_defconfig | 1 + 7 files changed, 1591 insertions(+) create mode 100644 arch/arm/dts/juno-base.dtsi create mode 100644 arch/arm/dts/juno-clocks.dtsi create mode 100644 arch/arm/dts/juno-cs-r1r2.dtsi create mode 100644 arch/arm/dts/juno-motherboard.dtsi create mode 100644 arch/arm/dts/juno-r2.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 9cddab37207..d53bae2c350 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1149,7 +1149,10 @@ dtb-$(CONFIG_TARGET_GE_BX50V3) += \ dtb-$(CONFIG_TARGET_GE_B1X5V2) += imx6dl-b1x5v2.dtb dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
+# TODO(Linus Walleij linus.walleij@linaro.org): Should us a single vexpress +# Kconfig option to build all of these. See examples above. dtb-$(CONFIG_TARGET_VEXPRESS_CA9X4) += vexpress-v2p-ca9.dtb +dtb-$(CONFIG_TARGET_VEXPRESS64_JUNO) += juno-r2.dtb
dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
diff --git a/arch/arm/dts/juno-base.dtsi b/arch/arm/dts/juno-base.dtsi new file mode 100644 index 00000000000..6288e104a08 --- /dev/null +++ b/arch/arm/dts/juno-base.dtsi @@ -0,0 +1,831 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "juno-clocks.dtsi" +#include "juno-motherboard.dtsi"
+/ {
- /*
* Devices shared by all Juno boards
*/
- memtimer: timer@2a810000 {
compatible = "arm,armv7-timer-mem";
reg = <0x0 0x2a810000 0x0 0x10000>;
clock-frequency = <50000000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x0 0x2a820000 0x20000>;
status = "disabled";
frame@2a830000 {
frame-number = <1>;
interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x10000 0x10000>;
};
- };
- mailbox: mhu@2b1f0000 {
compatible = "arm,mhu", "arm,primecell";
reg = <0x0 0x2b1f0000 0x0 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
#mbox-cells = <1>;
clocks = <&soc_refclk100mhz>;
clock-names = "apb_pclk";
- };
- smmu_gpu: iommu@2b400000 {
compatible = "arm,mmu-400", "arm,smmu-v1";
reg = <0x0 0x2b400000 0x0 0x10000>;
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
power-domains = <&scpi_devpd 1>;
dma-coherent;
status = "disabled";
- };
- smmu_pcie: iommu@2b500000 {
compatible = "arm,mmu-401", "arm,smmu-v1";
reg = <0x0 0x2b500000 0x0 0x10000>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
dma-coherent;
status = "disabled";
- };
- smmu_etr: iommu@2b600000 {
compatible = "arm,mmu-401", "arm,smmu-v1";
reg = <0x0 0x2b600000 0x0 0x10000>;
interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
dma-coherent;
power-domains = <&scpi_devpd 0>;
- };
- gic: interrupt-controller@2c010000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
reg = <0x0 0x2c010000 0 0x1000>,
<0x0 0x2c02f000 0 0x2000>,
<0x0 0x2c04f000 0 0x2000>,
<0x0 0x2c06f000 0 0x2000>;
#address-cells = <1>;
#interrupt-cells = <3>;
#size-cells = <1>;
interrupt-controller;
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
ranges = <0 0 0x2c1c0000 0x40000>;
v2m_0: v2m@0 {
compatible = "arm,gic-v2m-frame";
msi-controller;
reg = <0 0x10000>;
};
v2m@10000 {
compatible = "arm,gic-v2m-frame";
msi-controller;
reg = <0x10000 0x10000>;
};
v2m@20000 {
compatible = "arm,gic-v2m-frame";
msi-controller;
reg = <0x20000 0x10000>;
};
v2m@30000 {
compatible = "arm,gic-v2m-frame";
msi-controller;
reg = <0x30000 0x10000>;
};
- };
- timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
- };
- /*
* Juno TRMs specify the size for these coresight components as 64K.
* The actual size is just 4K though 64K is reserved. Access to the
* unmapped reserved region results in a DECERR response.
*/
- etf@20010000 { /* etf0 */
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0 0x20010000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
in-ports {
port {
etf0_in_port: endpoint {
remote-endpoint = <&main_funnel_out_port>;
};
};
};
out-ports {
port {
etf0_out_port: endpoint {
};
};
};
- };
- tpiu@20030000 {
compatible = "arm,coresight-tpiu", "arm,primecell";
reg = <0 0x20030000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
in-ports {
port {
tpiu_in_port: endpoint {
remote-endpoint = <&replicator_out_port0>;
};
};
};
- };
- /* main funnel on Juno r0, cssys0 funnel on Juno r1/r2 as per TRM*/
- main_funnel: funnel@20040000 {
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0 0x20040000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
main_funnel_out_port: endpoint {
remote-endpoint = <&etf0_in_port>;
};
};
};
main_funnel_in_ports: in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
main_funnel_in_port0: endpoint {
remote-endpoint = <&cluster0_funnel_out_port>;
};
};
port@1 {
reg = <1>;
main_funnel_in_port1: endpoint {
remote-endpoint = <&cluster1_funnel_out_port>;
};
};
};
- };
- etr@20070000 {
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0 0x20070000 0 0x1000>;
iommus = <&smmu_etr 0>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
arm,scatter-gather;
in-ports {
port {
etr_in_port: endpoint {
remote-endpoint = <&replicator_out_port1>;
};
};
};
- };
- stm@20100000 {
compatible = "arm,coresight-stm", "arm,primecell";
reg = <0 0x20100000 0 0x1000>,
<0 0x28000000 0 0x1000000>;
reg-names = "stm-base", "stm-stimulus-base";
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
stm_out_port: endpoint {
};
};
};
- };
- replicator@20120000 {
compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
reg = <0 0x20120000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
#address-cells = <1>;
#size-cells = <0>;
/* replicator output ports */
port@0 {
reg = <0>;
replicator_out_port0: endpoint {
remote-endpoint = <&tpiu_in_port>;
};
};
port@1 {
reg = <1>;
replicator_out_port1: endpoint {
remote-endpoint = <&etr_in_port>;
};
};
};
in-ports {
port {
replicator_in_port0: endpoint {
};
};
};
- };
- cpu_debug0: cpu-debug@22010000 {
compatible = "arm,coresight-cpu-debug", "arm,primecell";
reg = <0x0 0x22010000 0x0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
- };
- etm0: etm@22040000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x22040000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster0_etm0_out_port: endpoint {
remote-endpoint = <&cluster0_funnel_in_port0>;
};
};
};
- };
- funnel@220c0000 { /* cluster0 funnel */
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0 0x220c0000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster0_funnel_out_port: endpoint {
remote-endpoint = <&main_funnel_in_port0>;
};
};
};
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
cluster0_funnel_in_port0: endpoint {
remote-endpoint = <&cluster0_etm0_out_port>;
};
};
port@1 {
reg = <1>;
cluster0_funnel_in_port1: endpoint {
remote-endpoint = <&cluster0_etm1_out_port>;
};
};
};
- };
- cpu_debug1: cpu-debug@22110000 {
compatible = "arm,coresight-cpu-debug", "arm,primecell";
reg = <0x0 0x22110000 0x0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
- };
- etm1: etm@22140000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x22140000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster0_etm1_out_port: endpoint {
remote-endpoint = <&cluster0_funnel_in_port1>;
};
};
};
- };
- cpu_debug2: cpu-debug@23010000 {
compatible = "arm,coresight-cpu-debug", "arm,primecell";
reg = <0x0 0x23010000 0x0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
- };
- etm2: etm@23040000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23040000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster1_etm0_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port0>;
};
};
};
- };
- funnel@230c0000 { /* cluster1 funnel */
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0 0x230c0000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster1_funnel_out_port: endpoint {
remote-endpoint = <&main_funnel_in_port1>;
};
};
};
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
cluster1_funnel_in_port0: endpoint {
remote-endpoint = <&cluster1_etm0_out_port>;
};
};
port@1 {
reg = <1>;
cluster1_funnel_in_port1: endpoint {
remote-endpoint = <&cluster1_etm1_out_port>;
};
};
port@2 {
reg = <2>;
cluster1_funnel_in_port2: endpoint {
remote-endpoint = <&cluster1_etm2_out_port>;
};
};
port@3 {
reg = <3>;
cluster1_funnel_in_port3: endpoint {
remote-endpoint = <&cluster1_etm3_out_port>;
};
};
};
- };
- cpu_debug3: cpu-debug@23110000 {
compatible = "arm,coresight-cpu-debug", "arm,primecell";
reg = <0x0 0x23110000 0x0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
- };
- etm3: etm@23140000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23140000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster1_etm1_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port1>;
};
};
};
- };
- cpu_debug4: cpu-debug@23210000 {
compatible = "arm,coresight-cpu-debug", "arm,primecell";
reg = <0x0 0x23210000 0x0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
- };
- etm4: etm@23240000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23240000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster1_etm2_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port2>;
};
};
};
- };
- cpu_debug5: cpu-debug@23310000 {
compatible = "arm,coresight-cpu-debug", "arm,primecell";
reg = <0x0 0x23310000 0x0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
- };
- etm5: etm@23340000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23340000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
cluster1_etm3_out_port: endpoint {
remote-endpoint = <&cluster1_funnel_in_port3>;
};
};
};
- };
- gpu: gpu@2d000000 {
compatible = "arm,juno-mali", "arm,mali-t624";
reg = <0 0x2d000000 0 0x10000>;
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "job", "mmu", "gpu";
clocks = <&scpi_dvfs 2>;
power-domains = <&scpi_devpd 1>;
dma-coherent;
/* The SMMU is only really of interest to bare-metal hypervisors */
/* iommus = <&smmu_gpu 0>; */
status = "disabled";
- };
- sram: sram@2e000000 {
compatible = "arm,juno-sram-ns", "mmio-sram";
reg = <0x0 0x2e000000 0x0 0x8000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x0 0x2e000000 0x8000>;
cpu_scp_lpri: scp-sram@0 {
compatible = "arm,juno-scp-shmem";
reg = <0x0 0x200>;
};
cpu_scp_hpri: scp-sram@200 {
compatible = "arm,juno-scp-shmem";
reg = <0x200 0x200>;
};
- };
- pcie_ctlr: pcie@40000000 {
compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic";
device_type = "pci";
reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */
bus-range = <0 255>;
linux,pci-domain = <0>;
#address-cells = <3>;
#size-cells = <2>;
dma-coherent;
ranges = <0x01000000 0x00 0x00000000 0x00 0x5f800000 0x0 0x00800000>,
<0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
<0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
/* Standard AXI Translation entries as programmed by EDK2 */
dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>,
<0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
<0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &gic 0 GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 2 &gic 0 GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 3 &gic 0 GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 4 &gic 0 GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
msi-parent = <&v2m_0>;
status = "disabled";
iommu-map-mask = <0x0>; /* RC has no means to output PCI RID */
iommu-map = <0x0 &smmu_pcie 0x0 0x1>;
- };
- scpi {
compatible = "arm,scpi";
mboxes = <&mailbox 1>;
shmem = <&cpu_scp_hpri>;
clocks {
compatible = "arm,scpi-clocks";
scpi_dvfs: clocks-0 {
compatible = "arm,scpi-dvfs-clocks";
#clock-cells = <1>;
clock-indices = <0>, <1>, <2>;
clock-output-names = "atlclk", "aplclk","gpuclk";
};
scpi_clk: clocks-1 {
compatible = "arm,scpi-variable-clocks";
#clock-cells = <1>;
clock-indices = <3>;
clock-output-names = "pxlclk";
};
};
scpi_devpd: power-controller {
compatible = "arm,scpi-power-domains";
num-domains = <2>;
#power-domain-cells = <1>;
};
scpi_sensors0: sensors {
compatible = "arm,scpi-sensors";
#thermal-sensor-cells = <1>;
};
- };
- thermal-zones {
pmic {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 0>;
};
soc {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 3>;
};
big_cluster_thermal_zone: big-cluster {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 21>;
status = "disabled";
};
little_cluster_thermal_zone: little-cluster {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 22>;
status = "disabled";
};
gpu0_thermal_zone: gpu0 {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 23>;
status = "disabled";
};
gpu1_thermal_zone: gpu1 {
polling-delay = <1000>;
polling-delay-passive = <100>;
thermal-sensors = <&scpi_sensors0 24>;
status = "disabled";
};
- };
- smmu_dma: iommu@7fb00000 {
compatible = "arm,mmu-401", "arm,smmu-v1";
reg = <0x0 0x7fb00000 0x0 0x10000>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
dma-coherent;
- };
- smmu_hdlcd1: iommu@7fb10000 {
compatible = "arm,mmu-401", "arm,smmu-v1";
reg = <0x0 0x7fb10000 0x0 0x10000>;
interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
- };
- smmu_hdlcd0: iommu@7fb20000 {
compatible = "arm,mmu-401", "arm,smmu-v1";
reg = <0x0 0x7fb20000 0x0 0x10000>;
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
- };
- smmu_usb: iommu@7fb30000 {
compatible = "arm,mmu-401", "arm,smmu-v1";
reg = <0x0 0x7fb30000 0x0 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
#global-interrupts = <1>;
dma-coherent;
- };
- dma@7ff00000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0x7ff00000 0 0x1000>;
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_dma 0>,
<&smmu_dma 1>,
<&smmu_dma 2>,
<&smmu_dma 3>,
<&smmu_dma 4>,
<&smmu_dma 5>,
<&smmu_dma 6>,
<&smmu_dma 7>,
<&smmu_dma 8>;
clocks = <&soc_faxiclk>;
clock-names = "apb_pclk";
- };
- hdlcd@7ff50000 {
compatible = "arm,hdlcd";
reg = <0 0x7ff50000 0 0x1000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_hdlcd1 0>;
clocks = <&scpi_clk 3>;
clock-names = "pxlclk";
port {
hdlcd1_output: endpoint {
remote-endpoint = <&tda998x_1_input>;
};
};
- };
- hdlcd@7ff60000 {
compatible = "arm,hdlcd";
reg = <0 0x7ff60000 0 0x1000>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_hdlcd0 0>;
clocks = <&scpi_clk 3>;
clock-names = "pxlclk";
port {
hdlcd0_output: endpoint {
remote-endpoint = <&tda998x_0_input>;
};
};
- };
- soc_uart0: serial@7ff80000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0x7ff80000 0x0 0x1000>;
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
clock-names = "uartclk", "apb_pclk";
- };
- i2c@7ffa0000 {
compatible = "snps,designware-i2c";
reg = <0x0 0x7ffa0000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <400000>;
i2c-sda-hold-time-ns = <500>;
clocks = <&soc_smc50mhz>;
hdmi-transmitter@70 {
compatible = "nxp,tda998x";
reg = <0x70>;
port {
tda998x_0_input: endpoint {
remote-endpoint = <&hdlcd0_output>;
};
};
};
hdmi-transmitter@71 {
compatible = "nxp,tda998x";
reg = <0x71>;
port {
tda998x_1_input: endpoint {
remote-endpoint = <&hdlcd1_output>;
};
};
};
- };
- usb@7ffb0000 {
compatible = "generic-ohci";
reg = <0x0 0x7ffb0000 0x0 0x10000>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_usb 0>;
clocks = <&soc_usb48mhz>;
- };
- usb@7ffc0000 {
compatible = "generic-ehci";
reg = <0x0 0x7ffc0000 0x0 0x10000>;
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&smmu_usb 0>;
clocks = <&soc_usb48mhz>;
- };
- memory-controller@7ffd0000 {
compatible = "arm,pl354", "arm,primecell";
reg = <0 0x7ffd0000 0 0x1000>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
- };
- memory@80000000 {
device_type = "memory";
/* last 16MB of the first memory area is reserved for secure world use by firmware */
reg = <0x00000000 0x80000000 0x0 0x7f000000>,
<0x00000008 0x80000000 0x1 0x80000000>;
- };
- bus@8000000 {
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 15>;
interrupt-map = <0 0 0 &gic 0 GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
<0 0 1 &gic 0 GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
<0 0 2 &gic 0 GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
<0 0 3 &gic 0 GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
<0 0 4 &gic 0 GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
<0 0 5 &gic 0 GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
<0 0 6 &gic 0 GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
<0 0 7 &gic 0 GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
<0 0 8 &gic 0 GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
<0 0 9 &gic 0 GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
<0 0 10 &gic 0 GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
<0 0 11 &gic 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
<0 0 12 &gic 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
- };
- site2: tlx-bus@60000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0x60000000 0x10000000>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0>;
interrupt-map = <0 0 &gic 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
- };
+}; diff --git a/arch/arm/dts/juno-clocks.dtsi b/arch/arm/dts/juno-clocks.dtsi new file mode 100644 index 00000000000..b0f8ccaac9e --- /dev/null +++ b/arch/arm/dts/juno-clocks.dtsi @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/*
- ARM Juno Platform clocks
- Copyright (c) 2013-2014 ARM Ltd
- This file is licensed under a dual GPLv2 or BSD license.
- */
+/ {
- /* SoC fixed clocks */
- soc_uartclk: refclk7372800hz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <7372800>;
clock-output-names = "juno:uartclk";
- };
- soc_usb48mhz: clk48mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <48000000>;
clock-output-names = "clk48mhz";
- };
- soc_smc50mhz: clk50mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
clock-output-names = "smc_clk";
- };
- soc_refclk100mhz: refclk100mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "apb_pclk";
- };
- soc_faxiclk: refclk400mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <400000000>;
clock-output-names = "faxi_clk";
- };
+}; diff --git a/arch/arm/dts/juno-cs-r1r2.dtsi b/arch/arm/dts/juno-cs-r1r2.dtsi new file mode 100644 index 00000000000..eda3d9e18af --- /dev/null +++ b/arch/arm/dts/juno-cs-r1r2.dtsi @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 +/ {
- funnel@20130000 { /* cssys1 */
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0 0x20130000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
csys1_funnel_out_port: endpoint {
remote-endpoint = <&etf1_in_port>;
};
};
};
in-ports {
port {
csys1_funnel_in_port0: endpoint {
};
};
};
- };
- etf@20140000 { /* etf1 */
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0 0x20140000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
in-ports {
port {
etf1_in_port: endpoint {
remote-endpoint = <&csys1_funnel_out_port>;
};
};
};
out-ports {
port {
etf1_out_port: endpoint {
remote-endpoint = <&csys2_funnel_in_port1>;
};
};
};
- };
- funnel@20150000 { /* cssys2 */
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0 0x20150000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
power-domains = <&scpi_devpd 0>;
out-ports {
port {
csys2_funnel_out_port: endpoint {
remote-endpoint = <&replicator_in_port0>;
};
};
};
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
csys2_funnel_in_port0: endpoint {
slave-mode;
remote-endpoint = <&etf0_out_port>;
};
};
port@1 {
reg = <1>;
csys2_funnel_in_port1: endpoint {
slave-mode;
remote-endpoint = <&etf1_out_port>;
};
};
};
- };
+}; diff --git a/arch/arm/dts/juno-motherboard.dtsi b/arch/arm/dts/juno-motherboard.dtsi new file mode 100644 index 00000000000..42b17542ab1 --- /dev/null +++ b/arch/arm/dts/juno-motherboard.dtsi @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/*
- ARM Juno Platform motherboard peripherals
- Copyright (c) 2013-2014 ARM Ltd
- This file is licensed under a dual GPLv2 or BSD license.
- */
+/ {
- mb_clk24mhz: clk24mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
clock-output-names = "juno_mb:clk24mhz";
- };
- mb_clk25mhz: clk25mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
clock-output-names = "juno_mb:clk25mhz";
- };
- v2m_refclk1mhz: refclk1mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000>;
clock-output-names = "juno_mb:refclk1mhz";
- };
- v2m_refclk32khz: refclk32khz {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
clock-output-names = "juno_mb:refclk32khz";
- };
- mb_fixed_3v3: mcc-sb-3v3 {
compatible = "regulator-fixed";
regulator-name = "MCC_SB_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
- };
- gpio-keys {
compatible = "gpio-keys";
power-button {
debounce-interval = <50>;
wakeup-source;
linux,code = <116>;
label = "POWER";
gpios = <&iofpga_gpio0 0 0x4>;
};
home-button {
debounce-interval = <50>;
wakeup-source;
linux,code = <102>;
label = "HOME";
gpios = <&iofpga_gpio0 1 0x4>;
};
rlock-button {
debounce-interval = <50>;
wakeup-source;
linux,code = <152>;
label = "RLOCK";
gpios = <&iofpga_gpio0 2 0x4>;
};
vol-up-button {
debounce-interval = <50>;
wakeup-source;
linux,code = <115>;
label = "VOL+";
gpios = <&iofpga_gpio0 3 0x4>;
};
vol-down-button {
debounce-interval = <50>;
wakeup-source;
linux,code = <114>;
label = "VOL-";
gpios = <&iofpga_gpio0 4 0x4>;
};
nmi-button {
debounce-interval = <50>;
wakeup-source;
linux,code = <99>;
label = "NMI";
gpios = <&iofpga_gpio0 5 0x4>;
};
- };
- bus@8000000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0x8000000 0 0x8000000 0x18000000>;
motherboard-bus@8000000 {
compatible = "arm,vexpress,v2p-p1", "simple-bus";
#address-cells = <2>; /* SMB chipselect number and offset */
#size-cells = <1>;
ranges = <0 0 0 0x08000000 0x04000000>,
<1 0 0 0x14000000 0x04000000>,
<2 0 0 0x18000000 0x04000000>,
<3 0 0 0x1c000000 0x04000000>,
<4 0 0 0x0c000000 0x04000000>,
<5 0 0 0x10000000 0x04000000>;
arm,hbi = <0x252>;
arm,vexpress,site = <0>;
flash@0 {
/* 2 * 32MiB NOR Flash memory mounted on CS0 */
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>;
bank-width = <4>;
/*
* Unfortunately, accessing the flash disturbs
* the CPU idle states (suspend) and CPU
* hotplug of the platform. For this reason,
* flash hardware access is disabled by default.
*/
status = "disabled";
partitions {
compatible = "arm,arm-firmware-suite";
};
};
ethernet@200000000 {
compatible = "smsc,lan9118", "smsc,lan9115";
reg = <2 0x00000000 0x10000>;
interrupts = <3>;
phy-mode = "mii";
reg-io-width = <4>;
smsc,irq-active-high;
smsc,irq-push-pull;
clocks = <&mb_clk25mhz>;
vdd33a-supply = <&mb_fixed_3v3>;
vddvario-supply = <&mb_fixed_3v3>;
};
iofpga-bus@300000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 3 0 0x200000>;
v2m_sysctl: sysctl@20000 {
compatible = "arm,sp810", "arm,primecell";
reg = <0x020000 0x1000>;
clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&mb_clk24mhz>;
clock-names = "refclk", "timclk", "apb_pclk";
#clock-cells = <1>;
clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
};
apbregs@10000 {
compatible = "syscon", "simple-mfd";
reg = <0x010000 0x1000>;
led0 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x01>;
label = "vexpress:0";
linux,default-trigger = "heartbeat";
default-state = "on";
};
led1 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x02>;
label = "vexpress:1";
linux,default-trigger = "mmc0";
default-state = "off";
};
led2 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x04>;
label = "vexpress:2";
linux,default-trigger = "cpu0";
default-state = "off";
};
led3 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x08>;
label = "vexpress:3";
linux,default-trigger = "cpu1";
default-state = "off";
};
led4 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x10>;
label = "vexpress:4";
linux,default-trigger = "cpu2";
default-state = "off";
};
led5 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x20>;
label = "vexpress:5";
linux,default-trigger = "cpu3";
default-state = "off";
};
led6 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x40>;
label = "vexpress:6";
default-state = "off";
};
led7 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x80>;
label = "vexpress:7";
default-state = "off";
};
};
mmc@50000 {
compatible = "arm,pl180", "arm,primecell";
reg = <0x050000 0x1000>;
interrupts = <5>;
/* cd-gpios = <&v2m_mmc_gpios 0 0>;
wp-gpios = <&v2m_mmc_gpios 1 0>; */
max-frequency = <12000000>;
vmmc-supply = <&mb_fixed_3v3>;
clocks = <&mb_clk24mhz>, <&soc_smc50mhz>;
clock-names = "mclk", "apb_pclk";
};
kmi@60000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x060000 0x1000>;
interrupts = <8>;
clocks = <&mb_clk24mhz>, <&soc_smc50mhz>;
clock-names = "KMIREFCLK", "apb_pclk";
};
kmi@70000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x070000 0x1000>;
interrupts = <8>;
clocks = <&mb_clk24mhz>, <&soc_smc50mhz>;
clock-names = "KMIREFCLK", "apb_pclk";
};
watchdog@f0000 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x0f0000 0x10000>;
interrupts = <7>;
clocks = <&mb_clk24mhz>, <&soc_smc50mhz>;
clock-names = "wdog_clk", "apb_pclk";
};
v2m_timer01: timer@110000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x110000 0x10000>;
interrupts = <9>;
clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&mb_clk24mhz>;
clock-names = "timclken1", "timclken2", "apb_pclk";
};
v2m_timer23: timer@120000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0x120000 0x10000>;
interrupts = <9>;
clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&mb_clk24mhz>;
clock-names = "timclken1", "timclken2", "apb_pclk";
};
rtc@170000 {
compatible = "arm,pl031", "arm,primecell";
reg = <0x170000 0x10000>;
interrupts = <0>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
};
iofpga_gpio0: gpio@1d0000 {
compatible = "arm,pl061", "arm,primecell";
reg = <0x1d0000 0x1000>;
interrupts = <6>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
};
};
- };
+}; diff --git a/arch/arm/dts/juno-r2.dts b/arch/arm/dts/juno-r2.dts new file mode 100644 index 00000000000..52a6517d165 --- /dev/null +++ b/arch/arm/dts/juno-r2.dts @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/*
- ARM Ltd. Juno Platform
- Copyright (c) 2015 ARM Ltd.
- This file is licensed under a dual GPLv2 or BSD license.
- */
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/arm-gic.h> +#include "juno-base.dtsi" +#include "juno-cs-r1r2.dtsi"
+/ {
- model = "ARM Juno development board (r2)";
- compatible = "arm,juno-r2", "arm,juno", "arm,vexpress";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
- aliases {
serial0 = &soc_uart0;
- };
- chosen {
stdout-path = "serial0:115200n8";
- };
- psci {
compatible = "arm,psci-0.2";
method = "smc";
- };
- cpus {
#address-cells = <2>;
#size-cells = <0>;
cpu-map {
cluster0 {
core0 {
cpu = <&A72_0>;
};
core1 {
cpu = <&A72_1>;
};
};
cluster1 {
core0 {
cpu = <&A53_0>;
};
core1 {
cpu = <&A53_1>;
};
core2 {
cpu = <&A53_2>;
};
core3 {
cpu = <&A53_3>;
};
};
};
idle-states {
entry-method = "psci";
CPU_SLEEP_0: cpu-sleep-0 {
compatible = "arm,idle-state";
arm,psci-suspend-param = <0x0010000>;
local-timer-stop;
entry-latency-us = <300>;
exit-latency-us = <1200>;
min-residency-us = <2000>;
};
CLUSTER_SLEEP_0: cluster-sleep-0 {
compatible = "arm,idle-state";
arm,psci-suspend-param = <0x1010000>;
local-timer-stop;
entry-latency-us = <400>;
exit-latency-us = <1200>;
min-residency-us = <2500>;
};
};
A72_0: cpu@0 {
compatible = "arm,cortex-a72";
reg = <0x0 0x0>;
device_type = "cpu";
enable-method = "psci";
i-cache-size = <0xc000>;
i-cache-line-size = <64>;
i-cache-sets = <256>;
d-cache-size = <0x8000>;
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A72_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <450>;
};
A72_1: cpu@1 {
compatible = "arm,cortex-a72";
reg = <0x0 0x1>;
device_type = "cpu";
enable-method = "psci";
i-cache-size = <0xc000>;
i-cache-line-size = <64>;
i-cache-sets = <256>;
d-cache-size = <0x8000>;
d-cache-line-size = <64>;
d-cache-sets = <256>;
next-level-cache = <&A72_L2>;
clocks = <&scpi_dvfs 0>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <450>;
};
A53_0: cpu@100 {
compatible = "arm,cortex-a53";
reg = <0x0 0x100>;
device_type = "cpu";
enable-method = "psci";
i-cache-size = <0x8000>;
i-cache-line-size = <64>;
i-cache-sets = <256>;
d-cache-size = <0x8000>;
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
dynamic-power-coefficient = <140>;
};
A53_1: cpu@101 {
compatible = "arm,cortex-a53";
reg = <0x0 0x101>;
device_type = "cpu";
enable-method = "psci";
i-cache-size = <0x8000>;
i-cache-line-size = <64>;
i-cache-sets = <256>;
d-cache-size = <0x8000>;
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
dynamic-power-coefficient = <140>;
};
A53_2: cpu@102 {
compatible = "arm,cortex-a53";
reg = <0x0 0x102>;
device_type = "cpu";
enable-method = "psci";
i-cache-size = <0x8000>;
i-cache-line-size = <64>;
i-cache-sets = <256>;
d-cache-size = <0x8000>;
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
dynamic-power-coefficient = <140>;
};
A53_3: cpu@103 {
compatible = "arm,cortex-a53";
reg = <0x0 0x103>;
device_type = "cpu";
enable-method = "psci";
i-cache-size = <0x8000>;
i-cache-line-size = <64>;
i-cache-sets = <256>;
d-cache-size = <0x8000>;
d-cache-line-size = <64>;
d-cache-sets = <128>;
next-level-cache = <&A53_L2>;
clocks = <&scpi_dvfs 1>;
cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <485>;
dynamic-power-coefficient = <140>;
};
A72_L2: l2-cache0 {
compatible = "cache";
cache-size = <0x200000>;
cache-line-size = <64>;
cache-sets = <2048>;
};
A53_L2: l2-cache1 {
compatible = "cache";
cache-size = <0x100000>;
cache-line-size = <64>;
cache-sets = <1024>;
};
- };
- pmu-a72 {
compatible = "arm,cortex-a72-pmu";
interrupts = <GIC_SPI 02 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&A72_0>,
<&A72_1>;
- };
- pmu-a53 {
compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&A53_0>,
<&A53_1>,
<&A53_2>,
<&A53_3>;
- };
+};
+&memtimer {
- status = "okay";
+};
+&pcie_ctlr {
- status = "okay";
+};
+&smmu_pcie {
- status = "okay";
+};
+&etm0 {
- cpu = <&A72_0>;
+};
+&etm1 {
- cpu = <&A72_1>;
+};
+&etm2 {
- cpu = <&A53_0>;
+};
+&etm3 {
- cpu = <&A53_1>;
+};
+&etm4 {
- cpu = <&A53_2>;
+};
+&etm5 {
- cpu = <&A53_3>;
+};
+&big_cluster_thermal_zone {
- status = "okay";
+};
+&little_cluster_thermal_zone {
- status = "okay";
+};
+&gpu0_thermal_zone {
- status = "okay";
+};
+&gpu1_thermal_zone {
- status = "okay";
+};
+&etf0_out_port {
- remote-endpoint = <&csys2_funnel_in_port0>;
+};
+&replicator_in_port0 {
- remote-endpoint = <&csys2_funnel_out_port>;
+};
+&csys1_funnel_in_port0 {
- remote-endpoint = <&stm_out_port>;
+};
+&stm_out_port {
- remote-endpoint = <&csys1_funnel_in_port0>;
+};
+&cpu_debug0 {
- cpu = <&A72_0>;
+};
+&cpu_debug1 {
- cpu = <&A72_1>;
+};
+&cpu_debug2 {
- cpu = <&A53_0>;
+};
+&cpu_debug3 {
- cpu = <&A53_1>;
+};
+&cpu_debug4 {
- cpu = <&A53_2>;
+};
+&cpu_debug5 {
- cpu = <&A53_3>;
+}; diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig index f6ff0e0a569..0d9914c32bf 100644 --- a/configs/vexpress_aemv8a_juno_defconfig +++ b/configs/vexpress_aemv8a_juno_defconfig @@ -51,3 +51,4 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_GENERIC=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_GENERIC=y +CONFIG_DEFAULT_DEVICE_TREE="juno-r2"

On Wed, Dec 08, 2021 at 04:59:14PM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:46 -0700 Simon Glass sjg@chromium.org wrote:
Hi,
Sync these file, obtained from Linux v5.15.
So just for the records: Here you have the same problem as with the other platforms: There are three different revisions of the board, all out in the wild and heavily used. The platform firmware (some STM32 controller on the board) sorts out which board you have, and places the right DTB in the NOR flash. So by reading that from there, you get the correct information.
So as it stands right now, having the Juno DTBs in the tree does not help in any way, as they are not packaged. Actually just u-boot.bin is becoming part of the TF-A FIP image, and then this fip.bin is copied to the board's SD card, along with all three DTBs. I can write up some instructions on how to deploy the firmware on the board, if that helps.
To me, a common theme is that the board documentation isn't clear enough on how things work so yes, this would be greatly appreciated.

Add an empty file to prevent build errors when building with CONFIG_OF_SEPARATE enabled.
The build instructions in U-Boot do not provide enough detail to build a useful devicetree, unfortunately.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Use 'empty' instead of 'fake'
arch/arm/dts/Makefile | 2 ++ arch/arm/dts/xenguest-arm64.dts | 15 +++++++++++++++ configs/xenguest_arm64_defconfig | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/xenguest-arm64.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d53bae2c350..f6345988c8c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1140,6 +1140,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8516-pumpkin.dtb \ mt8518-ap1-emmc.dtb
+dtb-$(CONFIG_XEN) += xenguest-arm64.dtb + dtb-$(CONFIG_TARGET_GE_BX50V3) += \ imx6q-bx50v3.dtb \ imx6q-b850v3.dtb \ diff --git a/arch/arm/dts/xenguest-arm64.dts b/arch/arm/dts/xenguest-arm64.dts new file mode 100644 index 00000000000..d8734433763 --- /dev/null +++ b/arch/arm/dts/xenguest-arm64.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Empty devicetree file for xenguest_arm64 + * + * This is required to make the board build with CONFIG OF_SEPARATE + * Build instructions at xenguest_arm64.rst are inadequate for obtaining a real + * devicetree. + * + * Copyright 2021 Google LLC + */ + +/dts-v1/; + +/ { +}; diff --git a/configs/xenguest_arm64_defconfig b/configs/xenguest_arm64_defconfig index 8d9d9133a2e..edce34346d3 100644 --- a/configs/xenguest_arm64_defconfig +++ b/configs/xenguest_arm64_defconfig @@ -3,7 +3,7 @@ CONFIG_POSITION_INDEPENDENT=y CONFIG_TARGET_XENGUEST_ARM64=y CONFIG_SYS_TEXT_BASE=0x40080000 CONFIG_SYS_MALLOC_LEN=0x2000000 -CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="xenguest-arm64" CONFIG_IDENT_STRING=" xenguest" CONFIG_SYS_LOAD_ADDR=0x40000000 CONFIG_BOOTDELAY=10

Hi, Simon!
On 07.12.21 02:11, Simon Glass wrote:
Add an empty file to prevent build errors when building with CONFIG_OF_SEPARATE enabled.
The build instructions in U-Boot do not provide enough detail to build a useful devicetree, unfortunately.
There is no such instruction exists as the device tree is built at run-time by the hypervisor itself depending on virtual machine configuration: I have already pointed that, e.g. U-boot is no different from any other kernel/binary running in a virtual machine.
Thus I do not agree with the sentence above as it misleads.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v7:
Use 'empty' instead of 'fake'
arch/arm/dts/Makefile | 2 ++ arch/arm/dts/xenguest-arm64.dts | 15 +++++++++++++++ configs/xenguest_arm64_defconfig | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/xenguest-arm64.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d53bae2c350..f6345988c8c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1140,6 +1140,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8516-pumpkin.dtb \ mt8518-ap1-emmc.dtb
+dtb-$(CONFIG_XEN) += xenguest-arm64.dtb
- dtb-$(CONFIG_TARGET_GE_BX50V3) += \ imx6q-bx50v3.dtb \ imx6q-b850v3.dtb \
diff --git a/arch/arm/dts/xenguest-arm64.dts b/arch/arm/dts/xenguest-arm64.dts new file mode 100644 index 00000000000..d8734433763 --- /dev/null +++ b/arch/arm/dts/xenguest-arm64.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Empty devicetree file for xenguest_arm64
- This is required to make the board build with CONFIG OF_SEPARATE
- Build instructions at xenguest_arm64.rst are inadequate for obtaining a real
- devicetree.
ditto. I will not provide any instruction as this is internal to Xen implementation and may change depending on Xen version and virtual machine configuration. If someone wants that she can dig into relevant Xen sources to see how the device tree constructed. But this may be different between Xen versions and/or virtual machine settings.
Please rephrase to reflect the dynamic nature of the device tree instead
Thank you, Oleksandr
- Copyright 2021 Google LLC
- */
+/dts-v1/;
+/ { +}; diff --git a/configs/xenguest_arm64_defconfig b/configs/xenguest_arm64_defconfig index 8d9d9133a2e..edce34346d3 100644 --- a/configs/xenguest_arm64_defconfig +++ b/configs/xenguest_arm64_defconfig @@ -3,7 +3,7 @@ CONFIG_POSITION_INDEPENDENT=y CONFIG_TARGET_XENGUEST_ARM64=y CONFIG_SYS_TEXT_BASE=0x40080000 CONFIG_SYS_MALLOC_LEN=0x2000000 -CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="xenguest-arm64" CONFIG_IDENT_STRING=" xenguest" CONFIG_SYS_LOAD_ADDR=0x40000000 CONFIG_BOOTDELAY=10

Hi Oleksandr,
On Mon, 6 Dec 2021 at 22:57, Oleksandr Andrushchenko Oleksandr_Andrushchenko@epam.com wrote:
Hi, Simon!
On 07.12.21 02:11, Simon Glass wrote:
Add an empty file to prevent build errors when building with CONFIG_OF_SEPARATE enabled.
The build instructions in U-Boot do not provide enough detail to build a useful devicetree, unfortunately.
There is no such instruction exists as the device tree is built at run-time by the hypervisor itself depending on virtual machine configuration: I have already pointed that, e.g. U-boot is no different from any other kernel/binary running in a virtual machine.
Thus I do not agree with the sentence above as it misleads.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v7:
Use 'empty' instead of 'fake'
arch/arm/dts/Makefile | 2 ++ arch/arm/dts/xenguest-arm64.dts | 15 +++++++++++++++ configs/xenguest_arm64_defconfig | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/xenguest-arm64.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d53bae2c350..f6345988c8c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1140,6 +1140,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8516-pumpkin.dtb \ mt8518-ap1-emmc.dtb
+dtb-$(CONFIG_XEN) += xenguest-arm64.dtb
- dtb-$(CONFIG_TARGET_GE_BX50V3) += \ imx6q-bx50v3.dtb \ imx6q-b850v3.dtb \
diff --git a/arch/arm/dts/xenguest-arm64.dts b/arch/arm/dts/xenguest-arm64.dts new file mode 100644 index 00000000000..d8734433763 --- /dev/null +++ b/arch/arm/dts/xenguest-arm64.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Empty devicetree file for xenguest_arm64
- This is required to make the board build with CONFIG OF_SEPARATE
- Build instructions at xenguest_arm64.rst are inadequate for obtaining a real
- devicetree.
ditto. I will not provide any instruction as this is internal to Xen implementation and may change depending on Xen version and virtual machine configuration. If someone wants that she can dig into relevant Xen sources to see how the device tree constructed. But this may be different between Xen versions and/or virtual machine settings.
Please rephrase to reflect the dynamic nature of the device tree instead
Yes I updated the others but missing this one, will tidy it up when I fix the fdtgrep problem.
Regards, Simon

Add an empty file to prevent build errors when building with CONFIG_OF_SEPARATE enabled.
Unfortunately there are no build instructions in the U-Boot tree to enable a real file to be created.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Use 'empty' instead of 'fake'
arch/arm/dts/Makefile | 3 +++ arch/arm/dts/octeontx.dts | 14 ++++++++++++++ configs/octeontx2_95xx_defconfig | 1 + configs/octeontx2_96xx_defconfig | 1 + configs/octeontx_81xx_defconfig | 1 + configs/octeontx_83xx_defconfig | 1 + 6 files changed, 21 insertions(+) create mode 100644 arch/arm/dts/octeontx.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index f6345988c8c..91302118598 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1142,6 +1142,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
dtb-$(CONFIG_XEN) += xenguest-arm64.dtb
+dtb-$(CONFIG_ARCH_OCTEONTX) += octeontx.dtb +dtb-$(CONFIG_ARCH_OCTEONTX2) += octeontx.dtb + dtb-$(CONFIG_TARGET_GE_BX50V3) += \ imx6q-bx50v3.dtb \ imx6q-b850v3.dtb \ diff --git a/arch/arm/dts/octeontx.dts b/arch/arm/dts/octeontx.dts new file mode 100644 index 00000000000..60a15f5df23 --- /dev/null +++ b/arch/arm/dts/octeontx.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Dummy devicetre file for octeontx2 boards + * + * This is required to make the board build with CONFIG OF_SEPARATE + * I could not find any in-tree documentation at all so this is a dummy file. + * + * Copyright 2021 Google LLC + */ + +/dts-v1/; + +/ { +}; diff --git a/configs/octeontx2_95xx_defconfig b/configs/octeontx2_95xx_defconfig index e1b86a5a8b6..e3df390c94b 100644 --- a/configs/octeontx2_95xx_defconfig +++ b/configs/octeontx2_95xx_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0xF00000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_TARGET_OCTEONTX2_95XX=y CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="octeontx" CONFIG_DEBUG_UART_BASE=0x87e028000000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART=y diff --git a/configs/octeontx2_96xx_defconfig b/configs/octeontx2_96xx_defconfig index ec03d959771..0478b3068a6 100644 --- a/configs/octeontx2_96xx_defconfig +++ b/configs/octeontx2_96xx_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0xF00000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_TARGET_OCTEONTX2_96XX=y CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="octeontx" CONFIG_DEBUG_UART_BASE=0x87e028000000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART=y diff --git a/configs/octeontx_81xx_defconfig b/configs/octeontx_81xx_defconfig index d0728ac3c67..d871be8f812 100644 --- a/configs/octeontx_81xx_defconfig +++ b/configs/octeontx_81xx_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0xF00000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_TARGET_OCTEONTX_81XX=y CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="octeontx" CONFIG_DEBUG_UART_BASE=0x87e028000000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART=y diff --git a/configs/octeontx_83xx_defconfig b/configs/octeontx_83xx_defconfig index 6c9609b0cd3..94b072bf6fa 100644 --- a/configs/octeontx_83xx_defconfig +++ b/configs/octeontx_83xx_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0xF00000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_TARGET_OCTEONTX_83XX=y CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="octeontx" CONFIG_DEBUG_UART_BASE=0x87e028000000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART=y

Add an empty file to prevent build errors when building with CONFIG_OF_SEPARATE enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/arm/dts/Makefile | 3 ++- arch/arm/dts/xilinx-versal-virt.dts | 11 +++++++++++ configs/xilinx_versal_virt_defconfig | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/xilinx-versal-virt.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 91302118598..b07a1b3378e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -360,7 +360,8 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \ dtb-$(CONFIG_ARCH_VERSAL) += \ versal-mini.dtb \ versal-mini-emmc0.dtb \ - versal-mini-emmc1.dtb + versal-mini-emmc1.dtb \ + xilinx-versal-virt.dtb dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \ zynqmp-r5.dtb dtb-$(CONFIG_AM33XX) += \ diff --git a/arch/arm/dts/xilinx-versal-virt.dts b/arch/arm/dts/xilinx-versal-virt.dts new file mode 100644 index 00000000000..733e532f987 --- /dev/null +++ b/arch/arm/dts/xilinx-versal-virt.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Empty device tree for versal-virt board + * + * Copyright 2021 Google LLC + */ + +/dts-v1/; + +/ { +}; diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 11598623954..f0ec2639a38 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x100000 CONFIG_SYS_MEMTEST_START=0x00000000 CONFIG_SYS_MEMTEST_END=0x00001000 CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-virt" CONFIG_CMD_FRU=y CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_COUNTER_FREQUENCY=100000000

On 12/7/21 01:11, Simon Glass wrote:
Add an empty file to prevent build errors when building with CONFIG_OF_SEPARATE enabled.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
a little bit weird.
arch/arm/dts/Makefile | 3 ++- arch/arm/dts/xilinx-versal-virt.dts | 11 +++++++++++ configs/xilinx_versal_virt_defconfig | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/xilinx-versal-virt.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 91302118598..b07a1b3378e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -360,7 +360,8 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \ dtb-$(CONFIG_ARCH_VERSAL) += \ versal-mini.dtb \ versal-mini-emmc0.dtb \
- versal-mini-emmc1.dtb
- versal-mini-emmc1.dtb \
- xilinx-versal-virt.dtb dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \ zynqmp-r5.dtb dtb-$(CONFIG_AM33XX) += \
diff --git a/arch/arm/dts/xilinx-versal-virt.dts b/arch/arm/dts/xilinx-versal-virt.dts new file mode 100644 index 00000000000..733e532f987 --- /dev/null +++ b/arch/arm/dts/xilinx-versal-virt.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/*
- Empty device tree for versal-virt board
- Copyright 2021 Google LLC
- */
+/dts-v1/;
+/ { +}; diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 11598623954..f0ec2639a38 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x100000 CONFIG_SYS_MEMTEST_START=0x00000000 CONFIG_SYS_MEMTEST_END=0x00001000 CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-virt" CONFIG_CMD_FRU=y CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_COUNTER_FREQUENCY=100000000
That's fine for me. I will add regular DTS at some point in future.
Thanks, Michal

Add a dummy devicetree file for these boards. It seems to be possible to obtain a real one from another bootloader called 'bolt' but I will leave this to the maintainer.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/arm/dts/Makefile | 2 ++ arch/arm/dts/bcm7xxx.dts | 15 +++++++++++++++ configs/bcm7260_defconfig | 1 + configs/bcm7445_defconfig | 1 + 4 files changed, 19 insertions(+) create mode 100644 arch/arm/dts/bcm7xxx.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b07a1b3378e..8bb15b96cc7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1092,6 +1092,8 @@ dtb-$(CONFIG_ARCH_BCM6858) += \
dtb-$(CONFIG_TARGET_BCMNS3) += ns3-board.dtb
+dtb-$(CONFIG_ARCH_BCMSTB) += bcm7xxx.dtb + dtb-$(CONFIG_ASPEED_AST2500) += ast2500-evb.dtb dtb-$(CONFIG_ASPEED_AST2600) += ast2600-evb.dtb
diff --git a/arch/arm/dts/bcm7xxx.dts b/arch/arm/dts/bcm7xxx.dts new file mode 100644 index 00000000000..786ce3ff959 --- /dev/null +++ b/arch/arm/dts/bcm7xxx.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Empty devicetre file for bcm7260 board + * + * This is required to make the board build with CONFIG OF_SEPARATE + * In-tree document explains how to obtain a real devicetree using 'bolt' but + * I did not attempt this. + * + * Copyright 2021 Google LLC + */ + +/dts-v1/; + +/ { +}; diff --git a/configs/bcm7260_defconfig b/configs/bcm7260_defconfig index 257d81052a8..2b527b65770 100644 --- a/configs/bcm7260_defconfig +++ b/configs/bcm7260_defconfig @@ -7,6 +7,7 @@ CONFIG_TARGET_BCM7260=y CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x814800 +CONFIG_DEFAULT_DEVICE_TREE="bcm7xxx" CONFIG_ENV_OFFSET_REDUND=0x824800 CONFIG_SYS_LOAD_ADDR=0x02000000 CONFIG_FIT=y diff --git a/configs/bcm7445_defconfig b/configs/bcm7445_defconfig index 9ffa436e454..3ae678ba56e 100644 --- a/configs/bcm7445_defconfig +++ b/configs/bcm7445_defconfig @@ -8,6 +8,7 @@ CONFIG_NR_DRAM_BANKS=3 CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x1E0000 CONFIG_ENV_SECT_SIZE=0x10000 +CONFIG_DEFAULT_DEVICE_TREE="bcm7xxx" CONFIG_ENV_OFFSET_REDUND=0x1F0000 CONFIG_SYS_LOAD_ADDR=0x02000000 CONFIG_FIT=y

This uses QEMU virt which creates its own devicetree.
Add an empty version of this file, so that we can at least build this board when devicetrees are required.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Switch to using an empty file for qemu virt
arch/powerpc/dts/Makefile | 1 + arch/powerpc/dts/qemu-ppce500.dts | 10 ++++++++++ configs/qemu-ppce500_defconfig | 1 + 3 files changed, 12 insertions(+) create mode 100644 arch/powerpc/dts/qemu-ppce500.dts
diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile index ceaa8ce5c82..66d22ae8a45 100644 --- a/arch/powerpc/dts/Makefile +++ b/arch/powerpc/dts/Makefile @@ -18,6 +18,7 @@ dtb-$(CONFIG_TARGET_P2041RDB) += p2041rdb.dtb dtb-$(CONFIG_TARGET_P3041DS) += p3041ds.dtb dtb-$(CONFIG_TARGET_P4080DS) += p4080ds.dtb dtb-$(CONFIG_TARGET_P5040DS) += p5040ds.dtb +dtb-$(CONFIG_TARGET_QEMU_PPCE500) += qemu-ppce500.dtb dtb-$(CONFIG_TARGET_SOCRATES) += socrates.dtb dtb-$(CONFIG_TARGET_T1024RDB) += t1024rdb.dtb dtb-$(CONFIG_TARGET_T1042D4RDB) += t1042d4rdb.dtb diff --git a/arch/powerpc/dts/qemu-ppce500.dts b/arch/powerpc/dts/qemu-ppce500.dts new file mode 100644 index 00000000000..e88e09e1796 --- /dev/null +++ b/arch/powerpc/dts/qemu-ppce500.dts @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Empty device tree for qemu-ppce400 + * + * Copyright 2021 Google LLC + */ +/dts-v1/; + +/ { +}; diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index f386f526548..ae4cd8b9618 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -1,6 +1,7 @@ CONFIG_PPC=y CONFIG_SYS_TEXT_BASE=0xf01000 CONFIG_ENV_SIZE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-ppce500" CONFIG_MPC85xx=y # CONFIG_CMD_ERRATA is not set CONFIG_TARGET_QEMU_PPCE500=y

Sync these files, obtained from Linux v5.15.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Bring in files from Linux instead
arch/arm/dts/Makefile | 2 + arch/arm/dts/ecx-common.dtsi | 231 +++++++++++++++++++++++++++++++++++ arch/arm/dts/highbank.dts | 158 ++++++++++++++++++++++++ configs/highbank_defconfig | 2 +- 4 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/ecx-common.dtsi create mode 100644 arch/arm/dts/highbank.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 8bb15b96cc7..453e2fd1a98 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -871,6 +871,8 @@ dtb-$(CONFIG_MX7) += imx7d-sdb.dtb \ dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-com.dtb \ imx7ulp-evk.dtb
+dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb + dtb-$(CONFIG_ARCH_IMX8) += \ fsl-imx8qm-apalis.dtb \ fsl-imx8qm-mek.dtb \ diff --git a/arch/arm/dts/ecx-common.dtsi b/arch/arm/dts/ecx-common.dtsi new file mode 100644 index 00000000000..57a028a6937 --- /dev/null +++ b/arch/arm/dts/ecx-common.dtsi @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2011-2012 Calxeda, Inc. + */ + +/ { + chosen { + bootargs = "console=ttyAMA0"; + }; + + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_suspend = <0x84000002>; + cpu_off = <0x84000004>; + cpu_on = <0x84000006>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&intc>; + + sata@ffe08000 { + compatible = "calxeda,hb-ahci"; + reg = <0xffe08000 0x10000>; + interrupts = <0 83 4>; + dma-coherent; + calxeda,port-phys = < &combophy5 0>, <&combophy0 0>, + <&combophy0 1>, <&combophy0 2>, + <&combophy0 3>; + calxeda,sgpio-gpio =<&gpioh 5 1>, <&gpioh 6 1>, + <&gpioh 7 1>; + calxeda,led-order = <4 0 1 2 3>; + }; + + sdhci@ffe0e000 { + compatible = "calxeda,hb-sdhci"; + reg = <0xffe0e000 0x1000>; + interrupts = <0 90 4>; + clocks = <&eclk>; + status = "disabled"; + }; + + ipc@fff20000 { + compatible = "arm,pl320", "arm,primecell"; + reg = <0xfff20000 0x1000>; + interrupts = <0 7 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + }; + + gpioe: gpio@fff30000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xfff30000 0x1000>; + interrupts = <0 14 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + gpiof: gpio@fff31000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xfff31000 0x1000>; + interrupts = <0 15 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + gpiog: gpio@fff32000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xfff32000 0x1000>; + interrupts = <0 16 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + gpioh: gpio@fff33000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xfff33000 0x1000>; + interrupts = <0 17 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + timer@fff34000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0xfff34000 0x1000>; + interrupts = <0 18 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + }; + + rtc@fff35000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0xfff35000 0x1000>; + interrupts = <0 19 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + }; + + serial@fff36000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xfff36000 0x1000>; + interrupts = <0 20 4>; + clocks = <&pclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + smic@fff3a000 { + compatible = "ipmi-smic"; + device_type = "ipmi"; + reg = <0xfff3a000 0x1000>; + interrupts = <0 24 4>; + reg-size = <4>; + reg-spacing = <4>; + }; + + sregs@fff3c000 { + compatible = "calxeda,hb-sregs"; + reg = <0xfff3c000 0x1000>; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + osc: oscillator { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <33333000>; + }; + + ddrpll: ddrpll { + #clock-cells = <0>; + compatible = "calxeda,hb-pll-clock"; + clocks = <&osc>; + reg = <0x108>; + }; + + a9pll: a9pll { + #clock-cells = <0>; + compatible = "calxeda,hb-pll-clock"; + clocks = <&osc>; + reg = <0x100>; + }; + + a9periphclk: a9periphclk { + #clock-cells = <0>; + compatible = "calxeda,hb-a9periph-clock"; + clocks = <&a9pll>; + reg = <0x104>; + }; + + a9bclk: a9bclk { + #clock-cells = <0>; + compatible = "calxeda,hb-a9bus-clock"; + clocks = <&a9pll>; + reg = <0x104>; + }; + + emmcpll: emmcpll { + #clock-cells = <0>; + compatible = "calxeda,hb-pll-clock"; + clocks = <&osc>; + reg = <0x10C>; + }; + + eclk: eclk { + #clock-cells = <0>; + compatible = "calxeda,hb-emmc-clock"; + clocks = <&emmcpll>; + reg = <0x114>; + }; + + pclk: pclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <150000000>; + }; + }; + }; + + dma@fff3d000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0xfff3d000 0x1000>; + interrupts = <0 92 4>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + }; + + ethernet@fff50000 { + compatible = "calxeda,hb-xgmac"; + reg = <0xfff50000 0x1000>; + interrupts = <0 77 4>, <0 78 4>, <0 79 4>; + dma-coherent; + }; + + ethernet@fff51000 { + compatible = "calxeda,hb-xgmac"; + reg = <0xfff51000 0x1000>; + interrupts = <0 80 4>, <0 81 4>, <0 82 4>; + dma-coherent; + }; + + combophy0: combo-phy@fff58000 { + compatible = "calxeda,hb-combophy"; + #phy-cells = <1>; + reg = <0xfff58000 0x1000>; + phydev = <5>; + }; + + combophy5: combo-phy@fff5d000 { + compatible = "calxeda,hb-combophy"; + #phy-cells = <1>; + reg = <0xfff5d000 0x1000>; + phydev = <31>; + }; + }; +}; diff --git a/arch/arm/dts/highbank.dts b/arch/arm/dts/highbank.dts new file mode 100644 index 00000000000..b6b0225a769 --- /dev/null +++ b/arch/arm/dts/highbank.dts @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2011-2012 Calxeda, Inc. + */ + +/dts-v1/; + +/* First 4KB has pen for secondary cores. */ +/memreserve/ 0x00000000 0x0001000; + +/ { + model = "Calxeda Highbank"; + compatible = "calxeda,highbank"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@900 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0x900>; + next-level-cache = <&L2>; + clocks = <&a9pll>; + clock-names = "cpu"; + operating-points = < + /* kHz ignored */ + 1300000 1000000 + 1200000 1000000 + 1100000 1000000 + 800000 1000000 + 400000 1000000 + 200000 1000000 + >; + clock-latency = <100000>; + }; + + cpu@901 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0x901>; + next-level-cache = <&L2>; + clocks = <&a9pll>; + clock-names = "cpu"; + operating-points = < + /* kHz ignored */ + 1300000 1000000 + 1200000 1000000 + 1100000 1000000 + 800000 1000000 + 400000 1000000 + 200000 1000000 + >; + clock-latency = <100000>; + }; + + cpu@902 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0x902>; + next-level-cache = <&L2>; + clocks = <&a9pll>; + clock-names = "cpu"; + operating-points = < + /* kHz ignored */ + 1300000 1000000 + 1200000 1000000 + 1100000 1000000 + 800000 1000000 + 400000 1000000 + 200000 1000000 + >; + clock-latency = <100000>; + }; + + cpu@903 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0x903>; + next-level-cache = <&L2>; + clocks = <&a9pll>; + clock-names = "cpu"; + operating-points = < + /* kHz ignored */ + 1300000 1000000 + 1200000 1000000 + 1100000 1000000 + 800000 1000000 + 400000 1000000 + 200000 1000000 + >; + clock-latency = <100000>; + }; + }; + + memory@0 { + name = "memory"; + device_type = "memory"; + reg = <0x00000000 0xff900000>; + }; + + soc { + ranges = <0x00000000 0x00000000 0xffffffff>; + + memory-controller@fff00000 { + compatible = "calxeda,hb-ddr-ctrl"; + reg = <0xfff00000 0x1000>; + interrupts = <0 91 4>; + }; + + timer@fff10600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xfff10600 0x20>; + interrupts = <1 13 0xf01>; + clocks = <&a9periphclk>; + }; + + watchdog@fff10620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0xfff10620 0x20>; + interrupts = <1 14 0xf01>; + clocks = <&a9periphclk>; + }; + + intc: interrupt-controller@fff11000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0xfff11000 0x1000>, + <0xfff10100 0x100>; + }; + + L2: cache-controller { + compatible = "arm,pl310-cache"; + reg = <0xfff12000 0x1000>; + interrupts = <0 70 4>; + cache-unified; + cache-level = <2>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 76 4>, <0 75 4>, <0 74 4>, <0 73 4>; + }; + + + sregs@fff3c200 { + compatible = "calxeda,hb-sregs-l2-ecc"; + reg = <0xfff3c200 0x100>; + interrupts = <0 71 4>, <0 72 4>; + }; + + }; +}; + +/include/ "ecx-common.dtsi" diff --git a/configs/highbank_defconfig b/configs/highbank_defconfig index 85b42c70f55..3e8bfcf73a6 100644 --- a/configs/highbank_defconfig +++ b/configs/highbank_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x00008000 CONFIG_SYS_MALLOC_LEN=0x80000 CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="highbank" CONFIG_SYS_BOOTCOUNT_ADDR=0xfff3cf0c CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y CONFIG_DISTRO_DEFAULTS=y @@ -21,7 +22,6 @@ CONFIG_AUTOBOOT_KEYED_CTRLC=y # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_BOARD=y CONFIG_ENV_IS_IN_NVRAM=y CONFIG_ENV_ADDR=0xFFF88000 CONFIG_SCSI_AHCI=y

On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
Cheers, Andre
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v7:
- Bring in files from Linux instead
arch/arm/dts/Makefile | 2 + arch/arm/dts/ecx-common.dtsi | 231 +++++++++++++++++++++++++++++++++++ arch/arm/dts/highbank.dts | 158 ++++++++++++++++++++++++ configs/highbank_defconfig | 2 +- 4 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/ecx-common.dtsi create mode 100644 arch/arm/dts/highbank.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 8bb15b96cc7..453e2fd1a98 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -871,6 +871,8 @@ dtb-$(CONFIG_MX7) += imx7d-sdb.dtb \ dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-com.dtb \ imx7ulp-evk.dtb
+dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb
dtb-$(CONFIG_ARCH_IMX8) += \ fsl-imx8qm-apalis.dtb \ fsl-imx8qm-mek.dtb \ diff --git a/arch/arm/dts/ecx-common.dtsi b/arch/arm/dts/ecx-common.dtsi new file mode 100644 index 00000000000..57a028a6937 --- /dev/null +++ b/arch/arm/dts/ecx-common.dtsi @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0-only +/*
- Copyright 2011-2012 Calxeda, Inc.
- */
+/ {
- chosen {
bootargs = "console=ttyAMA0";
- };
- psci {
compatible = "arm,psci";
method = "smc";
cpu_suspend = <0x84000002>;
cpu_off = <0x84000004>;
cpu_on = <0x84000006>;
- };
- soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&intc>;
sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x10000>;
interrupts = <0 83 4>;
dma-coherent;
calxeda,port-phys = < &combophy5 0>, <&combophy0 0>,
<&combophy0 1>, <&combophy0 2>,
<&combophy0 3>;
calxeda,sgpio-gpio =<&gpioh 5 1>, <&gpioh 6 1>,
<&gpioh 7 1>;
calxeda,led-order = <4 0 1 2 3>;
};
sdhci@ffe0e000 {
compatible = "calxeda,hb-sdhci";
reg = <0xffe0e000 0x1000>;
interrupts = <0 90 4>;
clocks = <&eclk>;
status = "disabled";
};
ipc@fff20000 {
compatible = "arm,pl320", "arm,primecell";
reg = <0xfff20000 0x1000>;
interrupts = <0 7 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
};
gpioe: gpio@fff30000 {
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
reg = <0xfff30000 0x1000>;
interrupts = <0 14 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
status = "disabled";
};
gpiof: gpio@fff31000 {
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
reg = <0xfff31000 0x1000>;
interrupts = <0 15 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
status = "disabled";
};
gpiog: gpio@fff32000 {
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
reg = <0xfff32000 0x1000>;
interrupts = <0 16 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
status = "disabled";
};
gpioh: gpio@fff33000 {
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
reg = <0xfff33000 0x1000>;
interrupts = <0 17 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
status = "disabled";
};
timer@fff34000 {
compatible = "arm,sp804", "arm,primecell";
reg = <0xfff34000 0x1000>;
interrupts = <0 18 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
};
rtc@fff35000 {
compatible = "arm,pl031", "arm,primecell";
reg = <0xfff35000 0x1000>;
interrupts = <0 19 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
};
serial@fff36000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0xfff36000 0x1000>;
interrupts = <0 20 4>;
clocks = <&pclk>, <&pclk>;
clock-names = "uartclk", "apb_pclk";
};
smic@fff3a000 {
compatible = "ipmi-smic";
device_type = "ipmi";
reg = <0xfff3a000 0x1000>;
interrupts = <0 24 4>;
reg-size = <4>;
reg-spacing = <4>;
};
sregs@fff3c000 {
compatible = "calxeda,hb-sregs";
reg = <0xfff3c000 0x1000>;
clocks {
#address-cells = <1>;
#size-cells = <0>;
osc: oscillator {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <33333000>;
};
ddrpll: ddrpll {
#clock-cells = <0>;
compatible = "calxeda,hb-pll-clock";
clocks = <&osc>;
reg = <0x108>;
};
a9pll: a9pll {
#clock-cells = <0>;
compatible = "calxeda,hb-pll-clock";
clocks = <&osc>;
reg = <0x100>;
};
a9periphclk: a9periphclk {
#clock-cells = <0>;
compatible = "calxeda,hb-a9periph-clock";
clocks = <&a9pll>;
reg = <0x104>;
};
a9bclk: a9bclk {
#clock-cells = <0>;
compatible = "calxeda,hb-a9bus-clock";
clocks = <&a9pll>;
reg = <0x104>;
};
emmcpll: emmcpll {
#clock-cells = <0>;
compatible = "calxeda,hb-pll-clock";
clocks = <&osc>;
reg = <0x10C>;
};
eclk: eclk {
#clock-cells = <0>;
compatible = "calxeda,hb-emmc-clock";
clocks = <&emmcpll>;
reg = <0x114>;
};
pclk: pclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <150000000>;
};
};
};
dma@fff3d000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0xfff3d000 0x1000>;
interrupts = <0 92 4>;
clocks = <&pclk>;
clock-names = "apb_pclk";
};
ethernet@fff50000 {
compatible = "calxeda,hb-xgmac";
reg = <0xfff50000 0x1000>;
interrupts = <0 77 4>, <0 78 4>, <0 79 4>;
dma-coherent;
};
ethernet@fff51000 {
compatible = "calxeda,hb-xgmac";
reg = <0xfff51000 0x1000>;
interrupts = <0 80 4>, <0 81 4>, <0 82 4>;
dma-coherent;
};
combophy0: combo-phy@fff58000 {
compatible = "calxeda,hb-combophy";
#phy-cells = <1>;
reg = <0xfff58000 0x1000>;
phydev = <5>;
};
combophy5: combo-phy@fff5d000 {
compatible = "calxeda,hb-combophy";
#phy-cells = <1>;
reg = <0xfff5d000 0x1000>;
phydev = <31>;
};
- };
+}; diff --git a/arch/arm/dts/highbank.dts b/arch/arm/dts/highbank.dts new file mode 100644 index 00000000000..b6b0225a769 --- /dev/null +++ b/arch/arm/dts/highbank.dts @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-only +/*
- Copyright 2011-2012 Calxeda, Inc.
- */
+/dts-v1/;
+/* First 4KB has pen for secondary cores. */ +/memreserve/ 0x00000000 0x0001000;
+/ {
- model = "Calxeda Highbank";
- compatible = "calxeda,highbank";
- #address-cells = <1>;
- #size-cells = <1>;
- cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@900 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0x900>;
next-level-cache = <&L2>;
clocks = <&a9pll>;
clock-names = "cpu";
operating-points = <
/* kHz ignored */
1300000 1000000
1200000 1000000
1100000 1000000
800000 1000000
400000 1000000
200000 1000000
>;
clock-latency = <100000>;
};
cpu@901 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0x901>;
next-level-cache = <&L2>;
clocks = <&a9pll>;
clock-names = "cpu";
operating-points = <
/* kHz ignored */
1300000 1000000
1200000 1000000
1100000 1000000
800000 1000000
400000 1000000
200000 1000000
>;
clock-latency = <100000>;
};
cpu@902 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0x902>;
next-level-cache = <&L2>;
clocks = <&a9pll>;
clock-names = "cpu";
operating-points = <
/* kHz ignored */
1300000 1000000
1200000 1000000
1100000 1000000
800000 1000000
400000 1000000
200000 1000000
>;
clock-latency = <100000>;
};
cpu@903 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0x903>;
next-level-cache = <&L2>;
clocks = <&a9pll>;
clock-names = "cpu";
operating-points = <
/* kHz ignored */
1300000 1000000
1200000 1000000
1100000 1000000
800000 1000000
400000 1000000
200000 1000000
>;
clock-latency = <100000>;
};
- };
- memory@0 {
name = "memory";
device_type = "memory";
reg = <0x00000000 0xff900000>;
- };
- soc {
ranges = <0x00000000 0x00000000 0xffffffff>;
memory-controller@fff00000 {
compatible = "calxeda,hb-ddr-ctrl";
reg = <0xfff00000 0x1000>;
interrupts = <0 91 4>;
};
timer@fff10600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xfff10600 0x20>;
interrupts = <1 13 0xf01>;
clocks = <&a9periphclk>;
};
watchdog@fff10620 {
compatible = "arm,cortex-a9-twd-wdt";
reg = <0xfff10620 0x20>;
interrupts = <1 14 0xf01>;
clocks = <&a9periphclk>;
};
intc: interrupt-controller@fff11000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0xfff11000 0x1000>,
<0xfff10100 0x100>;
};
L2: cache-controller {
compatible = "arm,pl310-cache";
reg = <0xfff12000 0x1000>;
interrupts = <0 70 4>;
cache-unified;
cache-level = <2>;
};
pmu {
compatible = "arm,cortex-a9-pmu";
interrupts = <0 76 4>, <0 75 4>, <0 74 4>, <0 73 4>;
};
sregs@fff3c200 {
compatible = "calxeda,hb-sregs-l2-ecc";
reg = <0xfff3c200 0x100>;
interrupts = <0 71 4>, <0 72 4>;
};
- };
+};
+/include/ "ecx-common.dtsi" diff --git a/configs/highbank_defconfig b/configs/highbank_defconfig index 85b42c70f55..3e8bfcf73a6 100644 --- a/configs/highbank_defconfig +++ b/configs/highbank_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x00008000 CONFIG_SYS_MALLOC_LEN=0x80000 CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x2000 +CONFIG_DEFAULT_DEVICE_TREE="highbank" CONFIG_SYS_BOOTCOUNT_ADDR=0xfff3cf0c CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y CONFIG_DISTRO_DEFAULTS=y @@ -21,7 +22,6 @@ CONFIG_AUTOBOOT_KEYED_CTRLC=y # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_BOARD=y CONFIG_ENV_IS_IN_NVRAM=y CONFIG_ENV_ADDR=0xFFF88000 CONFIG_SCSI_AHCI=y

Hi Andre,
On Mon, 6 Dec 2021 at 18:01, Andre Przywara andre.przywara@arm.com wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
What, there are two boards? How was I supposed to know that?
Where do the devicetree files come from? I was assuming it was Linux, but are they not even there? It doesn't really matter what the tree is, but I assume the base tree must come from *somewhere*. We want to sync that to U-Boot.
Please add a doc/board/highbank.rts or similar.
I think you have missed a lot of discussion about all this.
Regards, Simon

On Tue, Dec 07, 2021 at 08:07:17AM -0700, Simon Glass wrote:
Hi Andre,
On Mon, 6 Dec 2021 at 18:01, Andre Przywara andre.przywara@arm.com wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
What, there are two boards? How was I supposed to know that?
Where do the devicetree files come from? I was assuming it was Linux, but are they not even there? It doesn't really matter what the tree is, but I assume the base tree must come from *somewhere*. We want to sync that to U-Boot.
Please add a doc/board/highbank.rts or similar.
I think you have missed a lot of discussion about all this.
I think you missed where it was explained already that the DTS files come from the hardware.

On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.

Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware. Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
What all this is showing for me is how murky some of these platforms are. It has been a real education...
Regards, Simon

On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote:
Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.

Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote:
Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
Also this is just copied from Linux, which I understand you were comfortable with.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
Regards, Simon
-- Tom

On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote:
Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.

Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote:
Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote:
On Mon, 6 Dec 2021 17:11:52 -0700 Simon Glass sjg@chromium.org wrote:
> Sync these files, obtained from Linux v5.15.
Sorry, but this would be wrong. How do you know which board it is? Highbank or Midway? We use the same binary for both, and decide either by the DT nodes we find in DRAM or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are differences. The memory size would possibly be wrong (it's a DIMM slot). If you need *some* DT for build reasons, whatever, but at least go with the empty stub.
And I still don't get this whole development argument: Why would anyone need some random or partial DT sample in the U-Boot tree to do development? If people develop a driver, the document to code against is the *binding* documentation, which describes what to expect from the DT nodes. Then you *test* it against an actual tree, but on the actual hardware, in which case you get the actual DTB, from the board. If a developer needs to take a sneak peek into an actual DTB, there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a board, getting hands on the actual DT is probably the least of your problems.
So why would we need some mostly wrong DTs in the U-Boot tree? It seems to suggest that you can hack the DT to make things work, but this sounds bonkers, as the real DTB comes from somewhere else (SPI flash, SD card, generated based on command line), and patching U-Boot's copy to make things work is just wishful thinking.
I can see the hacker's desire to play around with the DTB from time to time (What happens if the GPIO is wrong? Can we deal with two instances of the same device?), but for those experiments there are plenty of ways to achieve this - and be it temporarily replacing the empty DT stub. I just feel that bending the (board's) DT design ideas for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
Regards, Simon

On Tue, Dec 07, 2021 at 09:09:54AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote:
Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote: > On Mon, 6 Dec 2021 17:11:52 -0700 > Simon Glass sjg@chromium.org wrote: > > > Sync these files, obtained from Linux v5.15. > > Sorry, but this would be wrong. > How do you know which board it is? Highbank or Midway? We use the > same binary for both, and decide either by the DT nodes we find in DRAM > or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are > differences. The memory size would possibly be wrong (it's a DIMM slot). > If you need *some* DT for build reasons, whatever, but at least go with > the empty stub. > > And I still don't get this whole development argument: Why would > anyone need some random or partial DT sample in the U-Boot tree to do > development? > If people develop a driver, the document to code against is the > *binding* documentation, which describes what to expect from the DT > nodes. Then you *test* it against an actual tree, but on the actual > hardware, in which case you get the actual DTB, from the board. > If a developer needs to take a sneak peek into an actual DTB, > there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD > card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the > kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a > board, getting hands on the actual DT is probably the least of your > problems. > > So why would we need some mostly wrong DTs in the U-Boot tree? > It seems to suggest that you can hack the DT to make things work, but > this sounds bonkers, as the real DTB comes from somewhere else (SPI > flash, SD card, generated based on command line), and patching U-Boot's > copy to make things work is just wishful thinking. > > I can see the hacker's desire to play around with the DTB from time > to time (What happens if the GPIO is wrong? Can we deal with two > instances of the same device?), but for those experiments there are > plenty of ways to achieve this - and be it temporarily replacing the > empty DT stub. I just feel that bending the (board's) DT design ideas > for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
This, largely, is why I still don't understand or agree with the direction this series is taking platforms that currently use CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
As v7 stands yes. But I'm still drafting my reply to the first patch in the series.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
I don't understand. What can't we support in mainline anymore? As Andre noted, you implement versus bindings.

Hi Tom,
On Tue, 7 Dec 2021 at 09:14, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:09:54AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote:
Hi Andre,
On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote: > > On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote: > > On Mon, 6 Dec 2021 17:11:52 -0700 > > Simon Glass sjg@chromium.org wrote: > > > > > Sync these files, obtained from Linux v5.15. > > > > Sorry, but this would be wrong. > > How do you know which board it is? Highbank or Midway? We use the > > same binary for both, and decide either by the DT nodes we find in DRAM > > or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are > > differences. The memory size would possibly be wrong (it's a DIMM slot). > > If you need *some* DT for build reasons, whatever, but at least go with > > the empty stub. > > > > And I still don't get this whole development argument: Why would > > anyone need some random or partial DT sample in the U-Boot tree to do > > development? > > If people develop a driver, the document to code against is the > > *binding* documentation, which describes what to expect from the DT > > nodes. Then you *test* it against an actual tree, but on the actual > > hardware, in which case you get the actual DTB, from the board. > > If a developer needs to take a sneak peek into an actual DTB, > > there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD > > card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the > > kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a > > board, getting hands on the actual DT is probably the least of your > > problems. > > > > So why would we need some mostly wrong DTs in the U-Boot tree? > > It seems to suggest that you can hack the DT to make things work, but > > this sounds bonkers, as the real DTB comes from somewhere else (SPI > > flash, SD card, generated based on command line), and patching U-Boot's > > copy to make things work is just wishful thinking. > > > > I can see the hacker's desire to play around with the DTB from time > > to time (What happens if the GPIO is wrong? Can we deal with two > > instances of the same device?), but for those experiments there are > > plenty of ways to achieve this - and be it temporarily replacing the > > empty DT stub. I just feel that bending the (board's) DT design ideas > > for a hacker's pleasure is not justified.
Andre, if you'd like to attend the U-Boot contributor call in an hour, please do.
> > This, largely, is why I still don't understand or agree with the > direction this series is taking platforms that currently use > CONFIG_OF_BOARD=y today.
I am not sure what else to do at this point. For real boards, there has to be some base devicetree somewhere that is put into the firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
Just because it changes at runtime does not change that fact. So we can inject any DT into the firmware and the same transformations should happen. We just need to have the same one as everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
As v7 stands yes. But I'm still drafting my reply to the first patch in the series.
So that's actually worse than Linux. I think that would be a great shame.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
I don't understand. What can't we support in mainline anymore? As Andre noted, you implement versus bindings.
I mean, we don't have to worry about it, nor include the devicetree in U-Boot, etc. It is effectively a downstream board and it's up to the maintainer to worry about it. We cannot use Binman with it anyway, since we don't have the devicetree, so the long-term aims of all this effort are not relevant for that board.
So in other words, if Midway doesn't exist in Linux, it doesn't need to existing in U-Boot either.
Actually I cannot find Midway in Linux either, so perhaps Andre can clarify that?
Regards, Simon

On Tue, Dec 07, 2021 at 09:21:40AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:14, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:09:54AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote: > Hi Andre, > > On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote: > > > > On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote: > > > On Mon, 6 Dec 2021 17:11:52 -0700 > > > Simon Glass sjg@chromium.org wrote: > > > > > > > Sync these files, obtained from Linux v5.15. > > > > > > Sorry, but this would be wrong. > > > How do you know which board it is? Highbank or Midway? We use the > > > same binary for both, and decide either by the DT nodes we find in DRAM > > > or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are > > > differences. The memory size would possibly be wrong (it's a DIMM slot). > > > If you need *some* DT for build reasons, whatever, but at least go with > > > the empty stub. > > > > > > And I still don't get this whole development argument: Why would > > > anyone need some random or partial DT sample in the U-Boot tree to do > > > development? > > > If people develop a driver, the document to code against is the > > > *binding* documentation, which describes what to expect from the DT > > > nodes. Then you *test* it against an actual tree, but on the actual > > > hardware, in which case you get the actual DTB, from the board. > > > If a developer needs to take a sneak peek into an actual DTB, > > > there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD > > > card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the > > > kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a > > > board, getting hands on the actual DT is probably the least of your > > > problems. > > > > > > So why would we need some mostly wrong DTs in the U-Boot tree? > > > It seems to suggest that you can hack the DT to make things work, but > > > this sounds bonkers, as the real DTB comes from somewhere else (SPI > > > flash, SD card, generated based on command line), and patching U-Boot's > > > copy to make things work is just wishful thinking. > > > > > > I can see the hacker's desire to play around with the DTB from time > > > to time (What happens if the GPIO is wrong? Can we deal with two > > > instances of the same device?), but for those experiments there are > > > plenty of ways to achieve this - and be it temporarily replacing the > > > empty DT stub. I just feel that bending the (board's) DT design ideas > > > for a hacker's pleasure is not justified. > > Andre, if you'd like to attend the U-Boot contributor call in an hour, > please do. > > https://bit.ly/3bFvwA1: > > > > > This, largely, is why I still don't understand or agree with the > > direction this series is taking platforms that currently use > > CONFIG_OF_BOARD=y today. > > I am not sure what else to do at this point. For real boards, there > has to be some base devicetree somewhere that is put into the > firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
> Just because it changes at runtime does not change that > fact. So we can inject any DT into the firmware and the same > transformations should happen. We just need to have the same one as > everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
As v7 stands yes. But I'm still drafting my reply to the first patch in the series.
So that's actually worse than Linux. I think that would be a great shame.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
I don't understand. What can't we support in mainline anymore? As Andre noted, you implement versus bindings.
I mean, we don't have to worry about it, nor include the devicetree in U-Boot, etc. It is effectively a downstream board and it's up to the maintainer to worry about it. We cannot use Binman with it anyway, since we don't have the devicetree, so the long-term aims of all this effort are not relevant for that board.
So in other words, if Midway doesn't exist in Linux, it doesn't need to existing in U-Boot either.
Actually I cannot find Midway in Linux either, so perhaps Andre can clarify that?
It works the way device trees are intended to work in Linux, and in U-Boot. The device tree describes the peripherals, the software enables the peripherals and the software (Linux, U-Boot, FreeBSD, what have you) don't need board-centric code.

On Tue, 7 Dec 2021 09:21:40 -0700 Simon Glass sjg@chromium.org wrote:
Hi Simon,
Hi Tom,
On Tue, 7 Dec 2021 at 09:14, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:09:54AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote: > Hi Andre, > > On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote: > > > > On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote: > > > On Mon, 6 Dec 2021 17:11:52 -0700 > > > Simon Glass sjg@chromium.org wrote: > > > > > > > Sync these files, obtained from Linux v5.15. > > > > > > Sorry, but this would be wrong. > > > How do you know which board it is? Highbank or Midway? We use the > > > same binary for both, and decide either by the DT nodes we find in DRAM > > > or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are > > > differences. The memory size would possibly be wrong (it's a DIMM slot). > > > If you need *some* DT for build reasons, whatever, but at least go with > > > the empty stub. > > > > > > And I still don't get this whole development argument: Why would > > > anyone need some random or partial DT sample in the U-Boot tree to do > > > development? > > > If people develop a driver, the document to code against is the > > > *binding* documentation, which describes what to expect from the DT > > > nodes. Then you *test* it against an actual tree, but on the actual > > > hardware, in which case you get the actual DTB, from the board. > > > If a developer needs to take a sneak peek into an actual DTB, > > > there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD > > > card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the > > > kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a > > > board, getting hands on the actual DT is probably the least of your > > > problems. > > > > > > So why would we need some mostly wrong DTs in the U-Boot tree? > > > It seems to suggest that you can hack the DT to make things work, but > > > this sounds bonkers, as the real DTB comes from somewhere else (SPI > > > flash, SD card, generated based on command line), and patching U-Boot's > > > copy to make things work is just wishful thinking. > > > > > > I can see the hacker's desire to play around with the DTB from time > > > to time (What happens if the GPIO is wrong? Can we deal with two > > > instances of the same device?), but for those experiments there are > > > plenty of ways to achieve this - and be it temporarily replacing the > > > empty DT stub. I just feel that bending the (board's) DT design ideas > > > for a hacker's pleasure is not justified. > > Andre, if you'd like to attend the U-Boot contributor call in an hour, > please do. > > https://bit.ly/3bFvwA1: > > > > > This, largely, is why I still don't understand or agree with the > > direction this series is taking platforms that currently use > > CONFIG_OF_BOARD=y today. > > I am not sure what else to do at this point. For real boards, there > has to be some base devicetree somewhere that is put into the > firmware.
Yes, there is. It's in the firmware on the hardware. That's where it lives.
> Just because it changes at runtime does not change that > fact. So we can inject any DT into the firmware and the same > transformations should happen. We just need to have the same one as > everyone else uses.
I think you're missing the point here still. The DT lives IN the firmware. In that an official dts for that firmware exists somewhere, I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
As v7 stands yes. But I'm still drafting my reply to the first patch in the series.
So that's actually worse than Linux. I think that would be a great shame.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
I don't understand. What can't we support in mainline anymore? As Andre noted, you implement versus bindings.
I mean, we don't have to worry about it, nor include the devicetree in U-Boot, etc. It is effectively a downstream board and it's up to the maintainer to worry about it. We cannot use Binman with it anyway, since we don't have the devicetree, so the long-term aims of all this effort are not relevant for that board.
I think the point is that U-Boot here is not the main firmware per-se, but just a bootloader, part of a whole firmware package. It *consumes* the DT provided by the former firmware, and hands it on to the loaded application (Linux, *BSD, you name it). The U-Boot binary is just another blob living in one of the SPI flash partitions, next to the DTB. There is no need for U-Boot to provide packaging of any kind. I never thought that would be something that U-Boot was opposed against?
So in other words, if Midway doesn't exist in Linux, it doesn't need to existing in U-Boot either.
Why does Midway not "exist in Linux"? Does this break down to: "if a board does not have a .dts file in the Linux kernel tree, it is not supported"? (Ignoring all the "real hardware(TM)" that uses ACPI for a moment, and QEMU and kvmtool and Xen, ...) To have Linux working, you would need to have your peripherals supported by drivers, and provide DT nodes complying to the documented bindings for those drivers. In reality this mostly boils down to have the SoC peripherals supported, and not having exotic chips on the board, but then Linux would just work, even if the .dts files are not merged into the tree. Granted, you should send your DT, but this is not really a technical necessity.
Actually I cannot find Midway in Linux either, so perhaps Andre can clarify that?
I don't want to give you funny ideas, but it's ecx-2000.dts in arch/arm/boot/dts ;-) But that really doesn't matter, the .dts files are just there for documentation purposes, have ever been, the actual DT comes from the SPI flash, loaded into DRAM by the BMC. So please do not include ecx-2000.dts in v8 ;-)
Cheers, Andre

On Tue, Dec 07, 2021 at 05:13:58PM +0000, Andre Przywara wrote:
On Tue, 7 Dec 2021 09:21:40 -0700 Simon Glass sjg@chromium.org wrote:
Hi Simon,
Hi Tom,
On Tue, 7 Dec 2021 at 09:14, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:09:54AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com wrote: > > On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote: > > Hi Andre, > > > > On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com wrote: > > > > > > On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara wrote: > > > > On Mon, 6 Dec 2021 17:11:52 -0700 > > > > Simon Glass sjg@chromium.org wrote: > > > > > > > > > Sync these files, obtained from Linux v5.15. > > > > > > > > Sorry, but this would be wrong. > > > > How do you know which board it is? Highbank or Midway? We use the > > > > same binary for both, and decide either by the DT nodes we find in DRAM > > > > or by some autodetection (Cortex-A9 vs. Cortex-A15) if there are > > > > differences. The memory size would possibly be wrong (it's a DIMM slot). > > > > If you need *some* DT for build reasons, whatever, but at least go with > > > > the empty stub. > > > > > > > > And I still don't get this whole development argument: Why would > > > > anyone need some random or partial DT sample in the U-Boot tree to do > > > > development? > > > > If people develop a driver, the document to code against is the > > > > *binding* documentation, which describes what to expect from the DT > > > > nodes. Then you *test* it against an actual tree, but on the actual > > > > hardware, in which case you get the actual DTB, from the board. > > > > If a developer needs to take a sneak peek into an actual DTB, > > > > there are so many simple ways to do that: QEMU's dumpdtb, RPi's SD > > > > card content, U-Boot's "fdt addr $fdtcontroladdr; fdt print", the > > > > kernel's /sys/firmware/devicetree/base, ... When you port U-Boot to a > > > > board, getting hands on the actual DT is probably the least of your > > > > problems. > > > > > > > > So why would we need some mostly wrong DTs in the U-Boot tree? > > > > It seems to suggest that you can hack the DT to make things work, but > > > > this sounds bonkers, as the real DTB comes from somewhere else (SPI > > > > flash, SD card, generated based on command line), and patching U-Boot's > > > > copy to make things work is just wishful thinking. > > > > > > > > I can see the hacker's desire to play around with the DTB from time > > > > to time (What happens if the GPIO is wrong? Can we deal with two > > > > instances of the same device?), but for those experiments there are > > > > plenty of ways to achieve this - and be it temporarily replacing the > > > > empty DT stub. I just feel that bending the (board's) DT design ideas > > > > for a hacker's pleasure is not justified. > > > > Andre, if you'd like to attend the U-Boot contributor call in an hour, > > please do. > > > > https://bit.ly/3bFvwA1: > > > > > > > > This, largely, is why I still don't understand or agree with the > > > direction this series is taking platforms that currently use > > > CONFIG_OF_BOARD=y today. > > > > I am not sure what else to do at this point. For real boards, there > > has to be some base devicetree somewhere that is put into the > > firmware. > > Yes, there is. It's in the firmware on the hardware. That's where it > lives. > > > Just because it changes at runtime does not change that > > fact. So we can inject any DT into the firmware and the same > > transformations should happen. We just need to have the same one as > > everyone else uses. > > I think you're missing the point here still. The DT lives IN the > firmware. In that an official dts for that firmware exists somewhere, > I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered from the answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS files, there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
As v7 stands yes. But I'm still drafting my reply to the first patch in the series.
So that's actually worse than Linux. I think that would be a great shame.
If it isn't public, why do we have the board in U-Boot? If one board is public and the other isn't, we should only care about the public board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support it because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
I don't understand. What can't we support in mainline anymore? As Andre noted, you implement versus bindings.
I mean, we don't have to worry about it, nor include the devicetree in U-Boot, etc. It is effectively a downstream board and it's up to the maintainer to worry about it. We cannot use Binman with it anyway, since we don't have the devicetree, so the long-term aims of all this effort are not relevant for that board.
I think the point is that U-Boot here is not the main firmware per-se, but just a bootloader, part of a whole firmware package. It *consumes* the DT provided by the former firmware, and hands it on to the loaded application (Linux, *BSD, you name it). The U-Boot binary is just another blob living in one of the SPI flash partitions, next to the DTB. There is no need for U-Boot to provide packaging of any kind. I never thought that would be something that U-Boot was opposed against?
So in other words, if Midway doesn't exist in Linux, it doesn't need to existing in U-Boot either.
Why does Midway not "exist in Linux"? Does this break down to: "if a board does not have a .dts file in the Linux kernel tree, it is not supported"? (Ignoring all the "real hardware(TM)" that uses ACPI for a moment, and QEMU and kvmtool and Xen, ...) To have Linux working, you would need to have your peripherals supported by drivers, and provide DT nodes complying to the documented bindings for those drivers. In reality this mostly boils down to have the SoC peripherals supported, and not having exotic chips on the board, but then Linux would just work, even if the .dts files are not merged into the tree. Granted, you should send your DT, but this is not really a technical necessity.
Actually I cannot find Midway in Linux either, so perhaps Andre can clarify that?
I don't want to give you funny ideas, but it's ecx-2000.dts in arch/arm/boot/dts ;-) But that really doesn't matter, the .dts files are just there for documentation purposes, have ever been, the actual DT comes from the SPI flash, loaded into DRAM by the BMC. So please do not include ecx-2000.dts in v8 ;-)
Thanks Andre for explaining more one of my points. This is how device tree is supposed to work for Linux, and this is how it's supposed to be able to be used for U-Boot, too.

Hi
On Tue, 7 Dec 2021 at 18:14, Andre Przywara andre.przywara@arm.com wrote:
On Tue, 7 Dec 2021 09:21:40 -0700 Simon Glass sjg@chromium.org wrote:
Hi Simon,
Hi Tom,
On Tue, 7 Dec 2021 at 09:14, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:09:54AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 09:07, Tom Rini trini@konsulko.com wrote:
On Tue, Dec 07, 2021 at 09:02:23AM -0700, Simon Glass wrote:
Hi Tom,
On Tue, 7 Dec 2021 at 08:39, Tom Rini trini@konsulko.com
wrote:
> > On Tue, Dec 07, 2021 at 08:33:49AM -0700, Simon Glass wrote: > > Hi Andre, > > > > On Tue, 7 Dec 2021 at 08:25, Tom Rini trini@konsulko.com
wrote:
> > > > > > On Tue, Dec 07, 2021 at 12:59:48AM +0000, Andre Przywara
wrote:
> > > > On Mon, 6 Dec 2021 17:11:52 -0700 > > > > Simon Glass sjg@chromium.org wrote: > > > > > > > > > Sync these files, obtained from Linux v5.15. > > > > > > > > Sorry, but this would be wrong. > > > > How do you know which board it is? Highbank or Midway?
We use the
> > > > same binary for both, and decide either by the DT nodes
we find in DRAM
> > > > or by some autodetection (Cortex-A9 vs. Cortex-A15) if
there are
> > > > differences. The memory size would possibly be wrong
(it's a DIMM slot).
> > > > If you need *some* DT for build reasons, whatever, but
at least go with
> > > > the empty stub. > > > > > > > > And I still don't get this whole development argument:
Why would
> > > > anyone need some random or partial DT sample in the
U-Boot tree to do
> > > > development? > > > > If people develop a driver, the document to code against
is the
> > > > *binding* documentation, which describes what to expect
from the DT
> > > > nodes. Then you *test* it against an actual tree, but on
the actual
> > > > hardware, in which case you get the actual DTB, from the
board.
> > > > If a developer needs to take a sneak peek into an actual
DTB,
> > > > there are so many simple ways to do that: QEMU's
dumpdtb, RPi's SD
> > > > card content, U-Boot's "fdt addr $fdtcontroladdr; fdt
print", the
> > > > kernel's /sys/firmware/devicetree/base, ... When you
port U-Boot to a
> > > > board, getting hands on the actual DT is probably the
least of your
> > > > problems. > > > > > > > > So why would we need some mostly wrong DTs in the U-Boot
tree?
> > > > It seems to suggest that you can hack the DT to make
things work, but
> > > > this sounds bonkers, as the real DTB comes from
somewhere else (SPI
> > > > flash, SD card, generated based on command line), and
patching U-Boot's
> > > > copy to make things work is just wishful thinking. > > > > > > > > I can see the hacker's desire to play around with the
DTB from time
> > > > to time (What happens if the GPIO is wrong? Can we deal
with two
> > > > instances of the same device?), but for those
experiments there are
> > > > plenty of ways to achieve this - and be it temporarily
replacing the
> > > > empty DT stub. I just feel that bending the (board's) DT
design ideas
> > > > for a hacker's pleasure is not justified. > > > > Andre, if you'd like to attend the U-Boot contributor call
in an hour,
> > please do. > > > > https://bit.ly/3bFvwA1: > > > > > > > > This, largely, is why I still don't understand or agree
with the
> > > direction this series is taking platforms that currently
use
> > > CONFIG_OF_BOARD=y today. > > > > I am not sure what else to do at this point. For real
boards, there
> > has to be some base devicetree somewhere that is put into the > > firmware. > > Yes, there is. It's in the firmware on the hardware. That's
where it
> lives. > > > Just because it changes at runtime does not change that > > fact. So we can inject any DT into the firmware and the same > > transformations should happen. We just need to have the same
one as
> > everyone else uses. > > I think you're missing the point here still. The DT lives IN
the
> firmware. In that an official dts for that firmware exists
somewhere,
> I gather it's not public, because it doesn't have to be.
That was my question to François a while back and I gathered
from the
answer that everything is public / open-source.
We already know every DT-using platform doesn't have public DTS
files,
there's the broadcom platform that was talked about an iteration or three back.
Also this is just copied from Linux, which I understand you were comfortable with.
I also said when the custodian doesn't object.
So what is the fallback? Another empty tree?
As v7 stands yes. But I'm still drafting my reply to the first patch
in
the series.
So that's actually worse than Linux. I think that would be a great shame.
If it isn't public, why do we have the board in U-Boot? If one
board
is public and the other isn't, we should only care about the
public
board, IMO. I hope I just have the wrong end of the stick here.
I'm elaborating on this in a draft right now still, but we support
it
because it works? That's part of the point of device trees, the information gets provided at run time.
We cannot support that stuff in mainline. It is up to the maintainer to keep things working.
I don't understand. What can't we support in mainline anymore? As Andre noted, you implement versus bindings.
I mean, we don't have to worry about it, nor include the devicetree in U-Boot, etc. It is effectively a downstream board and it's up to the maintainer to worry about it. We cannot use Binman with it anyway, since we don't have the devicetree, so the long-term aims of all this effort are not relevant for that board.
I think the point is that U-Boot here is not the main firmware per-se, but just a bootloader, part of a whole firmware package. It *consumes* the DT provided by the former firmware, and hands it on to the loaded application (Linux, *BSD, you name it). The U-Boot binary is just another blob living in one of the SPI flash partitions, next to the DTB. There is no need for U-Boot to provide packaging of any kind. I never thought that would be something that U-Boot was opposed against?
So in other words, if Midway doesn't exist in Linux, it doesn't need to existing in U-Boot either.
Why does Midway not "exist in Linux"? Does this break down to: "if a board does not have a .dts file in the Linux kernel tree, it is not supported"? (Ignoring all the "real hardware(TM)" that uses ACPI for a moment, and QEMU and kvmtool and Xen, ...) To have Linux working, you would need to have your peripherals supported by drivers, and provide DT nodes complying to the documented bindings for those drivers. In reality this mostly boils down to have the SoC peripherals supported, and not having exotic chips on the board, but then Linux would just work, even if the .dts files are not merged into the tree. Granted, you should send your DT, but this is not really a technical necessity.
Actually I cannot find Midway in Linux either, so perhaps Andre can clarify that?
I don't want to give you funny ideas, but it's ecx-2000.dts in arch/arm/boot/dts ;-) But that really doesn't matter, the .dts files are just there for documentation purposes, have ever been, the actual DT comes from the SPI flash, loaded into DRAM by the BMC. So please do not include ecx-2000.dts in v8 ;-)
I think similar things applies to a number of boards. For instance the
SolidRun Honeycomb board is based on an NXP chip that has a Serdes. U-Boot needs to see the SerDes to properly configure it and make it either PCI or MDIO devices for Linux. So the board DTB that U-Boot receives contains SerDes nodes. It should remove it and add necessary PCI or MDIO nodes for the operating system. The way to achieve this is to be decided board per board: - You can have a second device tree that you will hand over to the OS, - you can apply an overlay, - you can apply fixups to the one provided by the previous firmware. On the Honeycomb, compile options (SERDES=SD1_SD2_SD3) configures the hw properly and hands over the right DTB nodes to the OS. Bottom line, you should not copy the Linux DTS of honeycomb into U-Boot too.
Cheers, Andre

This should not be a separate option from OF_SEPARATE. It is a run-time option to override the devicetree, even if present.
Move the option out of the choice.
Disable BINMAN_FDT for a few boards which don't actually use it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
configs/qemu-ppce500_defconfig | 1 + configs/qemu-riscv32_spl_defconfig | 2 ++ configs/qemu-riscv64_spl_defconfig | 1 + dts/Kconfig | 11 ++++++----- 4 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index ae4cd8b9618..81d12d5f3c1 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -56,4 +56,5 @@ CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_BLK=y CONFIG_ADDR_MAP=y +# CONFIG_BINMAN_FDT is not set CONFIG_PANIC_HANG=y diff --git a/configs/qemu-riscv32_spl_defconfig b/configs/qemu-riscv32_spl_defconfig index c4422969c61..8889b028c6b 100644 --- a/configs/qemu-riscv32_spl_defconfig +++ b/configs/qemu-riscv32_spl_defconfig @@ -6,6 +6,7 @@ CONFIG_DEFAULT_DEVICE_TREE="qemu-virt32" CONFIG_SPL=y CONFIG_TARGET_QEMU_VIRT=y CONFIG_RISCV_SMODE=y +# CONFIG_OF_BOARD_FIXUP is not set CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x80200000 CONFIG_FIT=y @@ -18,3 +19,4 @@ CONFIG_OF_BOARD=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYSRESET_SBI=y +# CONFIG_BINMAN_FDT is not set diff --git a/configs/qemu-riscv64_spl_defconfig b/configs/qemu-riscv64_spl_defconfig index e02ca3a1465..8f875949ec0 100644 --- a/configs/qemu-riscv64_spl_defconfig +++ b/configs/qemu-riscv64_spl_defconfig @@ -19,3 +19,4 @@ CONFIG_OF_BOARD=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y CONFIG_SYSRESET_SBI=y +# CONFIG_BINMAN_FDT is not set diff --git a/dts/Kconfig b/dts/Kconfig index b7c4a2fec03..9994ab13dcb 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -97,11 +97,9 @@ config OF_LIVE choice prompt "Provider of DTB for DT control" depends on OF_CONTROL - default OF_BOARD if SANDBOX
config OF_SEPARATE bool "Separate DTB for DT control" - depends on !SANDBOX help If this option is enabled, the device tree will be built and placed as a separate u-boot.dtb file alongside the U-Boot image. @@ -114,14 +112,17 @@ config OF_EMBED and development only and is not recommended for production devices. Boards in the mainline U-Boot tree should not use it.
+endchoice + config OF_BOARD bool "Provided by the board (e.g a previous loader) at runtime" + default y if SANDBOX help If this option is enabled, the device tree will be provided by - the board at runtime if the board supports it, instead of being - bundled with the image. + the board at runtime if the board supports it. The device tree bundled + with the image (if any) will be overridden / ignored.
-endchoice + A device tree file must be provided in the tree.
config DEFAULT_DEVICE_TREE string "Default Device Tree for DT control"

This was added as a hack to work around not having an in-tree devicetree. Now that this is fixed it is not needed.
Drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 3 +-- dts/Kconfig | 18 ------------------ tools/binman/binman.rst | 20 -------------------- 3 files changed, 1 insertion(+), 40 deletions(-)
diff --git a/Makefile b/Makefile index 043af9a5dcd..6671c5d9e2f 100644 --- a/Makefile +++ b/Makefile @@ -953,7 +953,6 @@ endif endif INPUTS-$(CONFIG_TPL) += tpl/u-boot-tpl.bin INPUTS-$(CONFIG_OF_SEPARATE) += u-boot.dtb -INPUTS-$(CONFIG_BINMAN_STANDALONE_FDT) += u-boot.dtb ifeq ($(CONFIG_SPL_FRAMEWORK),y) INPUTS-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img endif @@ -1427,7 +1426,7 @@ u-boot-lzma.img: u-boot.bin.lzma FORCE
u-boot-dtb.img u-boot.img u-boot.kwb u-boot.pbl u-boot-ivt.img: \ $(if $(CONFIG_SPL_LOAD_FIT),u-boot-nodtb.bin \ - $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SANDBOX)$(CONFIG_BINMAN_STANDALONE_FDT),dts/dt.dtb) \ + $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SANDBOX),dts/dt.dtb) \ ,$(UBOOT_BIN)) FORCE $(call if_changed,mkimage) $(BOARD_SIZE_CHECK) diff --git a/dts/Kconfig b/dts/Kconfig index 9994ab13dcb..6ebbac2a649 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -16,24 +16,6 @@ config BINMAN bool select DTOC
-config BINMAN_STANDALONE_FDT - bool - depends on BINMAN - default y if OF_BOARD - help - This option tells U-Boot build system that a standalone device tree - source is explicitly required when using binman to package U-Boot. - - This is not necessary in a common scenario where a device tree source - that contains the binman node is provided in the arch/<arch>/dts - directory for a specific board. Such device tree sources are built for - OF_SEPARATE or OF_EMBED. However for a scenario like the board device - tree blob is not provided in the U-Boot build tree, but fed to U-Boot - in the runtime, e.g.: in the OF_BOARD case that it is passed by - a prior stage bootloader. For such scenario, a standalone device tree - blob containing binman node to describe how to package U-Boot should - be provided explicitly. - menu "Device Tree Control" depends on SUPPORT_OF_CONTROL
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 10389a52c4b..56f865800e6 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -232,26 +232,6 @@ You can use other, more specific CONFIG options - see 'Automatic .dtsi inclusion' below.
-Using binman with OF_BOARD --------------------------------------------- - -Normally binman is used with a board configured with OF_SEPARATE or OF_EMBED. -This is a typical scenario where a device tree source that contains the binman -node is provided in the arch/<arch>/dts directory for a specific board. - -However for a board configured with OF_BOARD, no device tree blob is provided -in the U-Boot build phase hence the binman node information is not available. -In order to support such use case, a new Kconfig option BINMAN_STANDALONE_FDT -is introduced, to tell the build system that a standalone device tree blob -containing binman node is explicitly required. - -Note there is a Kconfig option BINMAN_FDT which enables U-Boot run time to -access information about binman entries, stored in the device tree in a binman -node. Generally speaking, this option makes sense for OF_SEPARATE or OF_EMBED. -For the other OF_CONTROL methods, it's quite possible binman node is not -available as binman is invoked during the build phase, thus this option is not -turned on by default for these OF_CONTROL methods. - Access to binman entry offsets at run time (symbols) ----------------------------------------------------

Since OF_BOARD has been corrected to be a run-time option, we can drop the historical info from this documentation.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/devicetree/dt_update.rst | 74 +++------------------------- 1 file changed, 7 insertions(+), 67 deletions(-)
diff --git a/doc/develop/devicetree/dt_update.rst b/doc/develop/devicetree/dt_update.rst index e3b65f6fa66..10a2dfcfd39 100644 --- a/doc/develop/devicetree/dt_update.rst +++ b/doc/develop/devicetree/dt_update.rst @@ -32,66 +32,6 @@ that board on suitable hardware (or emulation). This is specified using the `CONFIG DEFAULT_DEVICE_TREE` option.
-Current situation (October 2021) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -As an aside, at present U-Boot allows `CONFIG_DEFAULT_DEVICE_TREE` to be empty, -e.g. if `CONFIG_OF_BOARD` is used. This has unfortunately created an enormous -amount of confusion and some wasted effort. This was not intended. Support for -an empty `CONFIG_DEFAULT_DEVICE_TREE` will be dropped soon. - -Some of the problems created are: - -- It is not obvious that the devicetree is coming from another project - -- There is no way to see even a sample devicetree for these platform in U-Boot, - so it is hard to know what is going on, e.g. which devices are typically - present - -- The other project may not provide a way to support U-Boot's requirements for - devicetree, such as the /config node. Note: On the U-Boot mailing list, this - was only discovered after weeks of discussion and confusion - -- For QEMU specifically, consulting two QEMU source files is required, for which - there are no references in U-Boot documentation. The code is generating a - devicetree, but it is not clear what controls affect this generation. - -Specifically on the changes in U-Bootm `CONFIG_OF_BOARD` was added in -rpi_patch_ for Raspberry Pi, which does have an in-tree devicetree, but this -feature has since been used for boards that don't - -Once this bug is fixed, CONFIG_OF_BOARD will override (at runtime) the -evicetree suppled with U-Boot, but will otherwise use CONFIG_OF_SEPARATE for the -in-tree build. So these two will become options, moving out of the 'choice' in -`dts/Kconfig`. - -This means that there is a basic devicetree build in the U-Boot tree, for -build-testing, consistency and documentation purposes, but at runtime U-Boot can -accept its devicetree from another source. The in-tree devicetree may contain -U-Boot-specific features (in u-boot*.dtsi files) and this may prove useful for -the other project, so it can ensure that U-Boot functions correctly and supports -all its expected features. - -To be clear, while U-Boot has its own copy of the devicetree source for each -board, this must match the Linux source, perhaps with some u-boot.dtsi -additions. The intent here is not to create a separate binding, just to provide -a representative devicetree in U-Boot. - -Offending boards are: - -- rpi_4 and rpi_4_32b (other rpi boards do have an in-tree devicetree) -- qemu_arm64 -- qemu_arm -- qemu-ppce500 -- qemu-riscv32 -- qemu-riscv32_smode -- qemu-riscv64 -- qemu-riscv64_smode - -All of these need to have a devicetree added in-tree. This is targeted to be -fixed in the 2022.01 release. - - Building the devicetree -----------------------
@@ -198,17 +138,18 @@ The /config node is similar in concept to the `/chosen node`_ except that it is for passing information *into* firmware instead of from firmware to the Operating System. Also, while Linux has a (sometimes extremely long) command line, U-Boot does not support this. The devicetree provides a more structured -approach in any case. +approach in any case. Upstreaming of this node (as /options) has begun as of +November 2021.
Devicetree in another project -----------------------------
-In some cases U-Boot receive its devicetree at runtime from a program that calls -it. For example ARM's Trusted Firmware A (`TF-A`_) may have a devicetree that it -passes to U-Boot. This overrides any devicetree build by U-Boot. When packaging -the firmware, the U-Boot devicetree may in fact be left out if it can be -guaranteed that it will receive one from another project. +In some cases U-Boot receives its devicetree at runtime from a program that +calls it. For example ARM's Trusted Firmware A (`TF-A`_) may have a devicetree +that it passes to U-Boot. This overrides any devicetree build by U-Boot. When +packaging the firmware, the U-Boot devicetree may in fact be left out if it can +be guaranteed that it will receive one from another project.
In this case, the devicetree in the other project must track U-Boot's use of device tree, for the following reasons: @@ -546,7 +487,6 @@ Overall, adding a second devicetree would create enormous confusion and complexity. It seems a lot cheaper to solve this by a change of attitude.
-.. _rpi_patch: https://patchwork.ozlabs.org/project/uboot/patch/20170402082520.32546-1-deym... .. _`TF-A`: https://www.trustedfirmware.org/projects/tf-a .. _`QEMU ARM`: https://github.com/qemu/qemu/blob/master/hw/arm/virt.c .. _`QEMU RISC-V`: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c

This logic is a bit convoluted for one function. Move the mulit-FIT part into its own function.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org ---
(no changes since v1)
lib/fdtdec.c | 62 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 24 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 7681f272d27..e0ce2532f95 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1594,13 +1594,46 @@ __weak int fdtdec_board_setup(const void *fdt_blob) return 0; }
+/** + * setup_multi_dtb_fit() - locate the correct dtb from a FIT + * + * This supports the CONFIG_MULTI_DTB_FIT feature, looking for the dtb in a + * supplied FIT + * + * It accepts the current value of gd->fdt_blob, which points to the FIT, then + * updates that gd->fdt_blob, to point to the chosen dtb so that U-Boot uses the + * correct one + */ +static void setup_multi_dtb_fit(void) +{ +# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) + void *blob; + + /* + * Try and uncompress the blob. + * Unfortunately there is no way to know how big the input blob really + * is. So let us set the maximum input size arbitrarily high. 16MB + * ought to be more than enough for packed DTBs. + */ + if (uncompress_blob(gd->fdt_blob, 0x1000000, &blob) == 0) + gd->fdt_blob = blob; + + /* + * Check if blob is a FIT images containings DTBs. + * If so, pick the most relevant + */ + blob = locate_dtb_in_fit(gd->fdt_blob); + if (blob) { + gd->multi_dtb_fit = gd->fdt_blob; + gd->fdt_blob = blob; + } +#endif /* # MULTI_DTB_FIT */ +} + int fdtdec_setup(void) { int ret; #if CONFIG_IS_ENABLED(OF_CONTROL) -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) - void *fdt_blob; -# endif # ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ # ifdef CONFIG_SPL_BUILD @@ -1621,27 +1654,8 @@ int fdtdec_setup(void) (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); # endif
-# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) - /* - * Try and uncompress the blob. - * Unfortunately there is no way to know how big the input blob really - * is. So let us set the maximum input size arbitrarily high. 16MB - * ought to be more than enough for packed DTBs. - */ - if (uncompress_blob(gd->fdt_blob, 0x1000000, &fdt_blob) == 0) - gd->fdt_blob = fdt_blob; - - /* - * Check if blob is a FIT images containings DTBs. - * If so, pick the most relevant - */ - fdt_blob = locate_dtb_in_fit(gd->fdt_blob); - if (fdt_blob) { - gd->multi_dtb_fit = gd->fdt_blob; - gd->fdt_blob = fdt_blob; - } - -# endif + if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) + setup_multi_dtb_fit(); #endif
ret = fdtdec_prepare_fdt();

Refactor the code to drop the #ifdefs for this feature.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
dts/Kconfig | 1 - include/asm-generic/global_data.h | 8 ++++++++ lib/fdtdec.c | 31 +++++++++++-------------------- 3 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/dts/Kconfig b/dts/Kconfig index 6ebbac2a649..5dcc79d5192 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -177,7 +177,6 @@ endchoice
config MULTI_DTB_FIT_UNCOMPRESS_SZ hex "Size of memory reserved to uncompress the DTBs" - depends on (MULTI_DTB_FIT_GZIP || MULTI_DTB_FIT_LZO) default 0x8000 help This is the size of this area where the DTBs are uncompressed. diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 16fd305a65c..99daa20c765 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -512,6 +512,14 @@ static_assert(sizeof(struct global_data) == GD_SIZE); #define gd_acpi_ctx() NULL #endif
+#if CONFIG_IS_ENABLED(MULTI_DTB_FIT) +#define gd_multi_dtb_fit() gd->multi_dtb_fit +#define gd_set_multi_dtb_fit(_dtb) gd->multi_dtb_fit = _dtb +#else +#define gd_multi_dtb_fit() NULL +#define gd_set_multi_dtb_fit(_dtb) +#endif + /** * enum gd_flags - global data flags * diff --git a/lib/fdtdec.c b/lib/fdtdec.c index e0ce2532f95..4967ab87075 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1146,11 +1146,10 @@ int fdtdec_setup_mem_size_base_lowest(void) return 0; }
-#if CONFIG_IS_ENABLED(MULTI_DTB_FIT) -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\ - CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO) static int uncompress_blob(const void *src, ulong sz_src, void **dstp) { +#if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\ + CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO) size_t sz_out = CONFIG_VAL(MULTI_DTB_FIT_UNCOMPRESS_SZ); bool gzip = 0, lzo = 0; ulong sz_in = sz_src; @@ -1175,11 +1174,11 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return -ENOMEM; } } else { -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_USER_DEFINED_AREA) +# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_USER_DEFINED_AREA) dst = (void *)CONFIG_VAL(MULTI_DTB_FIT_USER_DEF_ADDR); -# else +# else return -ENOTSUPP; -# endif +# endif }
if (CONFIG_IS_ENABLED(GZIP) && gzip) @@ -1197,16 +1196,12 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return -EBADMSG; } *dstp = dst; - return 0; -} -# else -static int uncompress_blob(const void *src, ulong sz_src, void **dstp) -{ +#else + *dstp = (void *)src; *dstp = (void *)src; +#endif return 0; } -# endif -#endif
#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* @@ -1606,7 +1601,6 @@ __weak int fdtdec_board_setup(const void *fdt_blob) */ static void setup_multi_dtb_fit(void) { -# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) void *blob;
/* @@ -1624,10 +1618,9 @@ static void setup_multi_dtb_fit(void) */ blob = locate_dtb_in_fit(gd->fdt_blob); if (blob) { - gd->multi_dtb_fit = gd->fdt_blob; + gd_set_multi_dtb_fit(gd->fdt_blob); gd->fdt_blob = blob; } -#endif /* # MULTI_DTB_FIT */ }
int fdtdec_setup(void) @@ -1664,7 +1657,6 @@ int fdtdec_setup(void) return ret; }
-#if CONFIG_IS_ENABLED(MULTI_DTB_FIT) int fdtdec_resetup(int *rescan) { void *fdt_blob; @@ -1675,8 +1667,8 @@ int fdtdec_resetup(int *rescan) * FIT image stillpresent there. Save the time and space * required to uncompress it again. */ - if (gd->multi_dtb_fit) { - fdt_blob = locate_dtb_in_fit(gd->multi_dtb_fit); + if (gd_multi_dtb_fit()) { + fdt_blob = locate_dtb_in_fit(gd_multi_dtb_fit());
if (fdt_blob == gd->fdt_blob) { /* @@ -1700,7 +1692,6 @@ int fdtdec_resetup(int *rescan) *rescan = 0; return 0; } -#endif
int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id, phys_addr_t *basep, phys_size_t *sizep,

Move this to the header file to clean up the C code.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/fdtdec.h | 14 ++++++++++++++ lib/fdtdec.c | 6 +----- 2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index 6c7ab887b20..68786111a44 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -111,6 +111,20 @@ struct fdt_pci_addr { extern u8 __dtb_dt_begin[]; /* embedded device tree blob */ extern u8 __dtb_dt_spl_begin[]; /* embedded device tree blob for SPL/TPL */
+/* Get a pointer to the embedded devicetree, if there is one, else NULL */ +static inline u8 *dtb_dt_embedded(void) +{ +#ifdef CONFIG_OF_EMBED +# ifdef CONFIG_SPL_BUILD + return __dtb_dt_spl_begin; +# else + return __dtb_dt_begin; +# endif +#else + return NULL; +#endif +} + /** * Compute the size of a resource. * diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4967ab87075..fbdc92c0813 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1629,11 +1629,7 @@ int fdtdec_setup(void) #if CONFIG_IS_ENABLED(OF_CONTROL) # ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ -# ifdef CONFIG_SPL_BUILD - gd->fdt_blob = __dtb_dt_spl_begin; -# else - gd->fdt_blob = __dtb_dt_begin; -# endif + gd->fdt_blob = dtb_dt_embedded(); # elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* Allow the board to override the fdt address. */ gd->fdt_blob = board_fdt_blob_setup(&ret);

This serves no purpose. Drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
lib/fdtdec.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index fbdc92c0813..299a2c3a32f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1203,7 +1203,6 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return 0; }
-#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* * For CONFIG_OF_SEPARATE, the board may optionally implement this to * provide and/or fixup the fdt. @@ -1226,7 +1225,6 @@ __weak void *board_fdt_blob_setup(int *err)
return fdt_blob; } -#endif
int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size) {

Change this to use if() instead of #if
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
lib/fdtdec.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 299a2c3a32f..659aeffd82e 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1634,12 +1634,11 @@ int fdtdec_setup(void) if (ret) return ret; # endif -# ifndef CONFIG_SPL_BUILD - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = map_sysmem - (env_get_ulong("fdtcontroladdr", 16, + if (!IS_ENABLED(CONFIG_SPL_BUILD)) { + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); -# endif + }
if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) setup_multi_dtb_fit();

This function should only be called when OF_CONTROL is enabled. It fails in fdtdec_prepare_fdt() anyway, since gd->fdt_blob stays as NULL if OF_CONTROL is not enabled.
Drop this useless check.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
lib/fdtdec.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 659aeffd82e..5b31064cee2 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1624,16 +1624,15 @@ static void setup_multi_dtb_fit(void) int fdtdec_setup(void) { int ret; -#if CONFIG_IS_ENABLED(OF_CONTROL) -# ifdef CONFIG_OF_EMBED +#ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ gd->fdt_blob = dtb_dt_embedded(); -# elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) +#elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* Allow the board to override the fdt address. */ gd->fdt_blob = board_fdt_blob_setup(&ret); if (ret) return ret; -# endif +#endif if (!IS_ENABLED(CONFIG_SPL_BUILD)) { /* Allow the early environment to override the fdt address */ gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, @@ -1642,7 +1641,6 @@ int fdtdec_setup(void)
if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) setup_multi_dtb_fit(); -#endif
ret = fdtdec_prepare_fdt(); if (!ret)

We only have two choices for obtaining the devicetree. Simplify the code to make that clear.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
lib/fdtdec.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 5b31064cee2..a7f62123a94 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1624,15 +1624,17 @@ static void setup_multi_dtb_fit(void) int fdtdec_setup(void) { int ret; -#ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = dtb_dt_embedded(); -#elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) - /* Allow the board to override the fdt address. */ - gd->fdt_blob = board_fdt_blob_setup(&ret); - if (ret) - return ret; -#endif + + /* The devicetree is typically appended to U-Boot */ + if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { + /* Allow the board to override the fdt address. */ + gd->fdt_blob = board_fdt_blob_setup(&ret); + if (ret) + return ret; + } else { /* embed dtb in ELF file for testing / development */ + gd->fdt_blob = dtb_dt_embedded(); + } + if (!IS_ENABLED(CONFIG_SPL_BUILD)) { /* Allow the early environment to override the fdt address */ gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16,

At present this override function is called even when OF_BOARD is not enabled. This makes it impossible to disable this feature and in fact makes the OF_BOARD option useless.
Reinstate its intended purpose, so that it is possible to switch between the appended devicetree and one provided by the board's custom function.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Fix 'Is' typo in commit message
Changes in v5: - Add new patches to clean up fdtdec_setup() and surrounds
include/fdtdec.h | 7 +++++-- lib/fdtdec.c | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index 68786111a44..68a36f10583 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -1170,10 +1170,13 @@ int fdtdec_resetup(int *rescan);
/** * Board-specific FDT initialization. Returns the address to a device tree blob. - * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined - * and the board implements it. + * + * Called when CONFIG_OF_BOARD is defined. + * + * The existing devicetree is available at gd->fdt_blob * * @err internal error code if we fail to setup a DTB + * @returns new devicetree blob pointer */ void *board_fdt_blob_setup(int *err);
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index a7f62123a94..31a509bc221 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1203,15 +1203,15 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) return 0; }
-/* - * For CONFIG_OF_SEPARATE, the board may optionally implement this to - * provide and/or fixup the fdt. +/** + * fdt_find_separate() - Find a devicetree at the end of the image + * + * @return pointer to FDT blob */ -__weak void *board_fdt_blob_setup(int *err) +static void *fdt_find_separate(void) { void *fdt_blob = NULL;
- *err = 0; #ifdef CONFIG_SPL_BUILD /* FDT is at end of BSS unless it is in a different memory region */ if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) @@ -1626,13 +1626,16 @@ int fdtdec_setup(void) int ret;
/* The devicetree is typically appended to U-Boot */ - if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { - /* Allow the board to override the fdt address. */ + if (IS_ENABLED(CONFIG_OF_SEPARATE)) + gd->fdt_blob = fdt_find_separate(); + else /* embed dtb in ELF file for testing / development */ + gd->fdt_blob = dtb_dt_embedded(); + + /* Allow the board to override the fdt address. */ + if (IS_ENABLED(CONFIG_OF_BOARD)) { gd->fdt_blob = board_fdt_blob_setup(&ret); if (ret) return ret; - } else { /* embed dtb in ELF file for testing / development */ - gd->fdt_blob = dtb_dt_embedded(); }
if (!IS_ENABLED(CONFIG_SPL_BUILD)) {

Add a function that returns some basic stats about driver model. For now we only have two.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/device.c | 11 ++++++++++ drivers/core/root.c | 7 ++++++ drivers/core/uclass.c | 13 ++++++++++++ include/dm/device.h | 11 +++++++++- include/dm/root.h | 8 +++++++ include/dm/uclass-internal.h | 7 ++++++ test/dm/core.c | 41 ++++++++++++++++++++++++++++++++++++ 7 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/drivers/core/device.c b/drivers/core/device.c index 74374ff881c..4873c47d10b 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -739,6 +739,17 @@ int device_get_child_count(const struct udevice *parent) return count; }
+int device_get_decendent_count(const struct udevice *parent) +{ + const struct udevice *dev; + int count = 1; + + list_for_each_entry(dev, &parent->child_head, sibling_node) + count += device_get_decendent_count(dev); + + return count; +} + int device_find_child_by_seq(const struct udevice *parent, int seq, struct udevice **devp) { diff --git a/drivers/core/root.c b/drivers/core/root.c index 26b8195faa3..815173f86eb 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -26,6 +26,7 @@ #include <dm/read.h> #include <dm/root.h> #include <dm/uclass.h> +#include <dm/uclass-internal.h> #include <dm/util.h> #include <linux/list.h>
@@ -407,6 +408,12 @@ int dm_init_and_scan(bool pre_reloc_only) return 0; }
+void dm_get_stats(int *device_countp, int *uclass_countp) +{ + *device_countp = device_get_decendent_count(gd->dm_root); + *uclass_countp = uclass_get_count(); +} + #ifdef CONFIG_ACPIGEN static int root_acpi_get_name(const struct udevice *dev, char *out_name) { diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 2aa21430775..336ea8d243d 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -643,6 +643,19 @@ int uclass_next_device_check(struct udevice **devp) return device_probe(*devp); }
+int uclass_get_count(void) +{ + const struct uclass *uc; + int count = 0; + + if (gd->dm_root) { + list_for_each_entry(uc, gd->uclass_root, sibling_node) + count++; + } + + return count; +} + int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, struct udevice **devp) { diff --git a/include/dm/device.h b/include/dm/device.h index daf28a0a457..19d37e0e76c 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -593,7 +593,7 @@ int device_get_child(const struct udevice *parent, int index, struct udevice **devp);
/** - * device_get_child_count() - Get the available child count of a device + * device_get_child_count() - Get the child count of a device * * Returns the number of children to a device. * @@ -601,6 +601,15 @@ int device_get_child(const struct udevice *parent, int index, */ int device_get_child_count(const struct udevice *parent);
+/** + * device_get_decendent_count() - Get the total number of decendents of a device + * + * Returns the total number of decendents, including all children + * + * @parent: Parent device to check + */ +int device_get_decendent_count(const struct udevice *parent); + /** * device_find_child_by_seq() - Find a child device based on a sequence * diff --git a/include/dm/root.h b/include/dm/root.h index 42510b106ab..780f269db65 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -131,4 +131,12 @@ int dm_remove_devices_flags(uint flags); static inline int dm_remove_devices_flags(uint flags) { return 0; } #endif
+/** + * dm_get_stats() - Get some stats for driver mode + * + * @device_countp: Returns total number of devices that are bound + * @uclass_countp: Returns total number of uclasses in use + */ +void dm_get_stats(int *device_countp, int *uclass_countp); + #endif diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index 49808c5c856..fb0edcc2969 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -306,6 +306,13 @@ int uclass_pre_remove_device(struct udevice *dev); static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; } #endif
+/** + * uclass_get_count() - Get the number of uclasses + * + * Returns the number of uclasses instantiated in driver model + */ +int uclass_get_count(void); + /** * uclass_find() - Find uclass by its id * diff --git a/test/dm/core.c b/test/dm/core.c index c9a7606666c..c76dfdb1651 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -307,11 +307,15 @@ static int dm_test_lifecycle(struct unit_test_state *uts) { int op_count[DM_TEST_OP_COUNT]; struct udevice *dev, *test_dev; + int start_dev_count, start_uc_count; + int dev_count, uc_count; int pingret; int ret;
memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
+ dm_get_stats(&start_dev_count, &start_uc_count); + ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual, &dev)); ut_assert(dev); @@ -319,6 +323,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts) == op_count[DM_TEST_OP_BIND] + 1); ut_assert(!dev_get_priv(dev));
+ /* We should have one more device */ + dm_get_stats(&dev_count, &uc_count); + ut_asserteq(start_dev_count + 1, dev_count); + ut_asserteq(start_uc_count, uc_count); + /* Probe the device - it should fail allocating private data */ uts->force_fail_alloc = 1; ret = device_probe(dev); @@ -353,6 +362,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts) ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
+ /* We should have one less device */ + dm_get_stats(&dev_count, &uc_count); + ut_asserteq(start_dev_count, dev_count); + ut_asserteq(start_uc_count, uc_count); + return 0; } DM_TEST(dm_test_lifecycle, UT_TESTF_SCAN_PDATA | UT_TESTF_PROBE_TEST); @@ -526,17 +540,31 @@ DM_TEST(dm_test_leak, 0); /* Test uclass init/destroy methods */ static int dm_test_uclass(struct unit_test_state *uts) { + int dev_count, uc_count; struct uclass *uc;
+ /* We should have just the root device and uclass */ + dm_get_stats(&dev_count, &uc_count); + ut_asserteq(1, dev_count); + ut_asserteq(1, uc_count); + ut_assertok(uclass_get(UCLASS_TEST, &uc)); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]); ut_assert(uclass_get_priv(uc));
+ dm_get_stats(&dev_count, &uc_count); + ut_asserteq(1, dev_count); + ut_asserteq(2, uc_count); + ut_assertok(uclass_destroy(uc)); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
+ dm_get_stats(&dev_count, &uc_count); + ut_asserteq(1, dev_count); + ut_asserteq(1, uc_count); + return 0; } DM_TEST(dm_test_uclass, 0); @@ -1217,3 +1245,16 @@ static int dm_test_dma_offset(struct unit_test_state *uts) } DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); #endif + +/* Test dm_get_stats() */ +static int dm_test_get_stats(struct unit_test_state *uts) +{ + int dev_count, uc_count; + + dm_get_stats(&dev_count, &uc_count); + ut_assert(dev_count > 50); + ut_assert(uc_count > 30); + + return 0; +} +DM_TEST(dm_test_get_stats, UT_TESTF_SCAN_FDT);

Keep track of where the devicetree came from, so we can report this later.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Drop FDTSRC_PASSAGE for now
include/asm-generic/global_data.h | 4 ++++ include/fdtdec.h | 32 +++++++++++++++++++++++++++++++ lib/fdtdec.c | 20 ++++++++++++++----- 3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 99daa20c765..104282bd479 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -244,6 +244,10 @@ struct global_data { * @fdt_size: space reserved for relocated device space */ unsigned long fdt_size; + /** + * @fdt_src: Source of FDT + */ + enum fdt_source_t fdt_src; #if CONFIG_IS_ENABLED(OF_LIVE) /** * @of_root: root node of the live tree diff --git a/include/fdtdec.h b/include/fdtdec.h index 68a36f10583..09525ce510a 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -55,6 +55,31 @@ struct bd_info; #define SPL_BUILD 0 #endif
+/** + * enum fdt_source_t - indicates where the devicetree came from + * + * These are listed in approximate order of desirability after FDTSRC_NONE + * + * @FDTSRC_SEPARATE: Appended to U-Boot. This is the normal approach if U-Boot + * is the only firmware being booted + * @FDTSRC_FIT: Found in a multi-dtb FIT. This should be used when U-Boot must + * select a devicetree from many options + * @FDTSRC_BOARD: Located by custom board code. This should only be used when + * the prior stage does not support FDTSRC_PASSAGE + * @FDTSRC_EMBED: Embedded into U-Boot executable. This should onyl be used when + * U-Boot is packaged as an ELF file, e.g. for debugging purposes + * @FDTSRC_ENV: Provided by the fdtcontroladdr environment variable. This should + * be used for debugging/development only + * @FDTSRC_NONE: No devicetree at all + */ +enum fdt_source_t { + FDTSRC_SEPARATE, + FDTSRC_FIT, + FDTSRC_BOARD, + FDTSRC_EMBED, + FDTSRC_ENV, +}; + /* * Information about a resource. start is the first address of the resource * and end is the last address (inclusive). The length of the resource will @@ -1215,4 +1240,11 @@ int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id, phys_addr_t *basep, phys_size_t *sizep, struct bd_info *bd);
+/** + * fdtdec_get_srcname() - Get the name of where the devicetree comes from + * + * @return source name + */ +const char *fdtdec_get_srcname(void); + #endif diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 31a509bc221..8cfa958fb96 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1618,6 +1618,7 @@ static void setup_multi_dtb_fit(void) if (blob) { gd_set_multi_dtb_fit(gd->fdt_blob); gd->fdt_blob = blob; + gd->fdt_src = FDTSRC_FIT; } }
@@ -1626,22 +1627,31 @@ int fdtdec_setup(void) int ret;
/* The devicetree is typically appended to U-Boot */ - if (IS_ENABLED(CONFIG_OF_SEPARATE)) + if (IS_ENABLED(CONFIG_OF_SEPARATE)) { gd->fdt_blob = fdt_find_separate(); - else /* embed dtb in ELF file for testing / development */ + gd->fdt_src = FDTSRC_SEPARATE; + } else { /* embed dtb in ELF file for testing / development */ gd->fdt_blob = dtb_dt_embedded(); + gd->fdt_src = FDTSRC_EMBED; + }
/* Allow the board to override the fdt address. */ if (IS_ENABLED(CONFIG_OF_BOARD)) { gd->fdt_blob = board_fdt_blob_setup(&ret); if (ret) return ret; + gd->fdt_src = FDTSRC_BOARD; }
+ /* Allow the early environment to override the fdt address */ if (!IS_ENABLED(CONFIG_SPL_BUILD)) { - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16, - (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); + ulong addr; + + addr = env_get_hex("fdtcontroladdr", 0); + if (addr) { + gd->fdt_blob = map_sysmem(addr, 0); + gd->fdt_src = FDTSRC_ENV; + } }
if (CONFIG_IS_ENABLED(MULTI_DTB_FIT))

It can be confusing to figure out where the devicetree came from. It seems important enough to warrant a message during boot. Add information about the number of devices and uclasses too since it is helpful to have some idea what is going on with driver model.
Report the devicetree source in bdinfo too.
This looks something like this, with > marking the new line.
U-Boot 2021.10-00190 (Oct 30 2021 - 09:01:29 -0600)
DRAM: 128 MiB
Core: 42 devices, 11 uclasses, devicetree: passage
Flash: 64 MiB
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Drop FDTSRC_PASSAGE for now
cmd/bdinfo.c | 2 ++ common/board_r.c | 18 ++++++++++++++++++ lib/fdtdec.c | 13 +++++++++++++ 3 files changed, 33 insertions(+)
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index bf63cc6d649..c56b3f4f6ec 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -128,6 +128,8 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); lmb_dump_all_force(&lmb); + if (IS_ENABLED(CONFIG_OF_REAL)) + printf("devicetree = %s\n", fdtdec_get_srcname()); }
arch_print_bdinfo(); diff --git a/common/board_r.c b/common/board_r.c index 31a59c585a8..99adff14b39 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -586,6 +586,23 @@ int initr_mem(void) } #endif
+static int dm_announce(void) +{ + int device_count; + int uclass_count; + + if (IS_ENABLED(CONFIG_DM)) { + dm_get_stats(&device_count, &uclass_count); + printf("Core: %d devices, %d uclasses", device_count, + uclass_count); + if (CONFIG_IS_ENABLED(OF_REAL)) + printf(", devicetree: %s", fdtdec_get_srcname()); + printf("\n"); + } + + return 0; +} + static int run_main_loop(void) { #ifdef CONFIG_SANDBOX @@ -661,6 +678,7 @@ static init_fnc_t init_sequence_r[] = { stdio_init_tables, serial_initialize, initr_announce, + dm_announce, #if CONFIG_IS_ENABLED(WDT) initr_watchdog, #endif diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 8cfa958fb96..118c100b389 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -76,6 +76,19 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init") };
+static const char *const fdt_src_name[] = { + [FDTSRC_SEPARATE] = "separate", + [FDTSRC_FIT] = "fit", + [FDTSRC_BOARD] = "board", + [FDTSRC_EMBED] = "embed", + [FDTSRC_ENV] = "env", +}; + +const char *fdtdec_get_srcname(void) +{ + return fdt_src_name[gd->fdt_src]; +} + const char *fdtdec_get_compatible(enum fdt_compat_id id) { /* We allow reading of the 'unknown' ID for testing purposes */

When U-Boot is started from another firmware program, not just a prior phase of U-Boot, special behaviour is typically used. In particular, the device tree may come from that prior stage.
At present this is sort-of indicated by OF_BOARD, although the correlation is not 1:1, since that option simply means that the board has a custom mechanism for obtaining the device tree. For example, sandbox defines OF_BOARD. Also the board_fdt_blob_setup() function can in fact make use of the devicetree in U-Boot if it wishes, as used by dragonboard410c until very recently.
Add an explicit Kconfig for this situation. Define it for boards which use this feature. Update the OF_BOARD option to more-accurately reflect what it is doing, e.g. for sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v7: - Add new patch to add a Kconfig for boards with a prior stage
arch/arm/Kconfig | 8 ++++++++ arch/arm/mach-bcm283x/Kconfig | 1 + board/emulation/qemu-riscv/Kconfig | 1 + dts/Kconfig | 31 ++++++++++++++++++++++++++---- lib/fdtdec.c | 1 + 5 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index eed27af74e8..d26461029af 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -635,6 +635,7 @@ config ARCH_BCMSTB select GPIO_EXTRA_HEADER select OF_CONTROL imply CMD_DM + imply OF_HAS_PRIOR_STAGE help This enables support for Broadcom ARM-based set-top box chipsets, including the 7445 family of chips. @@ -713,6 +714,7 @@ config ARCH_HIGHBANK select AHCI select DM_ETH select PHYS_64BIT + imply OF_HAS_PRIOR_STAGE
config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" @@ -966,6 +968,7 @@ config ARCH_QEMU imply DM_RNG imply DM_RTC imply RTC_PL031 + imply OF_HAS_PRIOR_STAGE
config ARCH_RMOBILE bool "Renesas ARM SoCs" @@ -1251,6 +1254,7 @@ config TARGET_VEXPRESS64_JUNO select DM_ETH select BLK select USB + imply OF_HAS_PRIOR_STAGE
config TARGET_TOTAL_COMPUTE bool "Support Total Compute Platform" @@ -1907,6 +1911,7 @@ config ARCH_OCTEONTX select OF_LIVE select BOARD_LATE_INIT select SYS_CACHE_SHIFT_7 + imply OF_HAS_PRIOR_STAGE
config ARCH_OCTEONTX2 bool "Support OcteonTX2 SoCs" @@ -1918,6 +1923,7 @@ config ARCH_OCTEONTX2 select OF_LIVE select BOARD_LATE_INIT select SYS_CACHE_SHIFT_7 + imply OF_HAS_PRIOR_STAGE
config TARGET_THUNDERX_88XX bool "Support ThunderX 88xx" @@ -1954,6 +1960,8 @@ config TARGET_XENGUEST_ARM64 select LINUX_KERNEL_IMAGE_HEADER select XEN_SERIAL select SSCANF + imply OF_HAS_PRIOR_STAGE + endchoice
config SUPPORT_PASSING_ATAGS diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig index b3287ce8bce..2eb3802d9ae 100644 --- a/arch/arm/mach-bcm283x/Kconfig +++ b/arch/arm/mach-bcm283x/Kconfig @@ -188,6 +188,7 @@ config TARGET_RPI_4
This option creates a build targeting the ARMv8/AArch64 ISA. select BCM2711_64B + imply OF_HAS_PRIOR_STAGE
config TARGET_RPI_ARM64 bool "Raspberry Pi one binary 64-bit build" diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 1bbf1bc84af..a380db61a0f 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -65,5 +65,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply VIRTIO_BLK imply MTD_NOR_FLASH imply CFI_FLASH + imply OF_HAS_PRIOR_STAGE
endif diff --git a/dts/Kconfig b/dts/Kconfig index 5dcc79d5192..803d0899556 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -100,11 +100,34 @@ config OF_BOARD bool "Provided by the board (e.g a previous loader) at runtime" default y if SANDBOX help - If this option is enabled, the device tree will be provided by - the board at runtime if the board supports it. The device tree bundled - with the image (if any) will be overridden / ignored. + If this option is enabled, the device tree is provided at runtime by + a custom function called board_fdt_blob_setup(). The board must + implement this function if it wishes to provide special behaviour.
- A device tree file must be provided in the tree. + With this option, the device tree build by U-Boot may be overridden or + ignored. See OF_HAS_PRIOR_STAGE. + + Note: Boards which use this to handle a device tree passed from an + earlier stage should enable OF_HAS_PRIOR_STAGE. + +config OF_HAS_PRIOR_STAGE + bool + help + Indicates that a prior stage of the firmware (before U-Boot proper) + makes use of device tree and this board normally boots with that prior + stage, that provides a devicetree to U-Boot. + + This means that the device tree built in U-Boot should not be packaged + in the firmware image. Instead, the prior stage's device tree should + be so packaged. At runtime, the prior stage reads this, does any + necessary fix-ups, then passes it to U-Boot. See OF_BOARD. + + This option does not preclude using the U-Boot device tree, e.g. for + development purposes, but it is not recommended, and likely will not + even work, for production systems. + + Note: This option must be set in Kconfig and cannot be enabled or + disabled in the board's defconfig file.
config DEFAULT_DEVICE_TREE string "Default Device Tree for DT control" diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 118c100b389..280cda61a72 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1595,6 +1595,7 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, return 0; }
+/* TODO(sjg@chromium.org): This function should not be weak */ __weak int fdtdec_board_setup(const void *fdt_blob) { return 0;

U-Boot always needs some sort of a device tree. Some boards never actually use this, at least in production systems, since a prior firmware stage sets one up and passes it to U-Boot. At present the only mechanism to do that is with custom function (OF_BOARD), but future work will include a standard way of doing this ('standard passage').
It can be confusing to see a device tree emitted from the U-Boot build in this situation. Add an option to drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 6 +++++- dts/Kconfig | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index 6671c5d9e2f..a3f018f01e0 100644 --- a/Makefile +++ b/Makefile @@ -952,7 +952,11 @@ INPUTS-$(CONFIG_SPL_FRAMEWORK) += u-boot.img endif endif INPUTS-$(CONFIG_TPL) += tpl/u-boot-tpl.bin + +# Allow omitting the .dtb output if it is not normally used +ifndef CONFIG_OF_OMIT_DTB INPUTS-$(CONFIG_OF_SEPARATE) += u-boot.dtb +endif ifeq ($(CONFIG_SPL_FRAMEWORK),y) INPUTS-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img endif @@ -1192,7 +1196,7 @@ u-boot.bin: u-boot-fit-dtb.bin FORCE u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE $(call if_changed,cat)
-else ifeq ($(CONFIG_OF_SEPARATE),y) +else ifeq ($(CONFIG_OF_SEPARATE).$(CONFIG_OF_OMIT_DTB),y.) u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE $(call if_changed,cat)
diff --git a/dts/Kconfig b/dts/Kconfig index 803d0899556..fd2829ad708 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -129,6 +129,16 @@ config OF_HAS_PRIOR_STAGE Note: This option must be set in Kconfig and cannot be enabled or disabled in the board's defconfig file.
+config OF_OMIT_DTB + bool "Omit the device tree output when building" + default y if OF_HAS_PRIOR_STAGE && !BINMAN + help + As a special case, avoid writing a device tree file u-boot.dtb when + building. Also don't include that file in u-boot.bin + + This is used for boards which normally provide a devicetree via a + runtime mechanism (such as OF_BOARD), to avoid confusion. + config DEFAULT_DEVICE_TREE string "Default Device Tree for DT control" depends on OF_CONTROL

Show a warning at build time if the devicetree is built for a board which normally should get it from a prior stage:
Warning: Devicetree was built but is not normally used on this board
When running, if the devicetree failed to come from the expected source, show a warning then also, e.g:
U-Boot ...
DRAM: 128 MiB Core: 42 devices, 11 uclasses, devicetree: separate Warning: Unexpected devicetree source (not from a prior stage) Warning: U-Boot may not function properly Flash: 64 MiB ...
These warnings should only appear if the board config has been changed, or the prior stage is broken.
Signed-off-by: Simon Glass sjg@chromium.org
---
(no changes since v1)
Makefile | 3 +++ common/board_r.c | 6 ++++++ 2 files changed, 9 insertions(+)
diff --git a/Makefile b/Makefile index a3f018f01e0..0059f10cbca 100644 --- a/Makefile +++ b/Makefile @@ -1107,6 +1107,9 @@ endif ifeq ($(CONFIG_DEPRECATED),y) $(warning "You have deprecated configuration options enabled in your .config! Please check your configuration.") endif +ifeq ($(CONFIG_OF_HAS_PRIOR_STAGE).$(CONFIG_OF_OMIT_DTB),y.) + @echo >&2 "Warning: Devicetree was built but is not normally used on this board" +endif ifeq ($(CONFIG_OF_EMBED)$(CONFIG_EFI_APP),y) @echo >&2 "===================== WARNING ======================" @echo >&2 "CONFIG_OF_EMBED is enabled. This option should only" diff --git a/common/board_r.c b/common/board_r.c index 99adff14b39..6d520662dbb 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -598,6 +598,12 @@ static int dm_announce(void) if (CONFIG_IS_ENABLED(OF_REAL)) printf(", devicetree: %s", fdtdec_get_srcname()); printf("\n"); + if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE) && + (gd->fdt_src == FDTSRC_SEPARATE || + gd->fdt_src == FDTSRC_EMBED)) { + printf("Warning: Unexpected devicetree source (not from a prior stage)"); + printf("Warning: U-Boot may not function properly\n"); + } }
return 0;

On Mon, Dec 06, 2021 at 05:11:38PM -0700, Simon Glass wrote:
[snip]
Changes in v7:
- Fix 'linst' typo
- Switch to using an empty file for qemu virt
- Switch to using an empty file for qemu virt
- Switch to using an empty file for qemu virt
- Reword commit message
- Bring in files from Linux instead
- Bring in files from Linux instead
- Rewrite the commit message
- Use 'empty' instead of 'fake'
- Use 'empty' instead of 'fake'
- Switch to using an empty file for qemu virt
- Bring in files from Linux instead
- Fix 'Is' typo in commit message
- Drop FDTSRC_PASSAGE for now
- Drop FDTSRC_PASSAGE for now
- Add new patch to add a Kconfig for boards with a prior stage
Alright, so I know François said to move to empty rather than dumping/"fake" dts file for this go-round. But I still don't like it. What Andre said vs the highbank patch is right. You develop against the binding.
Further, you see the problem of "it's board-specific how to update a platform dtb" having an answer of "hammer it in to U-Boot". The follow-up problem of "it's only going to get worse" has another solution to it I believe, which is that you're supposed to use capsule updates for this, if you're SystemReady compliant and able to ship the DTB on-device (I assume François or someone else can chime in here if I'm wrong).
I have more to say, but I think I need to reply that to the doc patch that adds your rationale for how DT should work in U-Boot.
participants (8)
-
Andre Przywara
-
François Ozog
-
Heinrich Schuchardt
-
Linus Walleij
-
Michal Simek
-
Oleksandr Andrushchenko
-
Simon Glass
-
Tom Rini