1g Easior!™
‘Making Everythin:
Learn to:
* Boot your system with a Device
Tree
ind the basic syntax of,
Tre
about Device Tre
Thomas Petazzoni
Free Elcvons. Kel divers and embedded Linux deepen, cosuing. ining and sppor, http: //free-electrons.com ">» CTO and Embedded Linux engineer at Free Electrons
» Embedded Linux development: kernel and driver
development, system integration, boot time and power
consumption optimization, consulting, etc.
> Embedded Linux training, Linux driver development training
and Android system development training, with materials
freely available under a Creative Commons license.
> http://free-electrons.com
> Contributions
> Kernel support for the Marvell Armada ARM SoCs from
Marvell
> Major contributor to Buildroot, an open-source, simple and
fast embedded Linux build system
> Living in Toulouse, south west of France>» Quick reminder about ARM platforms
v
User perspective: booting with the Device Tree
Basic Device Tree syntax and compilation
Simple example of Device Tree fragment
Overall organization of a Device Tree
Examples of Device Tree usage
vvvwywysy
General considerations about the Device Tree in Linux> ARM (the company) designs CPU cores: instruction set,
MMU, caches, etc.
» They don’t sell any hardware
» Silicon vendors buy the CPU core design from ARM, and
around it add a number of peripherals, either designed
internally or bought from third parties
> Texas Instruments, Atmel, Marvell, Freescale, Qualcomm,
Nvidia, etc.
> They sell System-on-chip or SoCs
> System makers design an actual board, with one or several
processors, and a number of on-board peripheralsBoard
‘System on Chip
lac
>| device
ARM
Cortex-A9 HE
SPI device
device
Internal
sot
bus
SPI SPI rae rae
device controller i< >) controller >| device
USB
Coa controller
‘Crypto DMA
use.
‘connector> Certain busses have dynamic discoverability features
> USB, PCI
> Allow to enumerate devices on the bus, query their
characteristics, at runtime.
» No need to know in advance what's on the bus
> But many busses do not have such features
>» Memory-mapped devices inside SoC, I2C, SPI, SDIO, etc.
> The system has to know in advance “where” the different
devices are located, and their characteristics> The kernel contains the entire description of the hardware.
> The bootloader loads a single binary, the kernel image, and
executes it.
> ulmage or zImage
> The bootloader prepares some additional information, called
ATAGS, which address is passed to the kernel through register
r2
» Contains information such as memory size and location, kernel
command line, etc.
> The bootloader tells the kernel on which board it is being
booted through a machine type integer, passed in register r1.
» U-Boot command: bootm
» Barebox variable: bootm. imageATAGS
RAM
rl
r2
> The kernel no longer contains the description of the hardware,
it is located in a separate binary: the device tree blob
> The bootloader loads two binaries: the kernel image and the
DTB
> Kernel image remains ulmage or zImage
> DTB located in arch/arm/boot/dts, one per board
> The bootloader passes the DTB address through r2. It is
supposed to adjust the DTB with memory information, kernel
command line, and potentially other info.
> No more machine type.
» U-Boot command:
boot [mz] -
> Barebox variables: bootm.image, bootm.oftreeRAM
rl = don't care
r2 = >» Some bootloaders have no specific support for the Device
Tree, or the version used on a particular device is too old to
have this support.
> To ease the transition, a compatibility mechanism was added:
CONFIG_ARM_APPENDED_DTB.
> It tells the kernel to look for a DTB right after the kernel
image.
> There is no built-in Makefile rule to produce such kernel, so
one must manually do:
> In addition, the additional option
CONFIG_ARM_ATAG_DTB_COMPAT tells the kernel to read the
ATAGS information from the bootloader, and update the DT
using them.> Quoted from the Power.org Standard for Embedded Power
Architecture Platform Requirements (ePAPR)
> The ePAPR specifies a concept called a device tree to describe
system hardware. A boot program loads a device tree into a
client program’s memory and passes a pointer to the device
tree to the client.
> A device tree is a tree data structure with nodes that describe
the physical devices in a system.
> An ePAPR-compliant device tree describes device information
in a system that cannot be dynamically detected by a client
program.Node name
Unit address
- Property name
Property value
nodees { V
-string-property string";
-string-List-property = “first string", “second string";
-byte-data-property = [0x01 0x23 0x34 0x56];
child-nodeeo { t
first-child-property; Bytestring
second-child-property = ;
a-reference-to-something = <&nodel>;
A vrandte—D
(reference to another node)
Properties of roeeo|
child-node@l {
‘an-empty-propert;
-cell-property = <1 2 3 4>;
child-nodego {
Four cells (32 bits values)> On ARM, all Device Tree Source files (DTS) are for now
located in arch/arm/boot/dts
> .dts files for board-level definitions
» .dtsi files for included files, generally containing SoC-level
definitions
> A tool, the Device Tree Compiler compiles the source into a
binary form.
» Source code located in scripts/dtc
> The Device Tree Blob is produced by the compiler, and is
the binary that gets loaded by the bootloader and parsed by
the kernel at boot time.
> arch/arm/boot/dts/Makefile lists which DTBs should be
generated at build time.> In /sys/firmware/devicetree/base, there is a
directory/file representation of the Device Tree contents
» If dtc is available on the target, possible to “unpack” the
Device Tree using:
dtc -I fs /sys/firmware/devicetree/baseauartO: serial@8e06a000 {
Defines the "programming model" for the device. Allows the
operating system to identify the corresponding device driver.
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
Address and length of the register area.
reg = <0x8006a000 0x2000>;
Interrupt number.
interrupts = <112>;
DMA engine and channels, with names.
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
Reference to the clock.
clocks = <&clks 45>;
The device is not enabled
status = "disabled";
Taken from arch/arm/boot/dts/imx28.dtsiThe compatible string used to bind a device with the driver
Code from drivers/tty/serial/mxs-auart.c>» of_match_device allows to get the matching entry in the
mxs_auart_dt_ids table.
> Useful to get the driver-specific data field, typically used to
alter the behavior of the driver depending on the variant of
the detected device.> Getting a reference to the clock
» described by the clocks property
> s->clk = clk_get(pdev->dev, NULL);
> Getting the I/O registers resource
» described by the reg property
» x = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> Getting the interrupt
» described by the interrupts property
> s->irq = platform_get_irq(pdev, 0);
> Get a DMA channel
» described by the dmas property
» s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx");
> s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx");
>» Check some custom property
> struct device node +np = pdev->dev.of_node;
> if (of_get_property(np, "fsl,uart-has-rtscts", NULL))> Device Tree files are not monolithic, they can be split in
several files, including each other.
>» .dtsi files are included files, while .dts files are final Device
Trees
> Typically, .dtsi will contain definition of SoC-level
information (or sometimes definitions common to several
almost identical boards).
> The .dts file contains the board-level information
> The inclusion works by overlaying the tree of the including
file over the tree of the included file.
> Inclusion using the DT operator /include/, or since a few
kernel releases, the DTS go through the C preprocessor, so
#include is recommended.Definition of the AM33xx SoC
Definition of the
BeagleBone board
NM Finclude "aa dP
onpatibte = "han; “
on
bar opstibte = “ti,an5x-bone", t1,an3900%;
arto; serinentee00 ¢ tea
Fecmese ate) a nora uartO: serialeetesseae {
pe elcoeerene eee + pinctr\enaes = sdfautt
pare Binetr tet eae pins
) Sine 2 lays
ho B
vu am33xx.dtsi i am335x-bone. dts
Compiled DTB
i
conpatibte = “ti,an5x-bone*, “tian;
Uuart@: sertalgsaeesene {
compatible = "ti,onap3-uart*
reg = <0xa¢e09000 0x2008>;
interrupts = <72>;
pinctri-nanes = *defavlt*;
Pinctrt-0 = <6uart0_pins>;
Note: the real DTB isin binary format,
Here we show the text equivatent ofthe
TB contentsarmada-370-xp.dtsi
ot,
SoCs
armada-xp.dtsi
EN
armada-xp- armada-xp- arnada-xp-
1nv78230.dtsi v78260.dtsi v78460.dtsi
armada-xp-
armada-378- armada-xp-
: oa oe openblocks- ‘armada-xp-db.dts
Boards ‘abox.dts axpwifiap.dts ee
arnada-378-
netgear-rnie2.dts aaa
arnada-370-rd.dts
armada-370-db.dts> Quoting the ePAPR:
> This chapter contains requirements, known as bindings, for
how specific types and classes of devices are represented
in the device tree.
» The compatible property of a device node describes the
specific binding (or bindings) to which the node complies.
> When creating a new device tree representation for a device, a
binding should be created that fully describes the
required properties and value of the device. This set of
properties shall be sufficiently descriptive to provide device
drivers with needed attributes of the device» All Device Tree bindings recognized by the kernel are
documented in Documentation/devicetree/bindings.
» Each binding documentation described which properties are
accepted, with which values, which properties are mandatory
vs. optional, etc.
> All new Device Tree bindings must be reviewed by the Device
Tree maintainers, by being posted to
[email protected]. This ensures correctness
and consistency across bindings.Docunentation/devicetree/bindings/tty/serial/fsl-mxs~auart.txtUnder the root of the Device Tree, one typically finds the following
top-level nodes:
» A cpus node, which sub-nodes describing each CPU in the
system.
>» A memory node, which defines the location and size of the
RAM.
> A chosen node, which defines parameters chosen or defined
by the system firmware at boot time. In practice, one of its
usage is to pass the kernel command line.
» A aliases node, to define shortcuts to certain nodes.
> One or more nodes defining the buses in the SoC.
> One or mode nodes defining on-board devices.arch/arm/boot/dts/imx28.dtsiFigure 1-2. .MX28 SOC System Busesarch/arm/boot/dts/imx28-evk.dts> The top-level compatible property typically defines a
compatible string for the board, and then for the SoC.
> Values always given with the most-specific first, to
least-specific last.
» Used to match with the dt_compat field of the DT_MACHINE
structure:
> Can also be used within code to test the machine:Inside a bus, one typically needs to define the following properties:
> A compatible property, which identifies the bus controller (in
case of I2C, SPI, PCI, etc.). A special value
compatible = "simple-bus" means a simple
memory-mapped bus with no specific handling or driver. Child
nodes will be registered as platform devices.
> The #address-cells property indicate how many cells (i.e
32 bits values) are needed to form the base address part in the
reg property.
> The #size-cells is the same, for the size part of the reg
property.
> The ranges property can describe an address translation
between the child bus and the parent bus. When simply
defined as ranges;, it means that the translation is an
identity translation.>» interrupt-controller; is a boolean property that
indicates that the current node is an interrupt controller.
> #interrupt-cells indicates the number of cells in the
interrupts property for the interrupts managed by the
selected interrupt controller.
>» interrupt-parent is a phandle that points to the interrupt
controller for the current node. There is generally a top-level
interrupt-parent definition for the main interrupt
controller.wm8903@la
wLf,wn8903,
2c bus
i2c@70e0ce00
<——
interrupt-parent =
interrupts =
nvidia, tegra20-i2e inte
arm, cortex-a9-gic
io
> ‘OP:
interrupt-parent = ;
interrupts = ;
nvidia, tegra20-gpio
Anterrupt-parent = <6inte>;
interrupts = ,
;
Tegra 20 SoC arch/arm/boot/dts/tegra28.dtsi
Tegra 20 Harmony board
arch/arn/boot/dts/tegra20-harmony.dtsThe Device Tree is really a hardware description language.
v
v
It should describe the hardware layout, and how it works.
v
But it should not describe which particular hardware
configuration you're interested in.
> As an example:
> You may describe in the DT whether a particular piece of
hardware supports DMA or not.
> But you may not describe in the DT if you want to use DMA
or not.» Since the DT is OS independent, it should also be stable.
> The original idea is that DTBs can be flashed on some devices
by the manufacturer, so that the user can install whichever
operating system (s)he wants.
» Once a Device Tree binding is defined, and used in DTBs, it
should no longer be changed anymore. It can only be
extended.
> This normally means that Device Tree bindings become
part of the kernel ABI, and it should be handled with the
same care.
> However, kernel developers are realizing that this is really hard
to achieve and slowing down the integration of drivers.
>» The ARM Kernel Mini-summit discussions have relaxed those
rules
> There will be additional discussions during the Kernel Summit,
with final conclusions published afterwards> A precise compatible string is better than a vague one
> You have a driver that covers both variants T320 and T330 of
your hardware. You may be tempted to use foo, t3xx as your
compatible string.
> Bad idea: what if T340 is slightly different, in an incompatible
way? You'd better use foo, t320 for both T320 and T330
> Do not encode too much hardware details in the DT
> When two hardware variants are quite similar, some developers
are tempted to encode all the differences in the DT, including
register offsets, bit masks or offsets.
» Bad idea: it makes the binding more complex, and therefore
less resilient to future changes. Instead, use two different
compatible strings and handle the differences in the driver.>» Dynamic Device Tree, with the principle of overlay. Partially
merged in 3.19.
> A tool to validate DTS against bindings
> Currently, the DT compiler only makes syntax checks, no
conformance checks against bindings.
> Proposal from Benoit Cousson and Fabien Parent, also from
Tomasz Figa.
> No progress since several months.
> Take out the Device Tree source files from the kernel
tree
> DTs are OS independent, so they can be used for other
purposes than just Linux. They are already used by Barebox or
U-Boot:
> Having them outside of the kernel reduces the amount of
churn in the kernel source.
> But is IMO likely to cause a huge number of compatibility
issues> Power.orgTM Standard for Embedded Power Architecture
Platform Requirements (ePAPR), http://www. power.org/
resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf
> DeviceTree.org website, http: //www.devicetree.org
» Device Tree documentation in the kernel sources,
Documentation/devicetree
> The Device Tree kernel mailing list, http:
//dir.gmane.org/gmane.1linux.drivers.devicetreeQuestions?
Thomas Petazzoni
thomas. [email protected]
Slides under CC-BY-SA 3.0
http: //free-electrons.com/pub/conferences/2014/e1c/petazzoni-device-
tree-dummies/Backup slidesPartial and approximate
clock tree of Marvell Armada XP
Internal bus clock
Mv 78460
Eth 1 clock
CPU clock
Us80
USB 0 clock > controller
nb clock CPU clocks
>| cPuo clock
DRAM control clock
>| cpur clock
DDR clock
Core clocks L—>} cruz ctock
>| cevo
Lf CPUS clock
Ref clock
TimerCPU, using a cpuclk
Timer, using either a coreclk or refclk
USB, using a gateclk> The pinctrl subsystem allows to manage pin muxing.
> In the Device Tree, devices that need pins to be muxed in a
certain way must declare the pinctr! configuration they need.
>» The pinctr1- properties allow to give the list of pinctrl
configuration needed for a certain state of the device.
>» The pinctrl-names property allows to give a name to each
state.
>» When a device is probed, its default pinctrl state is
requested automatically.> A pinctrl configuration provides a list of pins and their
configuration.
» Such configurations are defined as sub-nodes of the pinctrl
device, either at the SoC-level, or board-level.
> The binding for such configurations is highly dependent on
the specific pinctrl driver being used.
i.MX28
Marvell Kirkwood