Device Tree Made Easy
Device Tree Made Easy
EUF-DES-T1465
Massimo Bonazzi
M A Y. 2 0 1 5
TM
External Use
Agenda
• What’s the device tree?
• How was it working up to now?
• What’s changed?
• Device Tree syntax
• Bindings
• Bindings GIC example
• Bindings I2C example
• Gpio keys example
• i.MX 6Q device tree files
• How to build the dtb
• References
TM
External Use 1
What’s the Device Tree ?
TM
External Use 2
How Did it Work Until Now?
TM
External Use 3
How Did it Work Until Now?
RAM
• ATAGS has to be in RAM
ATAGS <R2>
• R2 should contain ATAG
address in recent kernels
• ATAGS must not extend beyond
the 0x4000 boundary
• 32 bit aligned
• Starts with ATAG_CORE, ends
with ATAG_NONE Kernel
• Must contain at least one
ATAG_MEM
TM
External Use 4
What’s Changed?
TM
External Use 5
What’s hanged?
RAM
• R2 now points to the DTB
DTB <R2>
• R1 is not used anymore
• The same kernel can be used for
more than one board
Kernel
TM
External Use 6
Device Tree Syntax
/{ Node
name
cpus {
#address-cells = <1>;
#size-cells = <0>;
Unit
address Property
value
Label
cpu0: cpu@0 {
compatible = "arm,cortex-a9";
Property device_type = "cpu"; phandle
name
reg = <0>;
next-level-cache = <&L2>;
operating-points = < Cell
/* kHz uV */ property
1200000 1275000
996000 1250000
852000 1250000
792000 1150000
396000 975000
>;
………………
TM
External Use 7
Bindings
TM
External Use 8
Bindings GIC Example
* ARM Generic Interrupt Controller
ARM SMP cores are often associated with a GIC, providing per processor interrupts (PPI), shared processor interrupts (SPI) and software generated interrupts (SGI).
Primary GIC is attached directly to the CPU and typically has PPIs and SGIs. Secondary GICs are cascaded into the upward interrupt controller and do not have PPIs or
SGIs.
Legal
Main node required properties:
properties
The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI interrupts.
The 2nd cell contains the interrupt number for the interrupt type. SPI interrupts are in the range [0-987]. PPI interrupts are in the range [0-15].
TM
External Use 9
Bindings I2C Example (I2C-imx.txt)
* Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX
Required
Required properties: properties
- compatible : Should be "fsl,<chip>-i2c"
- reg : Should contain I2C/HS-I2C registers location and length
- interrupts : Should contain I2C/HS-I2C interrupt
Optional
properties
Optional properties:
- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz.
The absence of the propoerty indicates the default frequency 100 kHz.
Examples:
External Use 10
Bindings I2C Example
i2c1: i2c@021a0000 { Required
#address-cells = <1>; properties
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a0000 0x4000>;
interrupts = <0 36 0x04>;
clocks = <&clks 125>;
status = "disabled";
Status };
disabled
i2c2: i2c@021a4000 {
#address-cells = <1>; Address
#size-cells = <0>; space
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a4000 0x4000>;
interrupts = <0 37 0x04>;
clocks = <&clks 126>;
Interrupts
What status = "disabled"; GIC’s style
clock? };
Later on in imx6qdl-sabresd.dtsi
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1_2>;
status = "okay";
codec: wm8962@1a {
Here it goes
compatible = "wlf,wm8962";
to okay
reg = <0x1a>;
TM
External Use 11
Bindings I2C Example Adding a Device
mma8451@1c { Compatible
compatible = "fsl,mma8451";
Node and reg = <0x1c>;
address position = <1>;
I2C
address
vdd-supply = <®_sensor>;
vddio-supply = <®_sensor>;
};
What
regulator?
Example:
accelerometer: mma8450@1c {
compatible = "fsl,mma8450";
reg = <0x1c>;
};
TM
External Use 12
Gpio Keys Example
Driver
compatibility
gpio-keys {
bind
compatible = "gpio-keys";
power {
Phandle to the pin
label = "Power Button"; (bank number flags)
A name for gpios = <&gpio3 29 1>;
convenience linux,code = <116>; /* KEY_POWER */
gpio-key,wakeup;
Need to }; The key ./include/linux/input.h
wakup? number
volume-up { #define KEY_VOLUMEDOWN 114
label = "Volume Up"; #define KEY_VOLUMEUP 115
gpios = <&gpio1 4 1>; #define KEY_POWER 116
linux,code = <115>; /* KEY_VOLUMEUP */
};
Here they
volume-down { are…
label = "Volume Down";
gpios = <&gpio1 5 1>;
linux,code = <114>; /* KEY_VOLUMEDOWN */
};
};
TM
External Use 13
Gpio Keys Example
Bank 3
address
gpio3: gpio@020a4000 {
compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
reg = <0x020a4000 0x4000>;
16K
interrupts = <0 70 0x04 0 71 0x04>;
gpio-controller; Shared
Marks #gpio-cells = <2>; 102-32=70
Trigger Documentation/devicetree/bindings/arm/gic.txt
interrupt-controller; - #interrupt-cells : Specifies the number of cells needed to encode an
interrupt source. The type shall be a <u32> and the value shall be 3.
#interrupt-cells = <2>;
}; The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
interrupts.
The 2nd cell contains the interrupt number for the interrupt type.
SPI interrupts are in the range [0-987]. PPI interrupts are in the
range [0-15].
External Use 14
Gpio Keys Example
volume-up {
label = "Volume Up";
gpios = <&gpio1 4 1>;
linux,code = <115>; /* KEY_VOLUMEUP */
};
volume-down {
label = "Volume Down";
gpios = <&gpio1 5 1>;
linux,code = <114>; /* KEY_VOLUMEDOWN */
};
TM
External Use 15
Driver Interface to the DTB
static struct gpio_keys_platform_data * gpio_keys_get_devtree_pdata(struct device *dev)
{
struct device_node *node, *pp; All done
struct gpio_keys_platform_data *pdata; here!
How struct gpio_keys_button *button;
many? int error,nbuttons; The node
node = dev->of_node;
nbuttons = of_get_child_count(node);
pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button),GFP_KERNEL);
pdata->buttons = (struct gpio_keys_button *)(pdata + 1); Get
pdata->nbuttons = nbuttons; autorepeat
pdata->rep = !!of_get_property(node, "autorepeat", NULL);
for_each_child_of_node(node, pp) {
int gpio; Is this property
Iterate… enum of_gpio_flags flags; there?
if (!of_find_property(pp, "gpios", NULL)) {
pdata->nbuttons--;
dev_warn(dev, "Found button without gpios\n");
continue;
}
Get flags
gpio = of_get_gpio_flags(pp, 0, &flags);
button = &pdata->buttons[i++];
button->gpio = gpio;
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
TM
External Use 16
Driver Interface to the DTB
if (of_property_read_u32(pp, "linux,code", &button->code)) {
dev_err(dev, "Button without keycode: 0x%x\n",button->gpio);
Get Key
code error = -EINVAL;
Get label
}
button->desc = of_get_property(pp, "label", NULL);
if (of_property_read_u32(pp, "linux,input-type", &button->type))
Is it button->type = EV_KEY;
wakeup?
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
TM
External Use 17
#include "imx6q.dtsi"
i.MX 6Q Device Tree Files #include "imx6qdl-sabresd.dtsi"
/{
model = "Freescale i.MX6 Quad SABRE Smart Device
Board stuff Board";
compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
Imx6q-sabresd.dts };
&battery {
offset-charger = <1900>;
offset-discharger = <1694>;
offset-usb-charger = <1685>;
};
cpus {
#address-cells = <1>;
Imx6q.dtsi Imx6qdl-sabresd.dtsi #size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0>;
next-level-cache = <&L2>;
SOC stuff operating-points = <
/* kHz uV */
1200000 1275000
996000 1250000
852000 1250000
792000 1150000
Imx6qdl-sabresd.dtsi Imx6qdl-sabresd.dtsi 396000 975000
TM
External Use 18
How to Build the DTB
TM
External Use 19
References
• Wikipedia.org
• Linux Kernel Doc’s in Documentation/devicetree
• Thomas Petazzoni’s preso in http://www.freeelectrons.org
• Power.orgTM Standard for Embedded Power Architecture Platform
Requirements (ePAPR), http://www.power.org/
• http://www.devicetree.org
TM
External Use 20
TM
www.Freescale.com