1Pre-relocation device tree manipulation 2======================================= 3 4Contents: 5 61. Purpose 72. Implementation 83. Example 94. Work to be done 10 111. Purpose 12---------- 13 14In certain markets, it is beneficial for manufacturers of embedded devices to 15offer certain ranges of products, where the functionality of the devices within 16one series either don't differ greatly from another, or can be thought of as 17"extensions" of each other, where one device only differs from another in the 18addition of a small number of features (e.g. an additional output connector). 19 20To realize this in hardware, one method is to have a motherboard, and several 21possible daughter boards that can be attached to this mother board. Different 22daughter boards then either offer the slightly different functionality, or the 23addition of the daughter board to the device realizes the "extension" of 24functionality to the device described previously. 25 26For the software, we obviously want to reuse components for all these 27variations of the device. This means that the software somehow needs to cope 28with the situation that certain ICs may or may not be present on any given 29system, depending on which daughter boards are connected to the motherboard. 30 31In the Linux kernel, one possible solution to this problem is to employ the 32device tree overlay mechanism: There exists one "base" device tree, which 33features only the components guaranteed to exist in all varieties of the 34device. At the start of the kernel, the presence and type of the daughter 35boards is then detected, and the corresponding device tree overlays are applied 36to support the components on the daughter boards. 37 38Note that the components present on every variety of the board must, of course, 39provide a way to find out if and which daughter boards are installed for this 40mechanism to work. 41 42In the U-Boot boot loader, support for device tree overlays has recently been 43integrated, and is used on some boards to alter the device tree that is later 44passed to Linux. But since U-Boot's driver model, which is device tree-based as 45well, is being used in more and more drivers, the same problem of altering the 46device tree starts cropping up in U-Boot itself as well. 47 48An additional problem with the device tree in U-Boot is that it is read-only, 49and the current mechanisms don't allow easy manipulation of the device tree 50after the driver model has been initialized. While migrating to a live device 51tree (at least after the relocation) would greatly simplify the solution of 52this problem, it is a non-negligible task to implement it, an a interim 53solution is needed to address the problem at least in the medium-term. 54 55Hence, we propose a solution to this problem by offering a board-specific 56call-back function, which is passed a writeable pointer to the device tree. 57This function is called before the device tree is relocated, and specifically 58before the main U-Boot's driver model is instantiated, hence the main U-Boot 59"sees" all modifications to the device tree made in this function. Furthermore, 60we have the pre-relocation driver model at our disposal at this stage, which 61means that we can query the hardware for the existence and variety of the 62components easily. 63 642. Implementation 65----------------- 66 67To take advantage of the pre-relocation device tree manipulation mechanism, 68boards have to implement the function board_fix_fdt, which has the following 69signature: 70 71int board_fix_fdt (void *rw_fdt_blob) 72 73The passed-in void pointer is a writeable pointer to the device tree, which can 74be used to manipulate the device tree using e.g. functions from 75include/fdt_support.h. The return value should either be 0 in case of 76successful execution of the device tree manipulation or something else for a 77failure. Note that returning a non-null value from the function will 78unrecoverably halt the boot process, as with any function from init_sequence_f 79(in common/board_f.c). 80 81Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function 82to be called: 83 84Device Tree Control 85-> [*] Board-specific manipulation of Device Tree 86 87+----------------------------------------------------------+ 88| WARNING: The actual manipulation of the device tree has | 89| to be the _last_ set of operations in board_fix_fdt! | 90| Since the pre-relocation driver model does not adapt to | 91| changes made to the device tree either, its references | 92| into the device tree will be invalid after manipulating | 93| it, and unpredictable behavior might occur when | 94| functions that rely on them are executed! | 95+----------------------------------------------------------+ 96 97Hence, the recommended layout of the board_fixup_fdt call-back function is the 98following: 99 100int board_fix_fdt(void *rw_fdt_blob) 101{ 102 /* Collect information about device's hardware and store them in e.g. 103 local variables */ 104 105 /* Do device tree manipulation using the values previously collected */ 106 107 /* Return 0 on successful manipulation and non-zero otherwise */ 108} 109 110If this convention is kept, both an "additive" approach, meaning that nodes for 111detected components are added to the device tree, as well as a "subtractive" 112approach, meaning that nodes for absent components are removed from the tree, 113as well as a combination of both approaches should work. 114 1153. Example 116---------- 117 118The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a 119board_fix_fdt function, in which six GPIO expanders (which might be present or 120not, since they are on daughter boards) on a I2C bus are queried for, and 121subsequently deactivated in the device tree if they are not present. 122 123Note that the dm_i2c_simple_probe function does not use the device tree, hence 124it is safe to call it after the tree has already been manipulated. 125 1264. Work to be done 127------------------ 128 129* The application of device tree overlay should be possible in board_fixup_fdt, 130 but has not been tested at this stage. 131 1322017-01-06, Mario Six <mario.six@gdsys.cc> 133