Difference between revisions of "How to create your board device tree"

[checked revision] [quality revision]
m (Article purpose)


1 Article purpose[edit]

This article is a guideline to create a first TF-A device tree for your board with STM32CubeMX and compile it with OpenSTLinux Distribution Package. Thanks to follow those Thank you for following the three links given previously to be familiar with those elements before digging into the steps below.

Info white.png Information
The strategy developed in this article consists in starting your board configuration from a virgin STM32MP1 series device chosen via STM32CubeMX MCU selector. Thanks Thank you to follow this guideline and avoid starting from a an ST board, because an incremental approach is less risky and so, preferred here.

2 TF-A setup to get 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 for various PLL (USB, DDR).
  • UARTx: setup the serial console.
    • Assign UARTx to the "Cortex-A7 non-secure" and the "Boot loader" contexts
    • Select the "Asynchronous" mode
    • In the "pinout view", change the RX and TX lines if STM32CubeMX default choices are not maching with your board.
    • Notice that UARTx instance is gotten from the device tree for the console but it is hard coded hardcoded to UART4 with TX on GPIOG11 for the crash console, in plat/st/stm32mp1/stm32mp1_def.h.
  • USB OTG: setup the serial boot interface.
    • Assign USB OTG to the "Cortex-A7 non-secure", the "Boot loader" and "Boot ROM" contexts.
    • Select the "High speed OTG/Dual_Role_Device".

- In Clock configuration:

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

- GENERATE CODE then:

Info white.png Information
At this step, you can ignore the "Warning: DDR not configured" because this is the purpose of the next chapter in this article
  • Complete "USER CODE BEGIN root" with "chosen" and "aliases" nodes, taking ST boards values as example (like fdts/stm32mp157a-dk1.dts ).


2.2 In 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 (i.e. minicom)

  • The freshly built TF-A should allow to boot in serial mode and you should observe "Cannot read DDR node in DT" error in the serial console: that is fine at this stage !

3 PMIC configuration via I2C[edit]

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

3.1 In STM32CubeMX[edit]

- In Pinout & Configuration:

  • I2Cx: setup 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 are not maching with your board.

- In Clock configuration:

  • Check that I2Cx source clock corresponds to your wish 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 regulators list of one of the ST boards device tree (like fdts/stm32mp157a-dk1.dts ) and adapt 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 one freshly updated.
- Compile TF-A to take those new files into account.
- Start the board with STM32CubeProgrammer connected via USB OTG and a terminal on UARTx (i.e. 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 to boot in serial mode and the "PMIC version" should now be displayed in the log, 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, that has to be run instead of TF-A. If your board is compatible with ST boards (UARTx = UART4, I2Cx = I2C4, PMIC using and HSE digital bypass), then you can directly use U-Boot SPL binary from a ST delivery. Otherwise, you need to build a U-Boot SPL binary with a configuration in line 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 line with 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 one freshly updated.
- Compile TF-A to take those new files into account.
- Start the board with STM32CubeProgrammer connected via USB OTG and a terminal on UARTx (i.e. minicom)

  • The DDR will properly be initialized now then TF-A will load U-Boot in DDR and the execution should fail just after "Booting BL32" notice, because states definitions are missing in the device tree (in pwr node overlay).
<noinclude>

[[Category:How to customize software]]</noinclude>


==Article purpose==
This article is a guideline to create a first [[TF-A overview|TF-A]] device tree for your board with [[STM32CubeMX]] and compile it with [[STM32MP1 Distribution Package|OpenSTLinux Distribution Package]]. Thanks to follow those three links Thank you for following the three links given previously to be familiar with those elements before digging into the steps below.
{{Info | The strategy developed in this article consists in starting your board configuration from a virgin STM32MP1 series device chosen via STM32CubeMX '''MCU selector'''. Thanks Thank you to follow this guideline and avoid starting from aan ST board, because an incremental approach is less risky and so, preferred here.}}

== TF-A setup to get the serial log on UART and USB boot ==
=== In STM32CubeMX ===
- Create a new project with the '''MCU selector''', selecting the [[STM32MP15_microprocessor#Part_number_codification|STM32MP1 part number]] that is mounted on your board.<br>


- In '''Pinout & Configuration''':
* '''RCC''': enable the HSE clock source according to your board setup. The HSE is needed for various PLL (USB, DDR).
* '''UARTx''': setup the serial console.
** Assign UARTx to the "Cortex-A7 non-secure" and the "Boot loader" contexts
** Select the "Asynchronous" mode
** In the "pinout view", change the RX and TX lines if STM32CubeMX default choices are not maching with your board.
** Notice that UARTx instance is gotten from the device tree for the console but it is hard coded hardcoded to UART4 with TX on GPIOG11 for the crash console, in plat/st/stm32mp1/stm32mp1_def.h.
* '''USB OTG''': setup the serial boot interface.
** Assign USB OTG to the "Cortex-A7 non-secure", the "Boot loader" and "Boot ROM" contexts.
** Select the "High speed OTG/Dual_Role_Device".

- In '''Clock configuration''':
* Adjust the HSE frequency, if needed.
* Check that UARTx source clock corresponds to your wish or select HSI by default.
* Configure the USBPHYC clock mux, to get an input clock for the PLL USBPHY that is one of the valid values showedshown in the clock configuration panel.

- '''GENERATE CODE''' then:
{{Info | At this step, you can ignore the "Warning: DDR not configured" because this is the purpose of the next chapter in this article}}
* Complete "USER CODE BEGIN root" with "chosen" and "aliases" nodes, taking ST boards values as example (like {{CodeSource | TF-A | fdts/stm32mp157a-dk1.dts}}).
{{InternalInfo|Ticket 70719 workaround : remove &usbphyc, &usbphyc_port0 and &usbphyc_port1 nodes}}

=== In OpenSTLinux Distribution Package ===
- Follow [[How to create your own machine]] to '''define your own machine''' and '''compile''' it with the device tree generated in the previous paragraph.<br>

- Select the [[STM32MP15_ROM_code_overview#Boot_device_selection_via_the_boot_pins_and_OTP|serial boot]] on your board<br>

- '''Start''' the board with [[STM32CubeProgrammer]] connected via USB OTG and a terminal on UARTx (i.e. minicom)
* The freshly built TF-A should allow to boot in serial mode and you should observe "Cannot read DDR node in DT" error in the serial console: that is fine at this stage !

== PMIC configuration via I2C ==
This part explains how to configure the I2Cx to which [[PMIC_hardware_components#STPMIC1|STPMIC1]] is connected, in case your board is supplied via this PMIC, used also on [[:Category:Getting_started_with_STM32MP1_boards|ST boards]]. In case of discrete power supply, this part has to be adapted, according to your board implementation.

=== In STM32CubeMX ===
- In '''Pinout & Configuration''':
* '''I2Cx''': setup 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 are not maching with your board.

- In '''Clock configuration''':
* Check that '''I2Cx source clock''' corresponds to your wish 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 regulators list of one of the ST boards device tree (like {{CodeSource | TF-A | fdts/stm32mp157a-dk1.dts}}) and adapt 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>;
     };
 };
{{InternalInfo|Ticket 70719 workaround : remove &usbphyc, &usbphyc_port0 and &usbphyc_port1 nodes}}

=== In OpenSTLinux Distribution Package ===
- '''Replace''' the initial STM32CubeMX generated files in your own Yocto machine (layers/meta-st/meta-st-stm32mp-addons/mx/<your project>), with the one freshly updated.<br>

- '''Compile''' TF-A to take those new files into account.<br>

- '''Start''' the board with [[STM32CubeProgrammer]] connected via USB OTG and a terminal on UARTx (i.e. 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 to boot in serial mode and the "PMIC version" should now be displayed in the log, still ending with "Cannot read DDR node in DT".

== DDR configuration with STM32CubeMX DDR Tuning Tool ==
=== In STM32CubeMX ===
- '''Prerequisite''': the DDR tuning tool interacts with the target via [[U-Boot_overview#SPL:_FSBL_for_basic_boot|U-Boot SPL]], that has to be run instead of TF-A. If your board is compatible with ST boards (UARTx = UART4, I2Cx = I2C4, PMIC using and HSE digital bypass), then you can directly use U-Boot SPL binary from a ST delivery. Otherwise, you need to build a U-Boot SPL binary with a configuration in line 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 {{Highlight|basic}}"

- In '''Pinout & Configuration''':
* '''DDR''': enable "DDR3 / DDR3L" then select the right "Width" and "Density", in line with 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'''
{{InternalInfo|Ticket 70719 workaround : remove &usbphyc, &usbphyc_port0 and &usbphyc_port1 nodes}}

=== In OpenSTLinux Distribution Package ===
- '''Replace''' the STM32CubeMX generated files in your own Yocto machine (layers/meta-st/meta-st-stm32mp-addons/mx/<your project>), with the one freshly updated.<br>

- '''Compile''' TF-A to take those new files into account.<br>

- '''Start''' the board with [[STM32CubeProgrammer]] connected via USB OTG and a terminal on UARTx (i.e. minicom)
* The DDR will properly be initialized now then TF-A will load U-Boot in DDR and the execution should fail just after "Booting BL32" notice, because states definitions are missing in the device tree (in pwr node overlay).
Line 4: Line 4:
   
 
==Article purpose==
 
==Article purpose==
This article is a guideline to create a first [[TF-A overview|TF-A]] device tree for your board with [[STM32CubeMX]] and compile it with [[STM32MP1 Distribution Package|OpenSTLinux Distribution Package]]. Thanks to follow those three links to be familiar with those elements before digging into the steps below.
+
This article is a guideline to create a first [[TF-A overview|TF-A]] device tree for your board with [[STM32CubeMX]] and compile it with [[STM32MP1 Distribution Package|OpenSTLinux Distribution Package]]. Thank you for following the three links given previously to be familiar with those elements before digging into the steps below.
{{Info | The strategy developed in this article consists in starting your board configuration from a virgin STM32MP1 series device chosen via STM32CubeMX '''MCU selector'''. Thanks to follow this guideline and avoid starting from a ST board, because an incremental approach is less risky and so, preferred here.}}
+
{{Info | The strategy developed in this article consists in starting your board configuration from a virgin STM32MP1 series device chosen via STM32CubeMX '''MCU selector'''. Thank you to follow this guideline and avoid starting from an ST board, because an incremental approach is less risky and so, preferred here.}}
   
 
== TF-A setup to get the serial log on UART and USB boot ==
 
== TF-A setup to get the serial log on UART and USB boot ==
Line 17: Line 17:
 
** Select the "Asynchronous" mode
 
** Select the "Asynchronous" mode
 
** In the "pinout view", change the RX and TX lines if STM32CubeMX default choices are not maching with your board.
 
** In the "pinout view", change the RX and TX lines if STM32CubeMX default choices are not maching with your board.
** Notice that UARTx instance is gotten from the device tree for the console but it is hard coded to UART4 with TX on GPIOG11 for the crash console, in plat/st/stm32mp1/stm32mp1_def.h.
+
** Notice that UARTx instance is gotten from the device tree for the console but it is hardcoded to UART4 with TX on GPIOG11 for the crash console, in plat/st/stm32mp1/stm32mp1_def.h.
 
* '''USB OTG''': setup the serial boot interface.
 
* '''USB OTG''': setup the serial boot interface.
 
** Assign USB OTG to the "Cortex-A7 non-secure", the "Boot loader" and "Boot ROM" contexts.
 
** Assign USB OTG to the "Cortex-A7 non-secure", the "Boot loader" and "Boot ROM" contexts.
Line 25: Line 25:
 
* Adjust the HSE frequency, if needed.
 
* Adjust the HSE frequency, if needed.
 
* Check that UARTx source clock corresponds to your wish or select HSI by default.
 
* Check that UARTx source clock corresponds to your wish or select HSI by default.
* Configure the USBPHYC clock mux, to get an input clock for the PLL USBPHY that is one of the valid values showed in the clock configuration panel.
+
* Configure the USBPHYC clock mux, to get an input clock for the PLL USBPHY that is one of the valid values shown in the clock configuration panel.
   
 
- '''GENERATE CODE''' then:
 
- '''GENERATE CODE''' then:
Line 39: Line 39:
   
 
== PMIC configuration via I2C ==
 
== PMIC configuration via I2C ==
This part explains how to configure the I2Cx to which [[PMIC_hardware_components#STPMIC1|STPMIC1]] is connected, in case your board is supplied via this PMIC, used on [[:Category:Getting_started_with_STM32MP1_boards|ST boards]]. In case of discrete power supply, this part has to be adapted, according to your board implementation.
+
This part explains how to configure the I2Cx to which [[PMIC_hardware_components#STPMIC1|STPMIC1]] is connected, in case your board is supplied via this PMIC, used also on [[:Category:Getting_started_with_STM32MP1_boards|ST boards]]. In case of discrete power supply, this part has to be adapted, according to your board implementation.
   
 
=== In STM32CubeMX ===
 
=== In STM32CubeMX ===