xref: /openbmc/u-boot/doc/driver-model/of-plat.txt (revision 151b8339ccd33428d249e75bd036bd7eb33c1ef6)
139782afbSSimon GlassDriver Model Compiled-in Device Tree / Platform Data
239782afbSSimon Glass====================================================
339782afbSSimon Glass
439782afbSSimon Glass
539782afbSSimon GlassIntroduction
639782afbSSimon Glass------------
739782afbSSimon Glass
839782afbSSimon GlassDevice tree is the standard configuration method in U-Boot. It is used to
939782afbSSimon Glassdefine what devices are in the system and provide configuration information
1039782afbSSimon Glassto these devices.
1139782afbSSimon Glass
1239782afbSSimon GlassThe overhead of adding device tree access to U-Boot is fairly modest,
1339782afbSSimon Glassapproximately 3KB on Thumb 2 (plus the size of the DT itself). This means
1439782afbSSimon Glassthat in most cases it is best to use device tree for configuration.
1539782afbSSimon Glass
1639782afbSSimon GlassHowever there are some very constrained environments where U-Boot needs to
1739782afbSSimon Glasswork. These include SPL with severe memory limitations. For example, some
1839782afbSSimon GlassSoCs require a 16KB SPL image which must include a full MMC stack. In this
1939782afbSSimon Glasscase the overhead of device tree access may be too great.
2039782afbSSimon Glass
2139782afbSSimon GlassIt is possible to create platform data manually by defining C structures
2212696251SSimon Glassfor it, and reference that data in a U_BOOT_DEVICE() declaration. This
2312696251SSimon Glassbypasses the use of device tree completely, effectively creating a parallel
2412696251SSimon Glassconfiguration mechanism. But it is an available option for SPL.
2539782afbSSimon Glass
2612696251SSimon GlassAs an alternative, a new 'of-platdata' feature is provided. This converts the
2739782afbSSimon Glassdevice tree contents into C code which can be compiled into the SPL binary.
2839782afbSSimon GlassThis saves the 3KB of code overhead and perhaps a few hundred more bytes due
2939782afbSSimon Glassto more efficient storage of the data.
3039782afbSSimon Glass
3112696251SSimon GlassNote: Quite a bit of thought has gone into the design of this feature.
3212696251SSimon GlassHowever it still has many rough edges and comments and suggestions are
3312696251SSimon Glassstrongly encouraged! Quite possibly there is a much better approach.
3412696251SSimon Glass
3539782afbSSimon Glass
3639782afbSSimon GlassCaveats
3739782afbSSimon Glass-------
3839782afbSSimon Glass
3939782afbSSimon GlassThere are many problems with this features. It should only be used when
4012696251SSimon Glassstrictly necessary. Notable problems include:
4139782afbSSimon Glass
4212696251SSimon Glass   - Device tree does not describe data types. But the C code must define a
4312696251SSimon Glass        type for each property. These are guessed using heuristics which
4439782afbSSimon Glass        are wrong in several fairly common cases. For example an 8-byte value
4539782afbSSimon Glass        is considered to be a 2-item integer array, and is byte-swapped. A
4639782afbSSimon Glass        boolean value that is not present means 'false', but cannot be
4739782afbSSimon Glass        included in the structures since there is generally no mention of it
4839782afbSSimon Glass        in the device tree file.
4939782afbSSimon Glass
5039782afbSSimon Glass   - Naming of nodes and properties is automatic. This means that they follow
5139782afbSSimon Glass        the naming in the device tree, which may result in C identifiers that
5212696251SSimon Glass        look a bit strange.
5339782afbSSimon Glass
5439782afbSSimon Glass   - It is not possible to find a value given a property name. Code must use
5539782afbSSimon Glass        the associated C member variable directly in the code. This makes
5639782afbSSimon Glass        the code less robust in the face of device-tree changes. It also
5739782afbSSimon Glass        makes it very unlikely that your driver code will be useful for more
5839782afbSSimon Glass        than one SoC. Even if the code is common, each SoC will end up with
5912696251SSimon Glass        a different C struct name, and a likely a different format for the
6012696251SSimon Glass        platform data.
6139782afbSSimon Glass
6239782afbSSimon Glass   - The platform data is provided to drivers as a C structure. The driver
6339782afbSSimon Glass        must use the same structure to access the data. Since a driver
6439782afbSSimon Glass        normally also supports device tree it must use #ifdef to separate
6539782afbSSimon Glass        out this code, since the structures are only available in SPL.
6639782afbSSimon Glass
67*3600b461SSimon Goldschmidt   - Correct relations between nodes are not implemented. This means that
68*3600b461SSimon Goldschmidt        parent/child relations (like bus device iteration) do not work yet.
69*3600b461SSimon Goldschmidt        Some phandles (those that are recognised as such) are converted into
70*3600b461SSimon Goldschmidt        a pointer to platform data. This pointer can potentially be used to
71*3600b461SSimon Goldschmidt        access the referenced device (by searching for the pointer value).
72*3600b461SSimon Goldschmidt        This feature is not yet implemented, however.
73*3600b461SSimon Goldschmidt
7439782afbSSimon Glass
7539782afbSSimon GlassHow it works
7639782afbSSimon Glass------------
7739782afbSSimon Glass
78*3600b461SSimon GoldschmidtThe feature is enabled by CONFIG OF_PLATDATA. This is only available in
79*3600b461SSimon GoldschmidtSPL/TPL and should be tested with:
8039782afbSSimon Glass
81*3600b461SSimon Goldschmidt        #if CONFIG_IS_ENABLED(OF_PLATDATA)
8239782afbSSimon Glass
8339782afbSSimon GlassA new tool called 'dtoc' converts a device tree file either into a set of
84*3600b461SSimon Goldschmidtstruct declarations, one for each compatible node, and a set of
8539782afbSSimon GlassU_BOOT_DEVICE() declarations along with the actual platform data for each
8639782afbSSimon Glassdevice. As an example, consider this MMC node:
8739782afbSSimon Glass
8839782afbSSimon Glass        sdmmc: dwmmc@ff0c0000 {
8939782afbSSimon Glass                compatible = "rockchip,rk3288-dw-mshc";
9039782afbSSimon Glass                clock-freq-min-max = <400000 150000000>;
9139782afbSSimon Glass                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
9239782afbSSimon Glass                         <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
9339782afbSSimon Glass                clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
9439782afbSSimon Glass                fifo-depth = <0x100>;
9539782afbSSimon Glass                interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
9639782afbSSimon Glass                reg = <0xff0c0000 0x4000>;
9739782afbSSimon Glass                bus-width = <4>;
9839782afbSSimon Glass                cap-mmc-highspeed;
9939782afbSSimon Glass                cap-sd-highspeed;
10039782afbSSimon Glass                card-detect-delay = <200>;
10139782afbSSimon Glass                disable-wp;
10239782afbSSimon Glass                num-slots = <1>;
10339782afbSSimon Glass                pinctrl-names = "default";
10439782afbSSimon Glass                pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
10539782afbSSimon Glass                vmmc-supply = <&vcc_sd>;
10639782afbSSimon Glass                status = "okay";
10739782afbSSimon Glass                u-boot,dm-pre-reloc;
10839782afbSSimon Glass        };
10939782afbSSimon Glass
11039782afbSSimon Glass
11139782afbSSimon GlassSome of these properties are dropped by U-Boot under control of the
11239782afbSSimon GlassCONFIG_OF_SPL_REMOVE_PROPS option. The rest are processed. This will produce
11339782afbSSimon Glassthe following C struct declaration:
11439782afbSSimon Glass
11539782afbSSimon Glassstruct dtd_rockchip_rk3288_dw_mshc {
11639782afbSSimon Glass        fdt32_t         bus_width;
11739782afbSSimon Glass        bool            cap_mmc_highspeed;
11839782afbSSimon Glass        bool            cap_sd_highspeed;
11939782afbSSimon Glass        fdt32_t         card_detect_delay;
12039782afbSSimon Glass        fdt32_t         clock_freq_min_max[2];
1210d15463cSSimon Glass        struct phandle_1_arg clocks[4];
12239782afbSSimon Glass        bool            disable_wp;
12339782afbSSimon Glass        fdt32_t         fifo_depth;
12439782afbSSimon Glass        fdt32_t         interrupts[3];
12539782afbSSimon Glass        fdt32_t         num_slots;
12639782afbSSimon Glass        fdt32_t         reg[2];
12739782afbSSimon Glass        fdt32_t         vmmc_supply;
12839782afbSSimon Glass};
12939782afbSSimon Glass
13039782afbSSimon Glassand the following device declaration:
13139782afbSSimon Glass
13239782afbSSimon Glassstatic struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
13339782afbSSimon Glass        .fifo_depth             = 0x100,
13439782afbSSimon Glass        .cap_sd_highspeed       = true,
13539782afbSSimon Glass        .interrupts             = {0x0, 0x20, 0x4},
13639782afbSSimon Glass        .clock_freq_min_max     = {0x61a80, 0x8f0d180},
13739782afbSSimon Glass        .vmmc_supply            = 0xb,
13839782afbSSimon Glass        .num_slots              = 0x1,
13912696251SSimon Glass        .clocks                 = {{&dtv_clock_controller_at_ff760000, 456},
14012696251SSimon Glass                                   {&dtv_clock_controller_at_ff760000, 68},
14112696251SSimon Glass                                   {&dtv_clock_controller_at_ff760000, 114},
14212696251SSimon Glass                                   {&dtv_clock_controller_at_ff760000, 118}},
14339782afbSSimon Glass        .cap_mmc_highspeed      = true,
14439782afbSSimon Glass        .disable_wp             = true,
14539782afbSSimon Glass        .bus_width              = 0x4,
14639782afbSSimon Glass        .u_boot_dm_pre_reloc    = true,
14739782afbSSimon Glass        .reg                    = {0xff0c0000, 0x4000},
14839782afbSSimon Glass        .card_detect_delay      = 0xc8,
14939782afbSSimon Glass};
15039782afbSSimon GlassU_BOOT_DEVICE(dwmmc_at_ff0c0000) = {
15139782afbSSimon Glass        .name           = "rockchip_rk3288_dw_mshc",
15239782afbSSimon Glass        .platdata       = &dtv_dwmmc_at_ff0c0000,
15312696251SSimon Glass        .platdata_size  = sizeof(dtv_dwmmc_at_ff0c0000),
15439782afbSSimon Glass};
15539782afbSSimon Glass
15639782afbSSimon GlassThe device is then instantiated at run-time and the platform data can be
15739782afbSSimon Glassaccessed using:
15839782afbSSimon Glass
15939782afbSSimon Glass        struct udevice *dev;
16039782afbSSimon Glass        struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_platdata(dev);
16139782afbSSimon Glass
16239782afbSSimon GlassThis avoids the code overhead of converting the device tree data to
16339782afbSSimon Glassplatform data in the driver. The ofdata_to_platdata() method should
16439782afbSSimon Glasstherefore do nothing in such a driver.
16539782afbSSimon Glass
166*3600b461SSimon GoldschmidtNote that for the platform data to be matched with a driver, the 'name'
167*3600b461SSimon Goldschmidtproperty of the U_BOOT_DEVICE() declaration has to match a driver declared
168*3600b461SSimon Goldschmidtvia U_BOOT_DRIVER(). This effectively means that a U_BOOT_DRIVER() with a
169*3600b461SSimon Goldschmidt'name' corresponding to the devicetree 'compatible' string (after converting
170*3600b461SSimon Goldschmidtit to a valid name for C) is needed, so a dedicated driver is required for
171*3600b461SSimon Goldschmidteach 'compatible' string.
172*3600b461SSimon Goldschmidt
1732cce5866SSimon GlassWhere a node has multiple compatible strings, a #define is used to make them
1742cce5866SSimon Glassequivalent, e.g.:
1752cce5866SSimon Glass
1762cce5866SSimon Glass#define dtd_rockchip_rk3299_dw_mshc dtd_rockchip_rk3288_dw_mshc
1772cce5866SSimon Glass
17839782afbSSimon Glass
17912696251SSimon GlassConverting of-platdata to a useful form
18012696251SSimon Glass---------------------------------------
18112696251SSimon Glass
182*3600b461SSimon GoldschmidtOf course it would be possible to use the of-platdata directly in your driver
183*3600b461SSimon Goldschmidtwhenever configuration information is required. However this means that the
18412696251SSimon Glassdriver will not be able to support device tree, since the of-platdata
18512696251SSimon Glassstructure is not available when device tree is used. It would make no sense
18612696251SSimon Glassto use this structure if device tree were available, since the structure has
18712696251SSimon Glassall the limitations metioned in caveats above.
18812696251SSimon Glass
18912696251SSimon GlassTherefore it is recommended that the of-platdata structure should be used
19012696251SSimon Glassonly in the probe() method of your driver. It cannot be used in the
19112696251SSimon Glassofdata_to_platdata() method since this is not called when platform data is
19212696251SSimon Glassalready present.
19312696251SSimon Glass
19412696251SSimon Glass
19539782afbSSimon GlassHow to structure your driver
19639782afbSSimon Glass----------------------------
19739782afbSSimon Glass
19839782afbSSimon GlassDrivers should always support device tree as an option. The of-platdata
19939782afbSSimon Glassfeature is intended as a add-on to existing drivers.
20039782afbSSimon Glass
20112696251SSimon GlassYour driver should convert the platdata struct in its probe() method. The
20212696251SSimon Glassexisting device tree decoding logic should be kept in the
20312696251SSimon Glassofdata_to_platdata() method and wrapped with #if.
20439782afbSSimon Glass
20539782afbSSimon GlassFor example:
20639782afbSSimon Glass
20739782afbSSimon Glass    #include <dt-structs.h>
20839782afbSSimon Glass
20939782afbSSimon Glass    struct mmc_platdata {
21039782afbSSimon Glass    #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
21112696251SSimon Glass            /* Put this first since driver model will copy the data here */
21239782afbSSimon Glass            struct dtd_mmc dtplat;
21339782afbSSimon Glass    #endif
21439782afbSSimon Glass            /*
21539782afbSSimon Glass             * Other fields can go here, to be filled in by decoding from
21612696251SSimon Glass             * the device tree (or the C structures when of-platdata is used).
21739782afbSSimon Glass             */
21839782afbSSimon Glass            int fifo_depth;
21939782afbSSimon Glass    };
22039782afbSSimon Glass
22139782afbSSimon Glass    static int mmc_ofdata_to_platdata(struct udevice *dev)
22239782afbSSimon Glass    {
22339782afbSSimon Glass    #if !CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
22412696251SSimon Glass            /* Decode the device tree data */
22539782afbSSimon Glass            struct mmc_platdata *plat = dev_get_platdata(dev);
22639782afbSSimon Glass            const void *blob = gd->fdt_blob;
227e160f7d4SSimon Glass            int node = dev_of_offset(dev);
22839782afbSSimon Glass
22939782afbSSimon Glass            plat->fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0);
23039782afbSSimon Glass    #endif
23139782afbSSimon Glass
23239782afbSSimon Glass            return 0;
23339782afbSSimon Glass    }
23439782afbSSimon Glass
23539782afbSSimon Glass    static int mmc_probe(struct udevice *dev)
23639782afbSSimon Glass    {
23739782afbSSimon Glass            struct mmc_platdata *plat = dev_get_platdata(dev);
23812696251SSimon Glass
23939782afbSSimon Glass    #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
24012696251SSimon Glass            /* Decode the of-platdata from the C structures */
24139782afbSSimon Glass            struct dtd_mmc *dtplat = &plat->dtplat;
24239782afbSSimon Glass
24312696251SSimon Glass            plat->fifo_depth = dtplat->fifo_depth;
24412696251SSimon Glass    #endif
24539782afbSSimon Glass            /* Set up the device from the plat data */
24639782afbSSimon Glass            writel(plat->fifo_depth, ...)
24739782afbSSimon Glass    }
24839782afbSSimon Glass
24939782afbSSimon Glass    static const struct udevice_id mmc_ids[] = {
25039782afbSSimon Glass            { .compatible = "vendor,mmc" },
25139782afbSSimon Glass            { }
25239782afbSSimon Glass    };
25339782afbSSimon Glass
25439782afbSSimon Glass    U_BOOT_DRIVER(mmc_drv) = {
25539782afbSSimon Glass            .name           = "mmc",
25639782afbSSimon Glass            .id             = UCLASS_MMC,
25739782afbSSimon Glass            .of_match       = mmc_ids,
25839782afbSSimon Glass            .ofdata_to_platdata = mmc_ofdata_to_platdata,
25939782afbSSimon Glass            .probe          = mmc_probe,
26039782afbSSimon Glass            .priv_auto_alloc_size = sizeof(struct mmc_priv),
26139782afbSSimon Glass            .platdata_auto_alloc_size = sizeof(struct mmc_platdata),
26239782afbSSimon Glass    };
26339782afbSSimon Glass
26439782afbSSimon Glass
26539782afbSSimon GlassIn the case where SPL_OF_PLATDATA is enabled, platdata_auto_alloc_size is
26612696251SSimon Glassstill used to allocate space for the platform data. This is different from
26712696251SSimon Glassthe normal behaviour and is triggered by the use of of-platdata (strictly
26812696251SSimon Glassspeaking it is a non-zero platdata_size which triggers this).
26939782afbSSimon Glass
27012696251SSimon GlassThe of-platdata struct contents is copied from the C structure data to the
27112696251SSimon Glassstart of the newly allocated area. In the case where device tree is used,
27212696251SSimon Glassthe platform data is allocated, and starts zeroed. In this case the
27312696251SSimon Glassofdata_to_platdata() method should still set up the platform data (and the
27412696251SSimon Glassof-platdata struct will not be present).
27512696251SSimon Glass
27612696251SSimon GlassSPL must use either of-platdata or device tree. Drivers cannot use both at
27712696251SSimon Glassthe same time, but they must support device tree. Supporting of-platdata is
27812696251SSimon Glassoptional.
27912696251SSimon Glass
28039782afbSSimon GlassThe device tree becomes in accessible when CONFIG_SPL_OF_PLATDATA is enabled,
28112696251SSimon Glasssince the device-tree access code is not compiled in. A corollary is that
28212696251SSimon Glassa board can only move to using of-platdata if all the drivers it uses support
28312696251SSimon Glassit. There would be little point in having some drivers require the device
28412696251SSimon Glasstree data, since then libfdt would still be needed for those drivers and
28512696251SSimon Glassthere would be no code-size benefit.
28639782afbSSimon Glass
28739782afbSSimon GlassInternals
28839782afbSSimon Glass---------
28939782afbSSimon Glass
29039782afbSSimon GlassThe dt-structs.h file includes the generated file
29139782afbSSimon Glass(include/generated//dt-structs.h) if CONFIG_SPL_OF_PLATDATA is enabled.
29239782afbSSimon GlassOtherwise (such as in U-Boot proper) these structs are not available. This
29312696251SSimon Glassprevents them being used inadvertently. All usage must be bracketed with
29412696251SSimon Glass#if CONFIG_IS_ENABLED(SPL_OF_PLATDATA).
29539782afbSSimon Glass
29639782afbSSimon GlassThe dt-platdata.c file contains the device declarations and is is built in
29739782afbSSimon Glassspl/dt-platdata.c.
29839782afbSSimon Glass
29939782afbSSimon GlassThe beginnings of a libfdt Python module are provided. So far this only
30039782afbSSimon Glassimplements a subset of the features.
30139782afbSSimon Glass
30212696251SSimon GlassThe 'swig' tool is needed to build the libfdt Python module. If this is not
30312696251SSimon Glassfound then the Python model is not used and a fallback is used instead, which
30412696251SSimon Glassmakes use of fdtget.
30512696251SSimon Glass
30612696251SSimon Glass
30712696251SSimon GlassCredits
30812696251SSimon Glass-------
30912696251SSimon Glass
31012696251SSimon GlassThis is an implementation of an idea by Tom Rini <trini@konsulko.com>.
31139782afbSSimon Glass
31239782afbSSimon Glass
31339782afbSSimon GlassFuture work
31439782afbSSimon Glass-----------
31539782afbSSimon Glass- Consider programmatically reading binding files instead of device tree
31639782afbSSimon Glass     contents
31739782afbSSimon Glass- Complete the phandle feature
31839782afbSSimon Glass- Move to using a full Python libfdt module
31939782afbSSimon Glass
32039782afbSSimon Glass--
32139782afbSSimon GlassSimon Glass <sjg@chromium.org>
32212696251SSimon GlassGoogle, Inc
32339782afbSSimon Glass6/6/16
32412696251SSimon GlassUpdated Independence Day 2016
325