- Device Tree Tips
- 1 Documentation
- 2 Device Tree Bindings
- 3 Zynq UltraScale+ MPSOC Memory Nodes
- 4 Clocks
- 4.1 Linux Disables Clocks
- 4.2 References to Clocks In Nodes
- 4.2.1 Device Driver Example
- 4.3 Clock Status At Runtime
- 4.4 Creating A Clock
- 5 Disabling A Device Node
- 6 Fixing A Broken Node
- 7 Interrupt Inputs Using GPIO
- 8 Using UIO
- 8.1 Kernel Bootargs
- 9 How to add or delete nodes and properties in PetaLinux
- 9.1 Adding a New Node or Update existing nodes
- 9.2 Deleting a Node or Properties of existing nodes
- 9.3 Adding a New Node or Update existing Device-tree Overlay nodes
- 9.4 Deleting a Node or Properties of existing Device-tree Overlay nodes
- Clock device tree configuration — Bootloader specific
- Contents
- 1 Article purpose [ edit ]
- 2 DT bindings documentation [ edit ]
- 3 DT configuration [ edit ]
- 3.1 DT configuration (STM32 level) [ edit ]
- 3.2 DT configuration (board level) [ edit ]
- 3.2.1 Clock node [ edit ]
- 3.2.2 STM32MP1 clock node [ edit ]
- 4 How to configure the DT using STM32CubeMX [ edit ]
- 5 References [ edit ]
Device Tree Tips
This page is intended to be a collection place for tips and tricks related to device trees.
1 Documentation
This is the first place you should start to better understand many details of device trees. Many thanks to Free Electrons for their work on this.
There are now many other good sites to help with links at the end of the page.
2 Device Tree Bindings
The Linux kernel Documentation directory contains device tree bindings for many devices such that it is the area to consider. Not all Xilinx devices are documented but many are and there is an effort to document them all.
3 Zynq UltraScale+ MPSOC Memory Nodes
Zynq UltraScale+ MPSOC is ARM64 such that memory addresses in the device tree memory node utilize 64 bits. There is also an address gap such that not all of the DDR is contiguous in the address map. These both affect the reg property for the memory node and are worthy of explanation.
The following device tree properties control the size of the address and size cells for any reg properties which follow them. Note that each cell is by default 32 bits such that a 64 bit value requires a value of 2 for the numbers of cells.
The following memory node illustrated two address ranges for the memory with the 1st starting at address 0 and the 2nd starting at address 0x800000000 with both memory ranges having a size of 2 GB each.
In 2018.x release onward DTG reserves 1MB for PMU on lower DDR memory range which is auto generated and this takes care by PCW.
4 Clocks
4.1 Linux Disables Clocks
By default Linux disables clocks which have no reference in the device tree (no nodes using the clock). This can create issues in an AMP design where Linux is running on one CPU and another non-Linux based design is running on the other CPU. When the non-Linux CPU software is trying to use devices that are not in the device tree the clock will be disabled such that the device is not accessible.
The text «clk_ignore_unused» can be added to the kernel command line and it will not disable unused clocks. This was tested for a 3.17 Linux kernel (Xilinx 2014.4 release). This topic is discussed in the following forum thread. This option is also documented in the kernel clock documentation referenced at the end of the page .
4.2 References to Clocks In Nodes
The SLCR node of the device tree contains a clkc subnode which is used by the Zynq clock driver. The clkc node (as illustated below) contains a list of the clocks in the clock-output-names property.
Other nodes in the device tree reference the clocks in the clkc node to indicate that the node uses the clock. The following property illustrates an example clock property.
The &clkc is a reference to the clkc node which contains the clock-output-names. The 15 is a zero based index into the clock-output-names such that it refers to fclk0.
4.2.1 Device Driver Example
The following code illustrates an example of a Linux device driver using the clocks property of a device tree node. The snippet of code was taken from the probe function. When the clocks property is not found the driver exits and does not probe successfully. This failure may be silent or may have console output which may not be explicit that the clock property was the issue.
4.3 Clock Status At Runtime
The clocks of the system can be viewed in the filesystem at /sys/kernel/debug/clk with clk_summary showing all the clocks. The debug filesystem must be turned on in the kernel configuration for this feature to be used. The following configuration path allows the debug filesystem to be turned on.
Kernel hacking -> Compile-time checks and compiler options -> Debug Filesystem (CONFIG_DEBUG_FS)
The following example illustrates the clock summary at runtime. When the enable count is zero the clock is disabled. For more details see the link for the kernel clock documentation at the end of the page.
4.4 Creating A Clock
Some devices in the device tree may require clock nodes to describe their clock inputs. For fixed clocks this is easily done as illustrated below.
The clock can be referenced in another node as illustrated below.
5 Disabling A Device Node
There are times when a device in the device tree, a node, is not wanted in the system. The status property of a node can be used to disable it. This property may not be present on all nodes by default, but can be added.
6 Fixing A Broken Node
There may be node that has a property which only has to exist, with no specific value (such as xlnx,tx_termination_fix), and the driver just checks for it’s existence in the device tree. There is no easy way to get rid of the property in an existing node but you can create a new node with a new name which does not have that property. Any references to the old node will need to change to the new node.
7 Interrupt Inputs Using GPIO
Interrupts can be connected direct to an interrupt controller or they can be connected to a GPIO input that can generate an interrupt. The following device tree illustrates the changes required to support this feature. It adds interrupt controller ability to the existing GPIO node and then indicates in the SPI device node that the GPIO node is the interrupt controller.
The interrupts property on the SPI device node uses the same interrupt type (edge, level, etc. ) as when connected to an interrupt controller. The interrupt number in the interrupts property is the GPIO pin number on the GPIO controller. For example, on Zynq with the PS GPIO using an MIO for the interrupt, the interrupt number starts at 0 which corresponds to GPIO pin 0 and MIO0. This GPIO pin number is not the same as the GPIO pin numbers see in /sys/class/gpio as those seem to be a virtualized pin number and can be a bigger number as the base.
The interrupt should be seen in /proc/interrupts and it should should show the GPIO node as the interrupt controller.
Note: This feature has less testing and early testing with a 3.19 kernel has shown there are GPIO driver issues related to clocking when using an interrupt that is active high level triggered. There should be a commit to alter Zynq GPIO coming in future to fix the issue.
8 Using UIO
Typically a node is added to the device tree or an existing node is used for the UIO framework/driver. The node compatible property could be any desired string but «generic-uio» is typically used. The key is that the bootargs of the kernel must be altered as described below to match this string.
8.1 Kernel Bootargs
After adding the «compatible = generic-uio» to the device tree node as described above, the boot args of the kernel must be altered to allow the UIO device driver to be compatible with the device tree node.
Add «uio_pdrv_genirq.of_id=generic-uio» to the bootargs of the kernel in the device tree. This string is altering the module parameter of_id for the uio_pdrv_genirq device driver so that when it’s built into the kernel (rather than a module) it will be compatible with the device tree node. If the driver is inserted as a module the user could also specify the module parameter at the time of insertion into the kernel.
9 How to add or delete nodes and properties in PetaLinux
9.1 Adding a New Node or Update existing nodes
New nodes in the device tree should be added near the top of
/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi between the first pair of brackets «<>» as illustrated below.
9.2 Deleting a Node or Properties of existing nodes
Delete nodes or properties in the device tree should be added near the top of
/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi between the first pair of brackets «<>» as illustrated below.
9.3 Adding a New Node or Update existing Device-tree Overlay nodes
New nodes in the device tree overlay should be added near the top of
/project-spec/meta-user/recipes-bsp/device-tree/files/pl-custom.dtsi between the first pair of brackets «/<>» as illustrated below.
9.4 Deleting a Node or Properties of existing Device-tree Overlay nodes
Delete nodes or properties in the device tree should be added near the top of
Источник
Clock device tree configuration — Bootloader specific
Expert | Aproved |
Technical writer | Approved |
Maintainer | Approved |
Contents
1 Article purpose [ edit ]
This article describes the specific RCC internal peripheral configuration done by the first stage bootloader:
Regarding OP-TEE when it is embedded in the device, OP-TEE OS is booted by TF-A BL2 , it is booted by TF-A BL2 bootstage. OP-TEE relies on TF-A BL2 bootstage for the RCC clock tree initial configuration. This article explicitily mentions OP-TEE when in information applies to OP-TEE secure world configuration.
This article explains how to configure the clock tree in the RCC at boot time. You can then refer to the clock device tree configuration article to understand how to derive each internal peripheral clock tree in Linux ® OS from the RCC clock tree. |
The configuration is performed using the device tree mechanism that provides a hardware description of the RCC peripheral.
This clock tree is only used in the device tree of the boot chain FSBL ; so in the TF-A device tree for OpenSTLinux official delivery (or in SPL only for the DDR tuning tool).
Even if the clock tree information is also present in the U-Boot device tree, it is not used during boot by this SSBL .
2 DT bindings documentation [ edit ]
The bootloader clock device tree bindings correspond to the vendor clock DT bindings used by the clk-stm32mp1 driver of the FSBL (TF-A or U-Boot SPL for DDR interactive mode), it is based on:
This binding document explains how to write the device tree files for clocks on the bootloader side:
3 DT configuration [ edit ]
This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device tree file split.
STM32CubeMX can be used to generate the board device tree. Refer to How to configure the DT using STM32CubeMX for more details.
3.1 DT configuration (STM32 level) [ edit ]
The STM32MP1 clock nodes are located in stm32mp151.dtsi [3] (see Device tree for more explanations):
- fixed-clock defined in clock node
- RCC node for #STM32MP1 clock node: clock generation and distribution.
Please refer to clock device tree configuration for the bindings common with Linux ® kernel.
3.2 DT configuration (board level) [ edit ]
3.2.1 Clock node [ edit ]
Note: this section applies to OP-TEE that gets input clocks frequency value from the device tree description it boots upon.
The clock tree is also based on five fixed clocks in the clock node. They are used to define the state of associated STM32MP1 oscillators:
Please refer to clock device tree configuration for detailed information.
At boot time, the clock tree initialization performs the following tasks:
- enabling of the oscillators present in the device tree and not disabled (node with status=»disabled»),
- disabling of the HSI oscillator if the node is absent or disabled ( HSI is always activated by the ROM code).
3.2.1.1 Optional properties for «clk-lse» and «clk-hse» external oscillators [ edit ]
For external oscillator HSE and LSE , the default clock configuration is an external crystal/ceramic resonator.
Four optional fields are supported:
- «st,bypass» configures the external analog clock source (set HSEBYP, LSEBYP),
- «st,digbypass» configures the external digital clock source (set DIGBYP and HSEBYP, LSEBYP),
- «st,css» activates the clock security system (HSECSSON, LSECSSON),
- «st,drive» ( LSE only) contains the value of the drive for the oscillator (see LSEDRV_ defined in the file stm32mp1-clksrc.h[4] ).
3.2.1.2 DT configuration for HSE [ edit ]
The HSE can accept an external crystal/ceramic or external clock source on OSC_IN, digital or analog : the user needs to select the correct frequency and the correct configuration in the device tree, corresponding to the hardware setup.
All the ST boards are using a digital external clock configuration (so device tree with = st,digbypass).
For example with the same 24MHz frequency, we have 3 configurations:
- Digital external clock = st,digbypass
- Analog external clock = st,bypass
- Crystal/ ceramic resonators configuration
3.2.1.3 DT configuration for LSE [ edit ]
Below an example of LSE on board file with 32,768kHz crystal resonators, the drive set to medium high and with activated clock security system.
3.2.1.4 Optional property for «clk-hsi» internal oscillator [ edit ]
The HSI clock frequency is internally fixed to 64 MHz for the STM32MP15 devices.
In the device tree, clk-hsi is the clock after HSIDIV divider (more information on clk_hsi can be found in the RCC chapter in the reference manual).
As a result the frequency of this fixed clock is used to compute the expected HSIDIV for the clock tree initialization.
Below an example with HSIDIV = 1/1:
Below an example with HSIDIV = 1/2:
3.2.1.5 Clock node example [ edit ]
Note: this section applies to OP-TEE OS clock drivers.
An example of clocks node with:
- all oscillators switched on ( HSE , HSI , LSE , LSI , CSI )
- HSI at 64MHZ (HSIDIV = 1/1)
- HSE using a digital external clock at 24MHz
- LSE using an external crystal at 32.768kHz (the typical frequency)
We highlight the customized parts:
So the resulting board device tree, based on SoC device tree «stm32mp151.dtsi», is :
It is the configuration used by TF-A for STM32MP15 boards.
3.2.2 STM32MP1 clock node [ edit ]
Please refer to clock device tree configuration for information on how to specify the number of cells in a clock specifier.
The bootloader performs a global clock initialization, as described below. The information related to a given board can be found in the board specific device tree files listed in clock node.
The bootloader uses other properties for RCC node («st,stm32mp1-rcc» compatible):
- secure-status: related to TZEN bit configuration in RCC security register that allows to restrict RCC and PWR registers write access
- st,clksrc: clock source configuration array
- st,clkdiv: clock divider configuration array
- st,pll: specific PLL configuration
- st,pkcs: peripheral kernel clock distribution configuration array.
All the available clocks are defined as preprocessor macros in stm32mp1-clks.h [5] and can be used in device tree sources.
Note: this section partially applies to OP-TEE OS clock drivers in that OP-TEE OS clock drivers consider only property secure-status over those listed above.
3.2.2.1 Defining clock source distribution with st,clksrc property [ edit ]
This property can be used to configure the clock distribution tree. When used, it must describe the whole distribution tree.
There are nine clock source selectors for the STM32MP15 devices. They must be configured in the following order: MPU , AXI, MCU , PLL12, PLL3, PLL4, RTC , MCO1, and MCO2.
The clock source configuration values are defined by the CLK_ _ macros located in stm32mp1-clksrc.h [4] .
3.2.2.2 Defining clock dividers with st,clkdiv property [ edit ]
This property can be used to configure the value of the clock main dividers. When used, it must describe the whole clock divider tree.
There are 11 dividers values for the STM32MP15 devices. They must be configured in the following order: MPU , AXI, MCU , APB1, APB2, APB3, APB4, APB5, RTC , MCO1 and MCO2.
Each divider value uses the DIV coding defined in the RCC associated register, RCC _xxxDIVR. In most cases, this value is the following:
- 0x0: not divided
- 0x1: division by 2
- 0x2: division by 4
- 0x3: division by 8
- .
Note that the coding differs for RTC MCO1 and MCO2:
- 0x0: not divided
- 0x1: division by 2
- 0x2: division by 3
- 0x3: division by 4
- .
3.2.2.3 Defining peripheral PLL frequencies with st,pll property [ edit ]
This property can be used to configure PLL frequencies.
The PLL children nodes for PLL1 to PLL4 (see reference manual for details) are associated with an index from 0 to 3 (st,pll@0 to st,pll@3).
PLL2, PLL3 or PLL4 are off when their associated nodes are absent or deactivated.
The configuration of PLL1, the source clock of Cortex -A7 core, with st,pll@0 node, is optional as TF-A automatically selects the most suitable operating point for the platform (please refer to How to change the CPU frequency). The node st,pll@0 node should be absent; it is only used if you want to override the PLL1 properties computed by TF-A (clock spreading for example).
Below the available properties for each PLL node:
- cfg contains the PLL configuration parameters in the following order: DIVM, DIVN, DIVP, DIVQ, DIVR, output.
DIVx values are defined as in RCC:
- 0x0: bypass (division by 1)
- 0x1: division by 2
- 0x2: division by 3
- 0x3: division by 4
- .
Output contains a bitfield for each output value (1:ON / 0:OFF)
- BIT(0) → output P : DIVPEN
- BIT(1) → output Q : DIVQEN
- BIT(2) → output R : DIVREN
Note: PQR(p,q,r) macro can be used to build this value with p, q, r = 0 or 1.
- frac: fractional part of the multiplication factor (optional, when absent PLL is in integer mode).
- csg contains the clock spreading generator parameters (optional) in the following order: MOD_PER, INC_STEP and SSCG_MODE.
MOD_PER: modulation period adjustment INC_STEP: modulation depth adjustment SSCG_MODE: Spread spectrum clock generator mode, defined in stm32mp1-clksrc.h[4] :
- SSCG_MODE_CENTER_SPREAD = 0
- SSCG_MODE_DOWN_SPREAD = 1
3.2.2.4 Defining peripheral kernel clock tree distribution with st,pkcs property [ edit ]
This property can be used to configure the peripheral kernel clock selection.
It is a list of peripheral kernel clock source identifiers defined by the CLK_ _
macros in the stm32mp1-clksrc.h [4] header file.
st,pkcs may not list all the kernel clocks. No specific order is required.
3.2.2.5 HSI and CSI clocks calibration [ edit ]
Note: this section applies to OP-TEE OS clock calibration support.
The calibration is an optional feature that can be enabled from the device tree. It allows requesting the HSI or CSI clock calibration by several means:
- SiP SMC service
- Periodic calibration every X seconds
- Interrupt raised by the MCU
This feature requires that a hardware timer is assigned to the calibration sequence.
A dedicated interrupt must be defined using «mcu_sev» name to start a calibration on detection of an interrupt raised by the MCU .
- st,hsi-cal: used to enable HSI clock calibration feature.
- st,csi-cal; used to enable CSI clock calibration feature.
- st,cal-sec: used to enable periodic calibration at specified time intervals from the secure monitor. The time interval must be given in seconds. If not specified, a calibration is only processed for each incoming request.
4 How to configure the DT using STM32CubeMX [ edit ]
The STM32CubeMX tool can be used to configure the STM32MPU device and get the corresponding platform configuration device tree files.
The STM32CubeMX may not support all the properties described in the above DT bindings documentation paragraph.
If so, the tool inserts user sections in the generated device tree.
These sections can then be edited to add some properties and they are preserved from one generation to another.
Refer to STM32CubeMX user manual for further information.
5 References [ edit ]
Please refer to the following links for additional information:
Источник