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