Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | .. sectionauthor:: Copyright 2011 The Chromium OS Authors |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 3 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 4 | Devicetree Control in U-Boot |
| 5 | ============================ |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 6 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 7 | This feature provides for run-time configuration of U-Boot via a flattened |
| 8 | devicetree (fdt). |
| 9 | |
| 10 | This feature aims to make it possible for a single U-Boot binary to support |
| 11 | multiple boards, with the exact configuration of each board controlled by |
| 12 | a flattened devicetree (fdt). This is the approach taken by Linux kernel for |
| 13 | ARM and RISC-V and has been used by PowerPC for some time. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 14 | |
| 15 | The fdt is a convenient vehicle for implementing run-time configuration |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 16 | for three reasons: |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 17 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 18 | - There is already excellent infrastructure for the fdt: a compiler checks |
| 19 | the text file and converts it to a compact binary format, and a library |
| 20 | is already available in U-Boot (libfdt) for handling this format |
| 21 | - It is extensible since it consists of nodes and properties in a nice |
| 22 | hierarchical format |
| 23 | - It is fairly efficient to read incrementally |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 24 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 25 | The arch/<arch>/dts directories contains a Makefile for building the devicetree |
| 26 | blob and embedding it in the U-Boot image. This is useful since it allows |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 27 | U-Boot to configure itself according to what it finds there. If you have |
| 28 | a number of similar boards with different peripherals, you can describe |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 29 | the features of each board in the devicetree file, and have a single |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 30 | generic source base. |
| 31 | |
| 32 | To enable this feature, add CONFIG_OF_CONTROL to your board config file. |
| 33 | |
| 34 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 35 | What is a Flattened Devicetree? |
| 36 | ------------------------------- |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 37 | |
| 38 | An fdt can be specified in source format as a text file. To read about |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 39 | the fdt syntax, take a look at the specification (dtspec_). |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 40 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 41 | There is also a mailing list (dtlist_) for the compiler and associated |
| 42 | tools. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 43 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 44 | In case you are wondering, OF stands for Open Firmware. This follows the |
| 45 | convention used in Linux. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 46 | |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 47 | |
| 48 | Tools |
| 49 | ----- |
| 50 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 51 | To create flattened device trees the device tree compiler is used. This is |
Simon Glass | 9665f19 | 2018-10-01 12:22:16 -0600 | [diff] [blame] | 52 | provided by U-Boot automatically. If you have a system version of dtc |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 53 | (typically in the 'device-tree-compiler' package), that system version is |
| 54 | currently not used. |
Simon Glass | 9665f19 | 2018-10-01 12:22:16 -0600 | [diff] [blame] | 55 | |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 56 | If you want to build your own dtc, it is kept here:: |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 57 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 58 | git://git.kernel.org/pub/scm/utils/dtc/dtc.git |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 59 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 60 | You can decode a binary file with:: |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 61 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 62 | dtc -I dtb -O dts <filename.dtb> |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 63 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 64 | That repo also includes `fdtget`/`fdtput` for reading and writing properties in |
| 65 | a binary file. U-Boot adds its own `fdtgrep` for creating subsets of the file. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 66 | |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 67 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 68 | Where do I get a devicetree file for my board? |
| 69 | ---------------------------------------------- |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 70 | |
| 71 | You may find that the Linux kernel has a suitable file. Look in the |
| 72 | kernel source in arch/<arch>/boot/dts. |
| 73 | |
| 74 | If not you might find other boards with suitable files that you can |
| 75 | modify to your needs. Look in the board directories for files with a |
| 76 | .dts extension. |
| 77 | |
| 78 | Failing that, you could write one from scratch yourself! |
| 79 | |
| 80 | |
| 81 | Configuration |
| 82 | ------------- |
| 83 | |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 84 | Use:: |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 85 | |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 86 | #define CONFIG_DEFAULT_DEVICE_TREE "<name>" |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 87 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 88 | to set the filename of the devicetree source. Then put your devicetree |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 89 | file into:: |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 90 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 91 | arch/<arch>/dts/<name>.dts |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 92 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 93 | This should include your CPU or SOC's devicetree file, placed in |
| 94 | `arch/<arch>/dts`, and then make any adjustments required using a u-boot-dtsi |
| 95 | file for your board. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 96 | |
| 97 | If CONFIG_OF_EMBED is defined, then it will be picked up and built into |
Simon Glass | 67bce6b | 2014-06-02 22:04:50 -0600 | [diff] [blame] | 98 | the U-Boot image (including u-boot.bin). This is suitable for debugging |
| 99 | and development only and is not recommended for production devices. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 100 | |
| 101 | If CONFIG_OF_SEPARATE is defined, then it will be built and placed in |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 102 | a u-boot.dtb file alongside u-boot-nodtb.bin with the combined result placed |
Baruch Siach | 6b0fcc0 | 2023-05-02 13:21:46 +0300 | [diff] [blame] | 103 | in u-boot.bin so you can still just flash u-boot.bin onto your board. If you are |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 104 | using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device |
Simon Glass | 67bce6b | 2014-06-02 22:04:50 -0600 | [diff] [blame] | 105 | tree binary. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 106 | |
Alex Deymo | 5b661ec | 2017-04-02 01:25:20 -0700 | [diff] [blame] | 107 | If CONFIG_OF_BOARD is defined, a board-specific routine will provide the |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 108 | devicetree at runtime, for example if an earlier bootloader stage creates |
Alex Deymo | 5b661ec | 2017-04-02 01:25:20 -0700 | [diff] [blame] | 109 | it and passes it to U-Boot. |
| 110 | |
Ilias Apalodimas | ab5348a | 2021-10-26 09:12:33 +0300 | [diff] [blame] | 111 | If CONFIG_SANDBOX is defined, then it will be read from a file on |
| 112 | startup. Use the -d flag to U-Boot to specify the file to read, -D for the |
| 113 | default and -T for the test devicetree, used to run sandbox unit tests. |
Simon Glass | 1539343 | 2013-04-20 08:42:41 +0000 | [diff] [blame] | 114 | |
| 115 | You cannot use more than one of these options at the same time. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 116 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 117 | To use a devicetree file that you have compiled yourself, pass |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 118 | EXT_DTB=<filename> to 'make', as in:: |
Simon Glass | 67bce6b | 2014-06-02 22:04:50 -0600 | [diff] [blame] | 119 | |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 120 | make EXT_DTB=boot/am335x-boneblack-pubkey.dtb |
Simon Glass | 67bce6b | 2014-06-02 22:04:50 -0600 | [diff] [blame] | 121 | |
| 122 | Then U-Boot will copy that file to u-boot.dtb, put it in the .img file |
| 123 | if used, and u-boot-dtb.bin. |
| 124 | |
Simon Glass | dc6fa64 | 2011-10-24 19:15:34 +0000 | [diff] [blame] | 125 | If you wish to put the fdt at a different address in memory, you can |
| 126 | define the "fdtcontroladdr" environment variable. This is the hex |
| 127 | address of the fdt binary blob, and will override either of the options. |
| 128 | Be aware that this environment variable is checked prior to relocation, |
| 129 | when only the compiled-in environment is available. Therefore it is not |
| 130 | possible to define this variable in the saved SPI/NAND flash |
Thomas Chou | 4fda281 | 2015-10-16 08:44:51 +0800 | [diff] [blame] | 131 | environment, for example (it will be ignored). After relocation, this |
| 132 | variable will be set to the address of the newly relocated fdt blob. |
| 133 | It is read-only and cannot be changed. It can optionally be used to |
| 134 | control the boot process of Linux with bootm/bootz commands. |
Simon Glass | dc6fa64 | 2011-10-24 19:15:34 +0000 | [diff] [blame] | 135 | |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 136 | To use this, put something like this in your board header file:: |
Simon Glass | dc6fa64 | 2011-10-24 19:15:34 +0000 | [diff] [blame] | 137 | |
Tom Rini | c9edebe | 2022-12-04 10:03:50 -0500 | [diff] [blame] | 138 | #define CFG_EXTRA_ENV_SETTINGS "fdtcontroladdr=10000\0" |
Simon Glass | dc6fa64 | 2011-10-24 19:15:34 +0000 | [diff] [blame] | 139 | |
Jagannadha Sutradharudu Teki | 79e63a4 | 2013-02-28 10:20:18 +0000 | [diff] [blame] | 140 | Build: |
| 141 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 142 | After the board configuration is done, fdt supported u-boot can be built in two |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 143 | ways: |
| 144 | |
| 145 | # build the default dts which is defined from CONFIG_DEFAULT_DEVICE_TREE:: |
| 146 | |
Jagannadha Sutradharudu Teki | 79e63a4 | 2013-02-28 10:20:18 +0000 | [diff] [blame] | 147 | $ make |
Simon Glass | ac35c2f | 2021-08-01 18:57:10 -0600 | [diff] [blame] | 148 | |
| 149 | # build the user specified dts file:: |
| 150 | |
Jagannadha Sutradharudu Teki | 79e63a4 | 2013-02-28 10:20:18 +0000 | [diff] [blame] | 151 | $ make DEVICE_TREE=<dts-file-name> |
| 152 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 153 | |
Simon Glass | c5f9e16 | 2021-08-01 18:57:12 -0600 | [diff] [blame] | 154 | .. _dttweaks: |
| 155 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 156 | Adding tweaks for U-Boot |
| 157 | ------------------------ |
| 158 | |
| 159 | It is strongly recommended that devicetree files in U-Boot are an exact copy of |
| 160 | those in Linux, so that it is easy to sync them up from time to time. |
| 161 | |
| 162 | U-Boot is of course a very different project from Linux, e.g. it operates under |
| 163 | much more restrictive memory and code-size constraints. Where Linux may use a |
| 164 | full clock driver with Common Clock Format (CCF) to find the input clock to the |
| 165 | UART, U-Boot typically wants to output a banner as early as possible before too |
| 166 | much code has run. |
| 167 | |
| 168 | A second difference is that U-Boot includes different phases. For SPL, |
| 169 | constraints are even more extreme and the devicetree is shrunk to remove |
| 170 | unwanted nodes, or even turned into C code to avoid access overhead. |
| 171 | |
| 172 | U-Boot automatically looks for and includes a file with updates to the standard |
| 173 | devicetree for your board, searching for them in the same directory as the |
| 174 | main file, in this order:: |
| 175 | |
| 176 | <orig_filename>-u-boot.dtsi |
| 177 | <CONFIG_SYS_SOC>-u-boot.dtsi |
| 178 | <CONFIG_SYS_CPU>-u-boot.dtsi |
| 179 | <CONFIG_SYS_VENDOR>-u-boot.dtsi |
| 180 | u-boot.dtsi |
| 181 | |
| 182 | Only one of these is selected but of course you can #include another one within |
| 183 | that file, to create a hierarchy of shared files. |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 184 | |
Rasmus Villemoes | 303d98d | 2021-11-21 14:52:51 +0100 | [diff] [blame] | 185 | |
| 186 | External .dtsi fragments |
| 187 | ------------------------ |
| 188 | |
| 189 | Apart from describing the hardware present, U-Boot also uses its |
| 190 | control dtb for various configuration purposes. For example, the |
| 191 | public key(s) used for Verified Boot are embedded in a specific format |
| 192 | in a /signature node. |
| 193 | |
| 194 | As mentioned above, the U-Boot build system automatically includes a |
| 195 | `*-u-boot.dtsi` file, if found, containing U-Boot specific |
| 196 | quirks. However, some data, such as the mentioned public keys, are not |
| 197 | appropriate for upstream U-Boot but are better kept and maintained |
| 198 | outside the U-Boot repository. You can use CONFIG_DEVICE_TREE_INCLUDES |
| 199 | to specify a list of .dtsi files that will also be included when |
| 200 | building .dtb files. |
| 201 | |
| 202 | |
Simon Glass | a31dc3d | 2018-10-01 12:22:17 -0600 | [diff] [blame] | 203 | Relocation, SPL and TPL |
| 204 | ----------------------- |
| 205 | |
| 206 | U-Boot can be divided into three phases: TPL, SPL and U-Boot proper. |
| 207 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 208 | The full devicetree is available to U-Boot proper, but normally only a subset |
Simon Glass | a31dc3d | 2018-10-01 12:22:17 -0600 | [diff] [blame] | 209 | (or none at all) is available to TPL and SPL. See 'Pre-Relocation Support' and |
Heinrich Schuchardt | c79f03c | 2020-02-25 21:35:39 +0100 | [diff] [blame] | 210 | 'SPL Support' in doc/driver-model/design.rst for more details. |
Simon Glass | a31dc3d | 2018-10-01 12:22:17 -0600 | [diff] [blame] | 211 | |
| 212 | |
Jean-Jacques Hiblot | 7c530e3 | 2018-12-07 14:50:52 +0100 | [diff] [blame] | 213 | Using several DTBs in the SPL (CONFIG_SPL_MULTI_DTB) |
| 214 | ---------------------------------------------------- |
| 215 | In some rare cases it is desirable to let SPL be able to select one DTB among |
| 216 | many. This usually not very useful as the DTB for the SPL is small and usually |
| 217 | fits several platforms. However the DTB sometimes include information that do |
| 218 | work on several platforms (like IO tuning parameters). |
| 219 | In this case it is possible to use CONFIG_SPL_MULTI_DTB. This option appends to |
| 220 | the SPL a FIT image containing several DTBs listed in SPL_OF_LIST. |
| 221 | board_fit_config_name_match() is called to select the right DTB. |
| 222 | |
| 223 | If board_fit_config_name_match() relies on DM (DM driver to access an EEPROM |
| 224 | containing the board ID for example), it possible to start with a generic DTB |
| 225 | and then switch over to the right DTB after the detection. For this purpose, |
| 226 | the platform code must call fdtdec_resetup(). Based on the returned flag, the |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 227 | platform may have to re-initialise the DM subsystem using dm_uninit() and |
Jean-Jacques Hiblot | 7c530e3 | 2018-12-07 14:50:52 +0100 | [diff] [blame] | 228 | dm_init_and_scan(). |
| 229 | |
| 230 | |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 231 | Limitations |
| 232 | ----------- |
| 233 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 234 | Devicetrees can help reduce the complexity of supporting variants of boards |
| 235 | which use the same SOC / CPU. |
| 236 | |
| 237 | However U-Boot is designed to build for a single architecture type and CPU |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 238 | type. So for example it is not possible to build a single ARM binary |
| 239 | which runs on your AT91 and OMAP boards, relying on an fdt to configure |
| 240 | the various features. This is because you must select one of |
| 241 | the CPU families within arch/arm/cpu/arm926ejs (omap or at91) at build |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 242 | time. Similarly U-Boot cannot be built for multiple cpu types or |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 243 | architectures. |
| 244 | |
Simon Glass | 38d6b8d | 2011-10-15 05:48:21 +0000 | [diff] [blame] | 245 | It is important to understand that the fdt only selects options |
| 246 | available in the platform / drivers. It cannot add new drivers (yet). So |
| 247 | you must still have the CONFIG option to enable the driver. For example, |
| 248 | you need to define CONFIG_SYS_NS16550 to bring in the NS16550 driver, |
| 249 | but can use the fdt to specific the UART clock, peripheral address, etc. |
| 250 | In very broad terms, the CONFIG options in general control *what* driver |
| 251 | files are pulled in, and the fdt controls *how* those files work. |
| 252 | |
Simon Glass | b4fbaaf | 2021-08-01 18:57:11 -0600 | [diff] [blame] | 253 | History |
| 254 | ------- |
| 255 | |
| 256 | U-Boot configuration was previous done using CONFIG options in the board |
| 257 | config file. This eventually got out of hand with nearly 10,000 options. |
| 258 | |
| 259 | U-Boot adopted devicetrees around the same time as Linux and early boards |
| 260 | used it before Linux (e.g. snow). The two projects developed in parallel |
| 261 | and there are still some differences in the bindings for certain boards. |
| 262 | While there has been discussion of having a separate repository for devicetree |
| 263 | files, in practice the Linux kernel Git repository has become the place where |
| 264 | these are stored, with U-Boot taking copies and adding tweaks with u-boot.dtsi |
| 265 | files. |
| 266 | |
| 267 | .. _dtspec: https://www.devicetree.org/specifications/ |
| 268 | .. _dtlist: https://www.spinics.net/lists/devicetree-compiler/ |