Let's break down a fairly simple device tree overlay, and walk through each section in order to better understand what it's doing.

Below is the device tree overlay for the UART1 device. It tells the kernel everything it needs to know in order to properly enable UART1 on pins P9_24 and P9_26.

One thing to note, make sure you're using the latest data to figure out the register offsets, and mux modes. I've found a really good reference to be the BoneScript pin reference located in the GitHub Repository.
/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for UART1 on connector pins P9.24 P9.26
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
/plugin/;

/ {
   	compatible = "ti,beaglebone", "ti,beaglebone-black";

        /* identification */
        part-number = "BB-UART1";
        version = "00A0";

        /* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.24",        /* uart1_txd */
                "P9.26",        /* uart1_rxd */
                /* the hardware ip uses */
                "uart1";

        fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart1_pins: pinmux_bb_uart1_pins {
                                pinctrl-single,pins = <
                                        0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
                                        0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
                                >;
                        };
                };
        };

	fragment@1 {
                target = <&uart2>;	/* really uart1 */
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&bb_uart1_pins>;
                };
        };
};
To start with, the above overlay is a "tree structure of nodes and properties".

We can break the file down to better understand it. The first section is just a comment that is optional, but usually a good idea to help folks understand what it's supposed to do, and for copyright/license information:
/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for UART1 on connector pins P9.24 P9.26
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
The next two lines are tokens to describe the version of the dts file, and that it's a plugin:
/dts-v1/;
/plugin/;
The next line describes the start of the root node of the DT:
The "compatible" line describes which platforms that the DT overlay is designed to work with, starting with most compatible to the least compatible. It's important to name all the platforms that you'd like to support, as it will fail to load in any platforms not mentioned.
compatible = "ti,beaglebone", "ti,beaglebone-black";
The next section, the part number and version are further guards to ensure that the proper DT overlays are loaded. In addition, they should also be used for the name of the .dts file in the form of -.dts. Also, as far as I can tell, the revision must be 00A0 on the BeagleBone Black.
/* identification */
part-number = "BB-UART1";
version = "00A0";
The exlusive-use property allows overlays to describe what resources they need, and prevents any other overlays from using those resources. In this case, we're using pins P9.24 and P9.26, as well as the uart1 device.
/* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.24",        /* uart1_txd */
                "P9.26",        /* uart1_rxd */
                /* the hardware ip uses */
                "uart1";
Next up are the device tree fragments. These will describe which target to overlay, and then each fragment will be customized to either mux pins, or enable devices. The below fragment looks fairly complicated, but it's not too bad. The first thing is that we're setting what the target for this fragment is going to overlay. In this case, it's the am33x_pinmux, which is compatible with the pinctrl-single driver. Examples on how to use this driver are found on the pinctrl-single documentation page.

The next line is the __overlay__ node itself. The first property within that node will be used in the next fragment (bb_uart1_pins), and contains the definition for muxing the pins, which is handled by the pinctrl-single driver. You can find out how to set that by viewing the documentation page. In particular, this is the section that describes how it should be setup:

  • The pin configuration nodes for pinctrl-single are specified as pinctrl register offset and value pairs using pinctrl-single,pins. Only the bits specified in pinctrl-single,function-mask are updated. For example, setting a pin for a device could be done with: pinctrl-single,pins = <0xdc 0x118>; Where 0xdc is the offset from the pinctrl register base address for the device pinctrl register, and 0x118 contains the desired value of the pinctrl register.

Within the pinctrl-single, pins value block, the two rows of values are setting the pins for the UART1 device. In this case, it's P9_24 as MODE0, which will be an OUTPUT (TX). As well as P9_26 as MODE0 an INPUT (RX). You can tell that P9_24 needed to be set to 0x184 by cross-referencing the pin reference for BoneScript (there are more around the web, but some are out of date).

fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart1_pins: pinmux_bb_uart1_pins {
                                pinctrl-single,pins = <
                                        0x184 0x20 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX)  */
                                        0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX)  */
                                >;
                        };
                };
        };
The last fragment enables the uart device. The target for the overlay is uart2 (which is commented as actually being uart1). It also references the previous fragments property (bb_uart1_pins) to map the pins enabled by the pinctrl driver to the uart device.
	fragment@1 {
                target = <&uart2>;	/* really uart1 */
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&bb_uart1_pins>;
                };
        };
This may seem quite overwhelming, and really obscure, and it kind of is. The easiest way to create a new overlay for what you want done is to start with one that is already close to what you want to do. The best place to look for that is in /lib/firmware (on Angstrom), and peruse the overlays already created for you to use.

This guide was first published on Jul 29, 2013. It was last updated on Jul 29, 2013.

This page (Device Tree Overlays) was last updated on Jul 26, 2013.

Text editor powered by tinymce.