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