How to create your board device tree


1 Article purpose[edit]

This article gives guidelines for the creation of an initial TF-A device tree for your board using STM32CubeMX, and its compilation with OpenSTLinux Distribution Package. We recommend that you follow the three elements linked above to gain familiarity before embarking on the steps below.

Info.png The strategy developed in this article consists of starting your board configuration from a virgin STM32MP1 Series device, chosen via STM32CubeMX MCU selector. When using these guidelines it is preferable to avoid starting with an ST board, as an incremental approach reduces the risk of potential issues.

2 TF-A setup to enable the serial log on UART and USB boot[edit]

2.1 In STM32CubeMX[edit]

Create a new project with the MCU selector, selecting the STM32MP1 part number that is mounted on your board.

In Pinout & Configuration:

  • RCC: enable the HSE clock source according to your board setup. The HSE is needed by various PLLs (USB, DDR).
  • UARTx: set up the serial console:
    • Assign UARTx to the "Cortex-A7 non-secure" and the "Boot loader" contexts
    • Select "Asynchronous" mode
    • In the "pinout view", change the RX and TX lines if the STM32CubeMX default choices do not match your board.
    • Notice that the UARTx instance is obtained from the device tree for the console, but is hard coded to UART4 with TX on GPIO G11 for the crash console, in plat/st/stm32mp1/stm32mp1_def.h
  • USB OTG: set up the serial boot interface:
    • Assign USB OTG to the "Cortex-A7 non-secure", "Boot loader", and "Boot ROM" contexts
    • Select the "High speed OTG/Dual_Role_Device".

In Clock configuration:

  • Adjust the HSE frequency, if necessary
  • Check that the UARTx source clock corresponds to your needs, or select HSI by default
  • Configure the USBPHYC clock mux, to select an input clock for the PLL USBPHY, choosing one of the valid values shown in the clock configuration panel.

GENERATE CODE then:

Info.png During this step, you can ignore the "Warning: DDR not configured" message, as this is dealt with in the next chapter in this article
  • Complete "USER CODE BEGIN root" with "chosen" and "aliases" nodes, taking ST board values as examples (for instance fdts/stm32mp157a-dk1.dts ).

2.2 In the OpenSTLinux Distribution Package[edit]

  • Follow How to create your own machine to define your own machine and compile it with the device tree generated in the previous paragraph.
  • Select the serial boot on your board
  • Start the board with STM32CubeProgrammer connected via USB OTG and a terminal on UARTx (for example minicom)
    • The freshly built TF-A should allow a boot in serial mode, and you should see the message: "Cannot read DDR node in DT" error in the serial console; this is normal at this stage!

3 PMIC configuration via I2C[edit]

This section explains how to configure the I2Cx to which the STPMIC1 is connected, if your board is supplied via this PMIC, and is also used on ST boards. In the case of a discrete power supply, this part has to be adapted according to your board implementation.

3.1 In STM32CubeMX[edit]

In Pinout & Configuration:

  • I2Cx: set up the control link for the PMIC.
    • Assign I2Cx to the "Cortex-A7 non-secure", the "Cortex-A7 secure" and the "Boot loader" contexts
    • Select "I2C" mode
    • In the "pinout view", change the SCL and SDA lines if STM32CubeMX default choices do not match your board.

In Clock configuration:

  • Check that I2Cx source clock corresponds to your requirement, or select HSI by default.

GENERATE CODE then:

  • Complete USER CODE BEGIN i2cx with:
    • "i2c-scl-rising-time-ns" and "i2c-scl-falling-time-ns" properties, computed according to your board characteristics.
    • "pmic" node and all its regulators. You can start from the regulator list of one of the ST board device trees (such as fdts/stm32mp157a-dk1.dts ) and adapt it according to your board implementation.
  • Complete USER CODE BEGIN addons with "pwr" overlay to specify vdd-supply from the PMIC:
&pwr {
    pwr-regulators {
    vdd-supply = <&vdd>;
    };
};

3.2 In OpenSTLinux Distribution Package[edit]

Replace the initial STM32CubeMX generated files in your own Yocto machine (layers/meta-st/meta-st-stm32mp-addons/mx/<your project>), with the freshly-updated one.
Compile TF-A to take the new files into account.
Start the board with STM32CubeProgrammer connected via USB OTG and a terminal on UARTx (for example minicom), using the flashlayout file generated by Yocto in your 'build-openstlinuxweston-stm32mp1-.../tmp-glibc/deploy/images/stm32mp1-.../flashlayout_st-image-weston' folder.

  • The freshly-built TF-A should allow a boot in serial mode, and the "PMIC version" should now be displayed in the log, in a message still ending with "Cannot read DDR node in DT".

4 DDR configuration with STM32CubeMX DDR Tuning Tool[edit]

4.1 In STM32CubeMX[edit]

Prerequisite: the DDR tuning tool interacts with the target via U-Boot SPL, which must be run instead of TF-A. If your board is compatible with ST boards (UARTx = UART4, I2Cx = I2C4, PMIC using and HSE digital bypass), you can directly use the U-Boot SPL binary from an ST delivery. Otherwise, must build a U-Boot SPL binary with a configuration aligned with your board: U-Boot SPL binary generation can be done from your Yocto machine adding the "basic" boot scheme in your machine conf file:

BOOTSCHEME_LABELS = "trusted basic"

In Pinout & Configuration:

  • DDR: enable "DDR3 / DDR3L" then select the right "Width" and "Density", in according to your board

In Clock configuration:

  • Scroll down to reach the PLL2R area where "DDRC clock" and "DDRPERFM clock" are visible.
  • Set the DDR expected frequency (533 MHz maximum) then press enter to launch the clock resolver.
  • When a solution is found, it is shown upper in the PLL2 area.

In Tools / DDR Test Suite:

  • Perform the DDR tuning then "Save tuning to configuration"

GENERATE CODE

4.2 In OpenSTLinux Distribution Package[edit]

Replace' the STM32CubeMX generated files in your own Yocto machine (layers/meta-st/meta-st-stm32mp-addons/mx/<your project>), with the freshly-updated one.
Compile TF-A to take the new files into account.
Start the board with STM32CubeProgrammer connected via USB OTG and a terminal on UARTx (for example minicom).

  • The DDR is now properly initialized, and TF-A loads U-Boot into DDR. The execution should fail just after the "Booting BL32" notice, because state definitions are missing in the device tree (in the pwr node overlay).


Attachments

Discussions