blob: 8a8eaed4c11e017381fa53153d3f8706f9fe35e4 [file] [log] [blame]
Bin Mengae258692019-07-18 00:33:55 -07001.. SPDX-License-Identifier: GPL-2.0+
Simon Glass261ad282016-07-04 11:58:07 -06002
Bin Mengae258692019-07-18 00:33:55 -07003Compiled-in Device Tree / Platform Data
4=======================================
5
Simon Glass261ad282016-07-04 11:58:07 -06006
7Introduction
8------------
9
10Device tree is the standard configuration method in U-Boot. It is used to
11define what devices are in the system and provide configuration information
12to these devices.
13
Simon Glass1730e462021-03-15 17:25:42 +130014The overhead of adding devicetree access to U-Boot is fairly modest,
Simon Glass261ad282016-07-04 11:58:07 -060015approximately 3KB on Thumb 2 (plus the size of the DT itself). This means
Simon Glass1730e462021-03-15 17:25:42 +130016that in most cases it is best to use devicetree for configuration.
Simon Glass261ad282016-07-04 11:58:07 -060017
18However there are some very constrained environments where U-Boot needs to
19work. These include SPL with severe memory limitations. For example, some
20SoCs require a 16KB SPL image which must include a full MMC stack. In this
Simon Glass1730e462021-03-15 17:25:42 +130021case the overhead of devicetree access may be too great.
Simon Glass261ad282016-07-04 11:58:07 -060022
23It is possible to create platform data manually by defining C structures
Simon Glass1730e462021-03-15 17:25:42 +130024for it, and reference that data in a `U_BOOT_DRVINFO()` declaration. This
25bypasses the use of devicetree completely, effectively creating a parallel
Simon Glass946c7232016-07-04 11:58:42 -060026configuration mechanism. But it is an available option for SPL.
Simon Glass261ad282016-07-04 11:58:07 -060027
Simon Glass1730e462021-03-15 17:25:42 +130028As an alternative, the 'of-platdata' feature is provided. This converts the
29devicetree contents into C code which can be compiled into the SPL binary.
Simon Glass261ad282016-07-04 11:58:07 -060030This saves the 3KB of code overhead and perhaps a few hundred more bytes due
31to more efficient storage of the data.
32
Simon Glass261ad282016-07-04 11:58:07 -060033
34How it works
35------------
36
Simon Goldschmidt49ce8ca2019-01-16 20:40:18 +010037The feature is enabled by CONFIG OF_PLATDATA. This is only available in
38SPL/TPL and should be tested with:
Simon Glass261ad282016-07-04 11:58:07 -060039
Bin Mengae258692019-07-18 00:33:55 -070040.. code-block:: c
41
42 #if CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass261ad282016-07-04 11:58:07 -060043
Simon Glass1730e462021-03-15 17:25:42 +130044A tool called 'dtoc' converts a devicetree file either into a set of
Simon Goldschmidt49ce8ca2019-01-16 20:40:18 +010045struct declarations, one for each compatible node, and a set of
Simon Glass1730e462021-03-15 17:25:42 +130046`U_BOOT_DRVINFO()` declarations along with the actual platform data for each
Simon Glass261ad282016-07-04 11:58:07 -060047device. As an example, consider this MMC node:
48
Bin Mengae258692019-07-18 00:33:55 -070049.. code-block:: none
50
51 sdmmc: dwmmc@ff0c0000 {
52 compatible = "rockchip,rk3288-dw-mshc";
53 clock-freq-min-max = <400000 150000000>;
54 clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
55 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
56 clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
57 fifo-depth = <0x100>;
58 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
59 reg = <0xff0c0000 0x4000>;
60 bus-width = <4>;
61 cap-mmc-highspeed;
62 cap-sd-highspeed;
63 card-detect-delay = <200>;
64 disable-wp;
65 num-slots = <1>;
66 pinctrl-names = "default";
67 pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
Simon Glass261ad282016-07-04 11:58:07 -060068 vmmc-supply = <&vcc_sd>;
69 status = "okay";
70 u-boot,dm-pre-reloc;
71 };
72
73
74Some of these properties are dropped by U-Boot under control of the
75CONFIG_OF_SPL_REMOVE_PROPS option. The rest are processed. This will produce
76the following C struct declaration:
77
Bin Mengae258692019-07-18 00:33:55 -070078.. code-block:: c
79
80 struct dtd_rockchip_rk3288_dw_mshc {
81 fdt32_t bus_width;
82 bool cap_mmc_highspeed;
83 bool cap_sd_highspeed;
84 fdt32_t card_detect_delay;
85 fdt32_t clock_freq_min_max[2];
86 struct phandle_1_arg clocks[4];
87 bool disable_wp;
88 fdt32_t fifo_depth;
89 fdt32_t interrupts[3];
90 fdt32_t num_slots;
91 fdt32_t reg[2];
92 fdt32_t vmmc_supply;
93 };
Simon Glass261ad282016-07-04 11:58:07 -060094
Simon Glassa7729462020-10-03 11:31:42 -060095and the following device declarations:
Simon Glass261ad282016-07-04 11:58:07 -060096
Bin Mengae258692019-07-18 00:33:55 -070097.. code-block:: c
98
Simon Glassa7729462020-10-03 11:31:42 -060099 /* Node /clock-controller@ff760000 index 0 */
100 ...
101
102 /* Node /dwmmc@ff0c0000 index 2 */
Bin Mengae258692019-07-18 00:33:55 -0700103 static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
104 .fifo_depth = 0x100,
105 .cap_sd_highspeed = true,
106 .interrupts = {0x0, 0x20, 0x4},
107 .clock_freq_min_max = {0x61a80, 0x8f0d180},
108 .vmmc_supply = 0xb,
109 .num_slots = 0x1,
Simon Glassa7729462020-10-03 11:31:42 -0600110 .clocks = {{0, 456},
111 {0, 68},
112 {0, 114},
113 {0, 118}},
Bin Mengae258692019-07-18 00:33:55 -0700114 .cap_mmc_highspeed = true,
115 .disable_wp = true,
116 .bus_width = 0x4,
117 .u_boot_dm_pre_reloc = true,
118 .reg = {0xff0c0000, 0x4000},
119 .card_detect_delay = 0xc8,
120 };
121
Simon Glass1d8364a2020-12-28 20:34:54 -0700122 U_BOOT_DRVINFO(dwmmc_at_ff0c0000) = {
Bin Mengae258692019-07-18 00:33:55 -0700123 .name = "rockchip_rk3288_dw_mshc",
Simon Glass71fa5b42020-12-03 16:55:18 -0700124 .plat = &dtv_dwmmc_at_ff0c0000,
125 .plat_size = sizeof(dtv_dwmmc_at_ff0c0000),
Simon Glassa7729462020-10-03 11:31:42 -0600126 .parent_idx = -1,
Bin Mengae258692019-07-18 00:33:55 -0700127 };
Simon Glass261ad282016-07-04 11:58:07 -0600128
129The device is then instantiated at run-time and the platform data can be
130accessed using:
131
Bin Mengae258692019-07-18 00:33:55 -0700132.. code-block:: c
133
134 struct udevice *dev;
Simon Glassfa20e932020-12-03 16:55:20 -0700135 struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_plat(dev);
Simon Glass261ad282016-07-04 11:58:07 -0600136
Simon Glass1730e462021-03-15 17:25:42 +1300137This avoids the code overhead of converting the devicetree data to
138platform data in the driver. The `of_to_plat()` method should
Simon Glass261ad282016-07-04 11:58:07 -0600139therefore do nothing in such a driver.
140
Simon Goldschmidt49ce8ca2019-01-16 20:40:18 +0100141Note that for the platform data to be matched with a driver, the 'name'
Simon Glass1730e462021-03-15 17:25:42 +1300142property of the `U_BOOT_DRVINFO()` declaration has to match a driver declared
143via `U_BOOT_DRIVER()`. This effectively means that a `U_BOOT_DRIVER()` with a
Simon Goldschmidt49ce8ca2019-01-16 20:40:18 +0100144'name' corresponding to the devicetree 'compatible' string (after converting
145it to a valid name for C) is needed, so a dedicated driver is required for
146each 'compatible' string.
147
Simon Glass1730e462021-03-15 17:25:42 +1300148In order to make this a bit more flexible, the `DM_DRIVER_ALIAS()` macro can be
Walter Lozanoc38b4912020-06-25 01:10:09 -0300149used to declare an alias for a driver name, typically a 'compatible' string.
Simon Glass1730e462021-03-15 17:25:42 +1300150This macro produces no code, but is used by dtoc tool. It must be located in the
Simon Glass2f4455f2021-02-03 06:01:05 -0700151same file as its associated driver, ideally just after it.
Walter Lozanoc38b4912020-06-25 01:10:09 -0300152
Simon Glass1730e462021-03-15 17:25:42 +1300153The parent_idx is the index of the parent `driver_info` structure within its
154linker list (instantiated by the `U_BOOT_DRVINFO()` macro). This is used to
155support `dev_get_parent()`.
Simon Glassa7729462020-10-03 11:31:42 -0600156
Simon Glass1730e462021-03-15 17:25:42 +1300157During the build process dtoc parses both `U_BOOT_DRIVER()` and
158`DM_DRIVER_ALIAS()` to build a list of valid driver names and driver aliases.
159If the 'compatible' string used for a device does not not match a valid driver
160name, it will be checked against the list of driver aliases in order to get the
161right driver name to use. If in this step there is no match found a warning is
162issued to avoid run-time failures.
Walter Lozanoc38b4912020-06-25 01:10:09 -0300163
Simon Glass1730e462021-03-15 17:25:42 +1300164Where a node has multiple compatible strings, dtoc generates a `#define` to
165make them equivalent, e.g.:
Simon Glass934be0b2017-06-13 21:10:06 -0600166
Bin Mengae258692019-07-18 00:33:55 -0700167.. code-block:: c
Simon Glass934be0b2017-06-13 21:10:06 -0600168
Bin Mengae258692019-07-18 00:33:55 -0700169 #define dtd_rockchip_rk3299_dw_mshc dtd_rockchip_rk3288_dw_mshc
170
Simon Glass946c7232016-07-04 11:58:42 -0600171
172Converting of-platdata to a useful form
173---------------------------------------
174
Simon Goldschmidt49ce8ca2019-01-16 20:40:18 +0100175Of course it would be possible to use the of-platdata directly in your driver
176whenever configuration information is required. However this means that the
Simon Glass1730e462021-03-15 17:25:42 +1300177driver will not be able to support devicetree, since the of-platdata
178structure is not available when devicetree is used. It would make no sense
179to use this structure if devicetree were available, since the structure has
180all the limitations metioned in caveats below.
Simon Glass946c7232016-07-04 11:58:42 -0600181
182Therefore it is recommended that the of-platdata structure should be used
Simon Glass1730e462021-03-15 17:25:42 +1300183only in the `probe()` method of your driver. It cannot be used in the
184`of_to_plat()` method since this is not called when platform data is
Simon Glass946c7232016-07-04 11:58:42 -0600185already present.
186
Simon Glass261ad282016-07-04 11:58:07 -0600187
188How to structure your driver
189----------------------------
190
Simon Glass1730e462021-03-15 17:25:42 +1300191Drivers should always support devicetree as an option. The of-platdata
Simon Glass261ad282016-07-04 11:58:07 -0600192feature is intended as a add-on to existing drivers.
193
Simon Glass1730e462021-03-15 17:25:42 +1300194Your driver should convert the plat struct in its `probe()` method. The
195existing devicetree decoding logic should be kept in the
196`of_to_plat()` method and wrapped with `#if`.
Simon Glass261ad282016-07-04 11:58:07 -0600197
198For example:
199
Bin Mengae258692019-07-18 00:33:55 -0700200.. code-block:: c
201
Simon Glass261ad282016-07-04 11:58:07 -0600202 #include <dt-structs.h>
203
Simon Glassb75b15b2020-12-03 16:55:23 -0700204 struct mmc_plat {
Lukasz Majewskifd54ab22019-09-03 15:43:19 +0200205 #if CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass946c7232016-07-04 11:58:42 -0600206 /* Put this first since driver model will copy the data here */
Simon Glass261ad282016-07-04 11:58:07 -0600207 struct dtd_mmc dtplat;
208 #endif
209 /*
210 * Other fields can go here, to be filled in by decoding from
Simon Glass1730e462021-03-15 17:25:42 +1300211 * the devicetree (or the C structures when of-platdata is used).
Simon Glass261ad282016-07-04 11:58:07 -0600212 */
213 int fifo_depth;
214 };
215
Simon Glassaad29ae2020-12-03 16:55:21 -0700216 static int mmc_of_to_plat(struct udevice *dev)
Simon Glass261ad282016-07-04 11:58:07 -0600217 {
Lukasz Majewskifd54ab22019-09-03 15:43:19 +0200218 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass1730e462021-03-15 17:25:42 +1300219 /* Decode the devicetree data */
Simon Glassb75b15b2020-12-03 16:55:23 -0700220 struct mmc_plat *plat = dev_get_plat(dev);
Simon Glass261ad282016-07-04 11:58:07 -0600221 const void *blob = gd->fdt_blob;
Simon Glassdd79d6e2017-01-17 16:52:55 -0700222 int node = dev_of_offset(dev);
Simon Glass261ad282016-07-04 11:58:07 -0600223
224 plat->fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0);
225 #endif
226
227 return 0;
228 }
229
230 static int mmc_probe(struct udevice *dev)
231 {
Simon Glassb75b15b2020-12-03 16:55:23 -0700232 struct mmc_plat *plat = dev_get_plat(dev);
Simon Glass946c7232016-07-04 11:58:42 -0600233
Lukasz Majewskifd54ab22019-09-03 15:43:19 +0200234 #if CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass946c7232016-07-04 11:58:42 -0600235 /* Decode the of-platdata from the C structures */
Simon Glass261ad282016-07-04 11:58:07 -0600236 struct dtd_mmc *dtplat = &plat->dtplat;
237
Simon Glass946c7232016-07-04 11:58:42 -0600238 plat->fifo_depth = dtplat->fifo_depth;
239 #endif
Simon Glass261ad282016-07-04 11:58:07 -0600240 /* Set up the device from the plat data */
241 writel(plat->fifo_depth, ...)
Simon Glass261ad282016-07-04 11:58:07 -0600242 }
243
244 static const struct udevice_id mmc_ids[] = {
245 { .compatible = "vendor,mmc" },
246 { }
247 };
248
249 U_BOOT_DRIVER(mmc_drv) = {
Walter Lozanoc38b4912020-06-25 01:10:09 -0300250 .name = "mmc_drv",
Simon Glass261ad282016-07-04 11:58:07 -0600251 .id = UCLASS_MMC,
252 .of_match = mmc_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700253 .of_to_plat = mmc_of_to_plat,
Simon Glass261ad282016-07-04 11:58:07 -0600254 .probe = mmc_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700255 .priv_auto = sizeof(struct mmc_priv),
Simon Glassb75b15b2020-12-03 16:55:23 -0700256 .plat_auto = sizeof(struct mmc_plat),
Simon Glass261ad282016-07-04 11:58:07 -0600257 };
258
Simon Glassdf65db82020-12-28 20:34:57 -0700259 DM_DRIVER_ALIAS(mmc_drv, vendor_mmc) /* matches compatible string */
Simon Glass261ad282016-07-04 11:58:07 -0600260
Simon Glass1730e462021-03-15 17:25:42 +1300261Note that `struct mmc_plat` is defined in the C file, not in a header. This
Simon Glass63c19ed2019-12-06 21:42:43 -0700262is to avoid needing to include dt-structs.h in a header file. The idea is to
263keep the use of each of-platdata struct to the smallest possible code area.
264There is just one driver C file for each struct, that can convert from the
265of-platdata struct to the standard one used by the driver.
266
Simon Glass1730e462021-03-15 17:25:42 +1300267In the case where SPL_OF_PLATDATA is enabled, `plat_auto` is
Simon Glass946c7232016-07-04 11:58:42 -0600268still used to allocate space for the platform data. This is different from
269the normal behaviour and is triggered by the use of of-platdata (strictly
Simon Glass1730e462021-03-15 17:25:42 +1300270speaking it is a non-zero `plat_size` which triggers this).
Simon Glass261ad282016-07-04 11:58:07 -0600271
Simon Glass946c7232016-07-04 11:58:42 -0600272The of-platdata struct contents is copied from the C structure data to the
Simon Glass1730e462021-03-15 17:25:42 +1300273start of the newly allocated area. In the case where devicetree is used,
Simon Glass946c7232016-07-04 11:58:42 -0600274the platform data is allocated, and starts zeroed. In this case the
Simon Glass1730e462021-03-15 17:25:42 +1300275`of_to_plat()` method should still set up the platform data (and the
Simon Glass946c7232016-07-04 11:58:42 -0600276of-platdata struct will not be present).
277
Simon Glass1730e462021-03-15 17:25:42 +1300278SPL must use either of-platdata or devicetree. Drivers cannot use both at
279the same time, but they must support devicetree. Supporting of-platdata is
Simon Glass946c7232016-07-04 11:58:42 -0600280optional.
Simon Glass261ad282016-07-04 11:58:07 -0600281
Simon Glass1730e462021-03-15 17:25:42 +1300282The devicetree becomes inaccessible when CONFIG_SPL_OF_PLATDATA is enabled,
283since the devicetree access code is not compiled in. A corollary is that
Simon Glass946c7232016-07-04 11:58:42 -0600284a board can only move to using of-platdata if all the drivers it uses support
285it. There would be little point in having some drivers require the device
286tree data, since then libfdt would still be needed for those drivers and
287there would be no code-size benefit.
Simon Glass261ad282016-07-04 11:58:07 -0600288
Simon Glasse2ec0ea2021-03-15 17:25:43 +1300289
290Build-time instantiation
291------------------------
292
293Even with of-platdata there is a fair amount of code required in driver model.
294It is possible to have U-Boot handle the instantiation of devices at build-time,
295so avoiding the need for the `device_bind()` code and some parts of
296`device_probe()`.
297
298The feature is enabled by CONFIG_OF_PLATDATA_INST.
299
300Here is an example device, as generated by dtoc::
301
302 /*
303 * Node /serial index 6
304 * driver sandbox_serial parent root_driver
305 */
306
307 #include <asm/serial.h>
308 struct sandbox_serial_plat __attribute__ ((section (".priv_data")))
309 _sandbox_serial_plat_serial = {
310 .dtplat = {
311 .sandbox_text_colour = "cyan",
312 },
313 };
314 #include <asm/serial.h>
315 u8 _sandbox_serial_priv_serial[sizeof(struct sandbox_serial_priv)]
316 __attribute__ ((section (".priv_data")));
317 #include <serial.h>
318 u8 _sandbox_serial_uc_priv_serial[sizeof(struct serial_dev_priv)]
319 __attribute__ ((section (".priv_data")));
320
321 DM_DEVICE_INST(serial) = {
322 .driver = DM_DRIVER_REF(sandbox_serial),
323 .name = "sandbox_serial",
324 .plat_ = &_sandbox_serial_plat_serial,
325 .priv_ = _sandbox_serial_priv_serial,
326 .uclass = DM_UCLASS_REF(serial),
327 .uclass_priv_ = _sandbox_serial_uc_priv_serial,
328 .uclass_node = {
329 .prev = &DM_UCLASS_REF(serial)->dev_head,
330 .next = &DM_UCLASS_REF(serial)->dev_head,
331 },
332 .child_head = {
333 .prev = &DM_DEVICE_REF(serial)->child_head,
334 .next = &DM_DEVICE_REF(serial)->child_head,
335 },
336 .sibling_node = {
337 .prev = &DM_DEVICE_REF(i2c_at_0)->sibling_node,
338 .next = &DM_DEVICE_REF(spl_test)->sibling_node,
339 },
340 .seq_ = 0,
341 };
342
343Here is part of the driver, for reference::
344
345 static const struct udevice_id sandbox_serial_ids[] = {
346 { .compatible = "sandbox,serial" },
347 { }
348 };
349
350 U_BOOT_DRIVER(sandbox_serial) = {
351 .name = "sandbox_serial",
352 .id = UCLASS_SERIAL,
353 .of_match = sandbox_serial_ids,
354 .of_to_plat = sandbox_serial_of_to_plat,
355 .plat_auto = sizeof(struct sandbox_serial_plat),
356 .priv_auto = sizeof(struct sandbox_serial_priv),
357 .probe = sandbox_serial_probe,
358 .remove = sandbox_serial_remove,
359 .ops = &sandbox_serial_ops,
360 .flags = DM_FLAG_PRE_RELOC,
361 };
362
363
364The `DM_DEVICE_INST()` macro declares a struct udevice so you can see that the
365members are from that struct. The private data is declared immediately above,
366as `_sandbox_serial_priv_serial`, so there is no need for run-time memory
367allocation. The #include lines are generated as well, since dtoc searches the
368U-Boot source code for the definition of `struct sandbox_serial_priv` and adds
369the relevant header so that the code will compile without errors.
370
371The `plat_` member is set to the dtv data which is declared immediately above
372the device. This is similar to how it would look without of-platdata-inst, but
373node that the `dtplat` member inside is part of the wider
374`_sandbox_serial_plat_serial` struct. This is because the driver declares its
375own platform data, and the part generated by dtoc can only be a portion of it.
376The `dtplat` part is always first in the struct. If the device has no
377`.plat_auto` field, then a simple dtv struct can be used as with this example::
378
379 static struct dtd_sandbox_clk dtv_clk_sbox = {
380 .assigned_clock_rates = 0x141,
381 .assigned_clocks = {0x7, 0x3},
382 };
383
384 #include <asm/clk.h>
385 u8 _sandbox_clk_priv_clk_sbox[sizeof(struct sandbox_clk_priv)]
386 __attribute__ ((section (".priv_data")));
387
388 DM_DEVICE_INST(clk_sbox) = {
389 .driver = DM_DRIVER_REF(sandbox_clk),
390 .name = "sandbox_clk",
391 .plat_ = &dtv_clk_sbox,
392
393Here is part of the driver, for reference::
394
395 static const struct udevice_id sandbox_clk_ids[] = {
396 { .compatible = "sandbox,clk" },
397 { }
398 };
399
400 U_BOOT_DRIVER(sandbox_clk) = {
401 .name = "sandbox_clk",
402 .id = UCLASS_CLK,
403 .of_match = sandbox_clk_ids,
404 .ops = &sandbox_clk_ops,
405 .probe = sandbox_clk_probe,
406 .priv_auto = sizeof(struct sandbox_clk_priv),
407 };
408
409
410You can see that `dtv_clk_sbox` just has the devicetree contents and there is
411no need for the `dtplat` separation, since the driver has no platform data of
412its own, besides that provided by the devicetree (i.e. no `.plat_auto` field).
413
414The doubly linked lists are handled by explicitly declaring the value of each
415node, as you can see with the `.prev` and `.next` values in the example above.
416Since dtoc knows the order of devices it can link them into the appropriate
417lists correctly.
418
419One of the features of driver model is the ability for a uclass to have a
420small amount of private data for each device in that uclass. This is used to
421provide a generic data structure that the uclass can use for all devices, thus
422allowing generic features to be implemented in common code. An example is I2C,
423which stores the bus speed there.
424
425Similarly, parent devices can have data associated with each of their children.
426This is used to provide information common to all children of a particular bus.
427For an I2C bus, this is used to store the I2C address of each child on the bus.
428
429This is all handled automatically by dtoc::
430
431 #include <asm/i2c.h>
432 u8 _sandbox_i2c_priv_i2c_at_0[sizeof(struct sandbox_i2c_priv)]
433 __attribute__ ((section (".priv_data")));
434 #include <i2c.h>
435 u8 _sandbox_i2c_uc_priv_i2c_at_0[sizeof(struct dm_i2c_bus)]
436 __attribute__ ((section (".priv_data")));
437
438 DM_DEVICE_INST(i2c_at_0) = {
439 .driver = DM_DRIVER_REF(sandbox_i2c),
440 .name = "sandbox_i2c",
441 .plat_ = &dtv_i2c_at_0,
442 .priv_ = _sandbox_i2c_priv_i2c_at_0,
443 .uclass = DM_UCLASS_REF(i2c),
444 .uclass_priv_ = _sandbox_i2c_uc_priv_i2c_at_0,
445 ...
446
447Part of driver, for reference::
448
449 static const struct udevice_id sandbox_i2c_ids[] = {
450 { .compatible = "sandbox,i2c" },
451 { }
452 };
453
454 U_BOOT_DRIVER(sandbox_i2c) = {
455 .name = "sandbox_i2c",
456 .id = UCLASS_I2C,
457 .of_match = sandbox_i2c_ids,
458 .ops = &sandbox_i2c_ops,
459 .priv_auto = sizeof(struct sandbox_i2c_priv),
460 };
461
462Part of I2C uclass, for reference::
463
464 UCLASS_DRIVER(i2c) = {
465 .id = UCLASS_I2C,
466 .name = "i2c",
467 .flags = DM_UC_FLAG_SEQ_ALIAS,
468 .post_bind = i2c_post_bind,
469 .pre_probe = i2c_pre_probe,
470 .post_probe = i2c_post_probe,
471 .per_device_auto = sizeof(struct dm_i2c_bus),
472 .per_child_plat_auto = sizeof(struct dm_i2c_chip),
473 .child_post_bind = i2c_child_post_bind,
474 };
475
476Here, `_sandbox_i2c_uc_priv_i2c_at_0` is required by the uclass but is declared
477in the device, as required by driver model. The required header file is included
478so that the code will compile without errors. A similar mechanism is used for
479child devices, but is not shown by this example.
480
481It would not be that useful to avoid binding devices but still need to allocate
482uclasses at runtime. So dtoc generates uclass instances as well::
483
484 struct list_head uclass_head = {
485 .prev = &DM_UCLASS_REF(serial)->sibling_node,
486 .next = &DM_UCLASS_REF(clk)->sibling_node,
487 };
488
489 DM_UCLASS_INST(clk) = {
490 .uc_drv = DM_UCLASS_DRIVER_REF(clk),
491 .sibling_node = {
492 .prev = &uclass_head,
493 .next = &DM_UCLASS_REF(i2c)->sibling_node,
494 },
495 .dev_head = {
496 .prev = &DM_DEVICE_REF(clk_sbox)->uclass_node,
497 .next = &DM_DEVICE_REF(clk_fixed)->uclass_node,
498 },
499 };
500
501At the top is the list head. Driver model uses this on start-up, instead of
502creating its own.
503
504Below that are a set of `DM_UCLASS_INST()` macros, each declaring a
505`struct uclass`. The doubly linked lists work as for devices.
506
507All private data is placed into a `.priv_data` section so that it is contiguous
508in the resulting output binary.
509
510
511Indexes
512-------
513
514U-Boot stores drivers, devices and many other things in linker_list structures.
515These are sorted by name, so dtoc knows the order that they will appear when
516the linker runs. Each driver_info / udevice is referenced by its index in the
517linker_list array, called 'idx' in the code.
518
519When CONFIG_OF_PLATDATA_INST is enabled, idx is the udevice index, otherwise it
520is the driver_info index. In either case, indexes are used to reference devices
521using device_get_by_ofplat_idx(). This allows phandles to work as expected.
522
523
524Phases
525------
526
527U-Boot operates in several phases, typically TPL, SPL and U-Boot proper.
528The latter does not use dtoc.
529
530In some rare cases different drivers are used for two phases. For example,
531in TPL it may not be necessary to use the full PCI subsystem, so a simple
532driver can be used instead.
533
534This works in the build system simply by compiling in one driver or the
535other (e.g. PCI driver + uclass for SPL; simple_bus for TPL). But dtoc has
536no way of knowing which code is compiled in for which phase, since it does
537not inspect Makefiles or dependency graphs.
538
539So to make this work for dtoc, we need to be able to explicitly mark
540drivers with their phase. This is done by adding a macro to the driver::
541
542 /* code in tpl.c only compiled into TPL */
543 U_BOOT_DRIVER(pci_x86) = {
544 .name = "pci_x86",
545 .id = UCLASS_SIMPLE_BUS,
546 .of_match = of_match_ptr(tpl_fake_pci_ids),
547 DM_PHASE(tpl)
548 };
549
550
551 /* code in pci_x86.c compiled into SPL and U-Boot proper */
552 U_BOOT_DRIVER(pci_x86) = {
553 .name = "pci_x86",
554 .id = UCLASS_PCI,
555 .of_match = pci_x86_ids,
556 .ops = &pci_x86_ops,
557 };
558
559
560Notice that the second driver has the same name but no DM_PHASE(), so it will be
561used for SPL and U-Boot.
562
563Note also that this only affects the code generated by dtoc. You still need to
564make sure that only the required driver is build into each phase.
565
566
567Header files
568------------
569
570With OF_PLATDATA_INST, dtoc must include the correct header file in the
571generated code for any structs that are used, so that the code will compile.
572For example, if `struct ns16550_plat` is used, the code must include the
573`ns16550.h` header file.
574
575Typically dtoc can detect the header file needed for a driver by looking
576for the structs that it uses. For example, if a driver as a `.priv_auto`
577that uses `struct ns16550_plat`, then dtoc can search header files for the
578definition of that struct and use the file.
579
580In some cases, enums are used in drivers, typically with the `.data` field
581of `struct udevice_id`. Since dtoc does not support searching for these,
582you must use the `DM_HDR()` macro to tell dtoc which header to use. This works
583as a macro included in the driver definition::
584
585 static const struct udevice_id apl_syscon_ids[] = {
586 { .compatible = "intel,apl-punit", .data = X86_SYSCON_PUNIT },
587 { }
588 };
589
590 U_BOOT_DRIVER(intel_apl_punit) = {
591 .name = "intel_apl_punit",
592 .id = UCLASS_SYSCON,
593 .of_match = apl_syscon_ids,
594 .probe = apl_punit_probe,
595 DM_HEADER(<asm/cpu.h>) /* for X86_SYSCON_PUNIT */
596 };
597
598
599
Simon Glassee3837c2021-07-04 12:19:50 -0600600Problems
601--------
602
603In some cases you will you see something like this::
604
605 WARNING: the driver rockchip_rk3188_grf was not found in the driver list
606
607The driver list is a list of drivers, each with a name. The name is in the
608U_BOOT_DRIVER() declaration, repeated twice, one in brackets and once as the
609.name member. For example, in the following declaration the driver name is
610`rockchip_rk3188_grf`::
611
612 U_BOOT_DRIVER(rockchip_rk3188_grf) = {
613 .name = "rockchip_rk3188_grf",
614 .id = UCLASS_SYSCON,
615 .of_match = rk3188_syscon_ids + 1,
616 .bind = rk3188_syscon_bind_of_plat,
617 };
618
619The first name U_BOOT_DRIVER(xx) is used to create a linker symbol so that the
620driver can be accessed at build-time without any overhead. The second one
621(.name = "xx") is used at runtime when something wants to print out the driver
622name.
623
624The dtoc tool expects to be able to find a driver for each compatible string in
625the devicetree. For example, if the devicetree has::
626
627 grf: grf@20008000 {
628 compatible = "rockchip,rk3188-grf", "syscon";
629 reg = <0x20008000 0x200>;
630 u-boot,dm-spl;
631 };
632
633then dtoc looks at the first compatible string ("rockchip,rk3188-grf"),
634converts that to a C identifier (rockchip_rk3188_grf) and then looks for that.
635
636Various things can cause dtoc to fail to find the driver and it tries to
637warn about these. For example:
638
639 rockchip_rk3188_uart: Missing .compatible in drivers/serial/serial_rockchip.c
640 : WARNING: the driver rockchip_rk3188_uart was not found in the driver list
641
642Without a compatible string a driver cannot be used by dtoc, even if the
643compatible string is not actually needed at runtime.
644
645If the problem is simply that there are multiple compatible strings, the
646DM_DRIVER_ALIAS() macro can be used to tell dtoc about this and avoid a problem.
647
648Checks are also made to confirm that the referenced driver has a .compatible
649member and a .id member. The first provides the array of compatible strings and
650the second provides the uclass ID.
651
652
Simon Glasse2ec0ea2021-03-15 17:25:43 +1300653Caveats
654-------
655
656There are various complications with this feature which mean it should only
657be used when strictly necessary, i.e. in SPL with limited memory. Notable
658caveats include:
659
660 - Device tree does not describe data types. But the C code must define a
661 type for each property. These are guessed using heuristics which
662 are wrong in several fairly common cases. For example an 8-byte value
663 is considered to be a 2-item integer array, and is byte-swapped. A
664 boolean value that is not present means 'false', but cannot be
665 included in the structures since there is generally no mention of it
666 in the devicetree file.
667
668 - Naming of nodes and properties is automatic. This means that they follow
669 the naming in the devicetree, which may result in C identifiers that
670 look a bit strange.
671
672 - It is not possible to find a value given a property name. Code must use
673 the associated C member variable directly in the code. This makes
674 the code less robust in the face of devicetree changes. To avoid having
675 a second struct with similar members and names you need to explicitly
676 declare it as an alias with `DM_DRIVER_ALIAS()`.
677
678 - The platform data is provided to drivers as a C structure. The driver
679 must use the same structure to access the data. Since a driver
680 normally also supports devicetree it must use `#ifdef` to separate
681 out this code, since the structures are only available in SPL. This could
682 be fixed fairly easily by making the structs available outside SPL, so
683 that `IS_ENABLED()` could be used.
684
685 - With CONFIG_OF_PLATDATA_INST all binding happens at build-time, meaning
686 that (by default) it is not possible to call `device_bind()` from C code.
687 This means that all devices must have an associated devicetree node and
688 compatible string. For example if a GPIO device currently creates child
689 devices in its `bind()` method, it will not work with
690 CONFIG_OF_PLATDATA_INST. Arguably this is bad practice anyway and the
691 devicetree binding should be updated to declare compatible strings for
692 the child devices. It is possible to disable OF_PLATDATA_NO_BIND but this
693 is not recommended since it increases code size.
694
695
Simon Glass261ad282016-07-04 11:58:07 -0600696Internals
697---------
698
Simon Glasse2ec0ea2021-03-15 17:25:43 +1300699Generated files
700```````````````
701
702When enabled, dtoc generates the following five files:
703
704include/generated/dt-decl.h (OF_PLATDATA_INST only)
705 Contains declarations for all drivers, devices and uclasses. This allows
706 any `struct udevice`, `struct driver` or `struct uclass` to be located by its
707 name
708
709include/generated/dt-structs-gen.h
710 Contains the struct definitions for the devicetree nodes that are used. This
711 is the same as without OF_PLATDATA_INST
712
713spl/dts/dt-plat.c (only with !OF_PLATDATA_INST)
714 Contains the `U_BOOT_DRVINFO()` declarations that U-Boot uses to bind devices
715 at start-up. See above for an example
716
717spl/dts/dt-device.c (only with OF_PLATDATA_INST)
718 Contains `DM_DEVICE_INST()` declarations for each device that can be used at
719 run-time. These are declared in the file along with any private/platform data
720 that they use. Every device has an idx, as above. Since each device must be
721 part of a double-linked list, the nodes are declared in the code as well.
722
723spl/dts/dt-uclass.c (only with OF_PLATDATA_INST)
724 Contains `DM_UCLASS_INST()` declarations for each uclass that can be used at
725 run-time. These are declared in the file along with any private data
726 associated with the uclass itself (the `.priv_auto` member). Since each
727 uclass must be part of a double-linked list, the nodes are declared in the
728 code as well.
729
Simon Glass261ad282016-07-04 11:58:07 -0600730The dt-structs.h file includes the generated file
Simon Glass1730e462021-03-15 17:25:42 +1300731`(include/generated/dt-structs.h`) if CONFIG_SPL_OF_PLATDATA is enabled.
Simon Glass261ad282016-07-04 11:58:07 -0600732Otherwise (such as in U-Boot proper) these structs are not available. This
Simon Glass946c7232016-07-04 11:58:42 -0600733prevents them being used inadvertently. All usage must be bracketed with
Simon Glass1730e462021-03-15 17:25:42 +1300734`#if CONFIG_IS_ENABLED(OF_PLATDATA)`.
Simon Glass261ad282016-07-04 11:58:07 -0600735
Simon Glass71fa5b42020-12-03 16:55:18 -0700736The dt-plat.c file contains the device declarations and is is built in
Simon Glass2500de22020-12-28 20:35:05 -0700737spl/dt-plat.c.
738
Simon Glasse2ec0ea2021-03-15 17:25:43 +1300739
740CONFIG options
741``````````````
742
743Several CONFIG options are used to control the behaviour of of-platdata, all
744available for both SPL and TPL:
745
746OF_PLATDATA
747 This is the main option which enables the of-platdata feature
748
749OF_PLATDATA_PARENT
750 This allows `device_get_parent()` to work. Without this, all devices exist as
751 direct children of the root node. This option is highly desirable (if not
752 always absolutely essential) for buses such as I2C.
753
754OF_PLATDATA_INST
755 This controls the instantiation of devices at build time. With it disabled,
756 only `U_BOOT_DRVINFO()` records are created, with U-Boot handling the binding
757 in `device_bind()` on start-up. With it enabled, only `DM_DEVICE_INST()` and
758 `DM_UCLASS_INST()` records are created, and `device_bind()` is not needed at
759 runtime.
760
761OF_PLATDATA_NO_BIND
762 This controls whether `device_bind()` is supported. It is enabled by default
763 with OF_PLATDATA_INST since code-size reduction is really the main point of
764 the feature. It can be disabled if needed but is not likely to be supported
765 in the long term.
766
767OF_PLATDATA_DRIVER_RT
768 This controls whether the `struct driver_rt` records are used by U-Boot.
769 Normally when a device is bound, U-Boot stores the device pointer in one of
770 these records. There is one for every `struct driver_info` in the system,
771 i.e. one for every device that is bound from those records. It provides a
772 way to locate a device in the code and is used by
773 `device_get_by_ofplat_idx()`. This option is always enabled with of-platdata,
774 provided OF_PLATDATA_INST is not. In that case the records are useless since
775 we don't have any `struct driver_info` records.
776
777OF_PLATDATA_RT
778 This controls whether the `struct udevice_rt` records are used by U-Boot.
779 It moves the updatable fields from `struct udevice` (currently only `flags`)
780 into a separate structure, allowing the records to be kept in read-only
781 memory. It is generally enabled if OF_PLATDATA_INST is enabled. This option
782 also controls whether the private data is used in situ, or first copied into
783 an allocated region. Again this is to allow the private data declared by
784 dtoc-generated code to be in read-only memory. Note that access to private
785 data must be done via accessor functions, such as `dev_get_priv()`, so that
786 the relocation is handled.
787
788READ_ONLY
789 This indicates that the data generated by dtoc should not be modified. Only
790 a few fields actually do get changed in U-Boot, such as device flags. This
791 option causes those to move into an allocated space (see OF_PLATDATA_RT).
792 Also, since updating doubly linked lists is generally impossible when some of
793 the nodes cannot be updated, OF_PLATDATA_NO_BIND is enabled.
794
795Data structures
796```````````````
797
798A few extra data structures are used with of-platdata:
799
800`struct udevice_rt`
801 Run-time information for devices. When OF_PLATDATA_RT is enabled, this holds
802 the flags for each device, so that `struct udevice` can remain unchanged by
803 U-Boot, and potentially reside in read-only memory. Access to flags is then
804 via functions like `dev_get_flags()` and `dev_or_flags()`. This data
805 structure is allocated on start-up, where the private data is also copied.
806 All flags values start at 0 and any changes are handled by `dev_or_flags()`
807 and `dev_bic_flags()`. It would be more correct for the flags to be set to
808 `DM_FLAG_BOUND`, or perhaps `DM_FLAG_BOUND | DM_FLAG_ALLOC_PDATA`, but since
809 there is no code to bind/unbind devices and no code to allocate/free
810 private data / platform data, it doesn't matter.
811
812`struct driver_rt`
813 Run-time information for `struct driver_info` records. When
814 OF_PLATDATA_DRIVER_RT is enabled, this holds a pointer to the device
815 created by each record. This is needed so that is it possible to locate a
816 device from C code. Specifically, the code can use `DM_DRVINFO_GET(name)` to
817 get a reference to a particular `struct driver_info`, with `name` being the
818 name of the devicetree node. This is very convenient. It is also fast, since
819 no searching or string comparison is needed. This data structure is
820 allocated on start-up, filled out by `device_bind()` and used by
821 `device_get_by_ofplat_idx()`.
822
823Other changes
824`````````````
825
826Some other changes are made with of-platdata:
827
828Accessor functions
829 Accessing private / platform data via functions such as `dev_get_priv()` has
830 always been encouraged. With OF_PLATDATA_RT this is essential, since the
831 `priv_` and `plat_` (etc.) values point to the data generated by dtoc, not
832 the read-write copy that is sometimes made on start-up. Changing the
833 private / platform data pointers has always been discouraged (the API is
834 marked internal) but with OF_PLATDATA_RT this is not currently supported in
835 general, since it assumes that all such pointers point to the relocated data.
836 Note also that the renaming of struct members to have a trailing underscore
837 was partly done to make people aware that they should not be accessed
838 directly.
839
840`gd->uclass_root_s`
841 Normally U-Boot sets up the head of the uclass list here and makes
842 `gd->uclass_root` point to it. With OF_PLATDATA_INST, dtoc generates a
843 declaration of `uclass_head` in `dt-uclass.c` since it needs to link the
844 head node into the list. In that case, `gd->uclass_root_s` is not used and
845 U-Boot just makes `gd->uclass_root` point to `uclass_head`.
846
847`gd->dm_driver_rt`
848 This holds a pointer to a list of `struct driver_rt` records, one for each
849 `struct driver_info`. The list is in alphabetical order by the name used
850 in `U_BOOT_DRVINFO(name)` and indexed by idx, with the first record having
851 an index of 0. It is only used if OF_PLATDATA_INST is not enabled. This is
852 accessed via macros so that it can be used inside IS_ENABLED(), rather than
853 requiring #ifdefs in the C code when it is not present.
854
855`gd->dm_udevice_rt`
856 This holds a pointer to a list of `struct udevice_rt` records, one for each
857 `struct udevice`. The list is in alphabetical order by the name used
858 in `DM_DEVICE_INST(name)` (a C version of the devicetree node) and indexed by
859 idx, with the first record having an index of 0. It is only used if
860 OF_PLATDATA_INST is enabled. This is accessed via macros so that it can be
861 used inside `IS_ENABLED()`, rather than requiring #ifdefs in the C code when
862 it is not present.
863
864`gd->dm_priv_base`
865 When OF_PLATDATA_RT is enabled, the private/platform data for each device is
866 copied into an allocated region by U-Boot on start-up. This points to that
867 region. All calls to accessor functions (e.g. `dev_get_priv()`) then
868 translate from the pointer provided by the caller (assumed to lie between
869 `__priv_data_start` and `__priv_data_end`) to the new allocated region. This
870 member is accessed via macros so that it can be used inside IS_ENABLED(),
871 rather than required #ifdefs in the C code when it is not present.
872
873`struct udevice->flags_`
874 When OF_PLATDATA_RT is enabled, device flags are no-longer part of
875 `struct udevice`, but are instead kept in `struct udevice_rt`, as described
876 above. Flags are accessed via functions, such as `dev_get_flags()` and
877 `dev_or_flags()`.
878
879`struct udevice->node_`
880 When OF_PLATDATA is enabled, there is no devicetree at runtime, so no need
881 for this field. It is removed, just to save space.
882
883`DM_PHASE`
884 This macro is used to indicate which phase of U-Boot a driver is intended
885 for. See above for details.
886
887`DM_HDR`
888 This macro is used to indicate which header file dtoc should use to allow
889 a driver declaration to compile correctly. See above for details.
890
891`device_get_by_ofplat_idx()`
892 There used to be a function called `device_get_by_driver_info()` which
893 looked up a `struct driver_info` pointer and returned the `struct udevice`
894 that was created from it. It was only available for use with of-platdata.
895 This has been removed in favour of `device_get_by_ofplat_idx()` which uses
896 `idx`, the index of the `struct driver_info` or `struct udevice` in the
897 linker_list. Similarly, the `struct phandle_0_arg` (etc.) structs have been
898 updated to use this index instead of a pointer to `struct driver_info`.
899
900`DM_DRVINFO_GET`
901 This has been removed since we now use indexes to obtain a driver from
902 `struct phandle_0_arg` and the like.
903
904Two-pass binding
905 The original of-platdata tried to order `U_BOOT_DRVINFO()` in the generated
906 files so as to have parents declared ahead of children. This was convenient
907 as it avoided any special code in U-Boot. With OF_PLATDATA_INST this does
908 not work as the idx value relies on using alphabetical order for everything,
909 so that dtoc and U-Boot's linker_lists agree on the idx value. Devices are
910 then bound in order of idx, having no regard to parent/child relationships.
911 For this reason, device binding now hapens in multiple passes, with parents
912 being bound before their children. This is important so that children can
913 find their parents in the bind() method if needed.
914
915Root device
916 The root device is generally bound by U-Boot but with OF_PLATDATA_INST it
917 cannot be, since binding needs to be done at build time. So in this case
918 dtoc sets up a root device using `DM_DEVICE_INST()` in `dt-device.c` and
919 U-Boot makes use of that. When OF_PLATDATA_INST is not enabled, U-Boot
920 generally ignores the root node and does not create a `U_BOOT_DRVINFO()`
921 record for it. This means that the idx numbers used by `struct driver_info`
922 (when OF_PLATDATA_INST is disabled) and the idx numbers used by
923 `struct udevice` (when OF_PLATDATA_INST is enabled) differ, since one has a
924 root node and the other does not. This does not actually matter, since only
925 one of them is actually used for any particular build, but it is worth
926 keeping in mind if comparing index values and switching OF_PLATDATA_INST on
927 and off.
928
929`__priv_data_start` and `__priv_data_end`
930 The private/platform data declared by dtoc is all collected together in
931 a linker section and these symbols mark the start and end of it. This allows
932 U-Boot to relocate the area to a new location if needed (with
933 OF_PLATDATA_RT)
934
935`dm_priv_to_rw()`
936 This function converts a private- or platform-data pointer value generated by
937 dtoc into one that can be used by U-Boot. It is a NOP unless OF_PLATDATA_RT
938 is enabled, in which case it translates the address to the relocated
939 region. See above for more information.
940
Simon Glass2500de22020-12-28 20:35:05 -0700941The dm_populate_phandle_data() function that was previous needed has now been
942removed, since dtoc can address the drivers directly from dt-plat.c and does
943not need to fix up things at runtime.
Simon Glass261ad282016-07-04 11:58:07 -0600944
Simon Glassa7729462020-10-03 11:31:42 -0600945The pylibfdt Python module is used to access the devicetree.
Simon Glass261ad282016-07-04 11:58:07 -0600946
Simon Glass946c7232016-07-04 11:58:42 -0600947
948Credits
949-------
950
951This is an implementation of an idea by Tom Rini <trini@konsulko.com>.
Simon Glass261ad282016-07-04 11:58:07 -0600952
953
954Future work
955-----------
Simon Glass1730e462021-03-15 17:25:42 +1300956- Consider programmatically reading binding files instead of devicetree
Bin Mengae258692019-07-18 00:33:55 -0700957 contents
Simon Glass1730e462021-03-15 17:25:42 +1300958- Allow IS_ENABLED() to be used in the C code instead of #if
Simon Glass261ad282016-07-04 11:58:07 -0600959
Bin Mengae258692019-07-18 00:33:55 -0700960
961.. Simon Glass <sjg@chromium.org>
962.. Google, Inc
963.. 6/6/16
964.. Updated Independence Day 2016
Simon Glassa7729462020-10-03 11:31:42 -0600965.. Updated 1st October 2020
Simon Glass1730e462021-03-15 17:25:42 +1300966.. Updated 5th February 2021