Last edited 5 years ago

U-Boot SPL: DDR interactive mode: Difference between revisions

imported>Frq07632
(Approved)
 
Registered User
mNo edit summary
 
(14 intermediate revisions by 4 users not shown)
Line 1: Line 1:
<noinclude>
In [[U-Boot_overview|U-Boot]], the U-Boot SPL can provide a debug console for DDR configuration.
{{ArticleMainWriter | PatrickD}}
{{ ArticleApprovedVersion | PatrickD| PatriceC, GeraldH, FredericL, NathalieS/Jean-ChristopheT | No previous approved version | AlainF - 23Jan'19 - 10418 | 25Jan'19}}
 
[[Category:U-Boot]]
</noinclude>
 
In [[U-Boot_overview|U-Boot]], the U-Boot SPL can provide a debug console for the DDR configuration.


It is the embedded part used by the [[STM32CubeMX|STM32CubeMX DDR tuning tools]].
It is the embedded part used by the [[STM32CubeMX|STM32CubeMX DDR tuning tools]].
Line 14: Line 7:
This mode is defined under the compilation flag CONFIG_STM32MP1_DDR_INTERACTIVE.
This mode is defined under the compilation flag CONFIG_STM32MP1_DDR_INTERACTIVE.


When this configuration flag is activated, to enter in interactive mode, you have 2 solutions:
When this configuration flag is activated, there are two ways to enter interactive mode:
# '''load SPL and key press the character 'd'''' (as DDR) in the console.<br/>Polling is done only during 200ms in boot sequence.<br/>So it is difficult manually and you should maintain the key "d" pressed during the SPL startup until the {{Highlight|DDR>}} prompt
# '''load SPL and key press the character 'd'''' (for DDR) in the console.<br/>Polling is only done during 200 ms of the boot sequence.<br/>It is therefore difficult to do manually and you should keep the key "d" pressed during the SPL startup until the {{Highlight|DDR>}} prompt
# '''compile to force DDR_INTERACTIVE mode''' by adding '''DDR_INTERACTIVE=1''' in make option<br/>then SPL automatically enters in DDR mode:
# '''compile to force DDR_INTERACTIVE mode''' by adding '''DDR_INTERACTIVE=1''' in the make option<br/>the SPL then automatically enters DDR mode:
   {{PC$}} DEVICE_TREE=<device tree name> DDR_INTERACTIVE=1 make
   {{PC$}} DEVICE_TREE=<device tree name> DDR_INTERACTIVE=1 make


when the DDR tool console is available you have the display after the SPL information banner:
When the DDR tool console is available, the following output is displayed after the SPL information banner:
   0:DDR_RESET
   0:DDR_RESET
   DDR>
   DDR>
 
Interactive mode uses the same UART as the SPL console, by default the STMicroelectronics boards use UART4 with Bps=115200 Bit=8 Parity=None Stop=1
The interactive mode uses the same UART that SPL console, by default the STMicroelectronics boards use UART4 with Bps=115200 Bit=8 Parity=None Stop=1


=== DDR steps ===
=== DDR steps ===


The DDR interactive mode uses some 5 steps to initialize the DDR controller and the PHY with parameters found in the device tree:
DDR interactive mode uses 5 steps to initialize the DDR controller and the PHY (including the "Mode Register" 0-3 sent to DDR during initialization) with parameters found in the device tree:


{| class="wikitable"
{| class="st-table"
|-
|-
! step !! name !! Description !! DDR CTL<br/>state  !! DDR PHY<br/>state !! DDR CTL<br/>registers !! DDR PHY<br/>registers
! step !! name !! Description !! DDR CTL<br/>state  !! DDR PHY<br/>state !! DDR CTL<br/>registers !! DDR PHY<br/>registers
Line 66: Line 58:
* print [{{Highlight|type}}|{{Highlight|reg}}]: dump register
* print [{{Highlight|type}}|{{Highlight|reg}}]: dump register
* edit: modifies register in the DDR controller and DDR PHY<br/>need to be done at the correct step, AFTER the initialization from the input parameters (values from device tree )
* edit: modifies register in the DDR controller and DDR PHY<br/>need to be done at the correct step, AFTER the initialization from the input parameters (values from device tree )
*** step 1 => CTRL register update allowed
::* {{Highlight|step 1}} => CTRL register update allowed
*** step 2 => PHY register update allowed
::* {{Highlight|step 2}} => PHY register update allowed
*** step 3 => DDR ready (only for dynamic register for controller and PHY)
::* {{Highlight|step 3}} => DDR ready (only for dynamic register for controller and PHY)
** edit [{{Highlight|type}}|{{Highlight|reg}}]: modifies value register in DDR controller or PHY
** edit [{{Highlight|type}}|{{Highlight|reg}}]: modifies value register in DDR controller or PHY
* step: manages the step
* step: manages the step
Line 90: Line 82:
   3:Display registers:
   3:Display registers:
   4:Bist config:[nbErr] [seed]
   4:Bist config:[nbErr] [seed]
The "param" command is a simple way to test the modified settings, as it modifies the input parameters ({{Highlight| 'param'}}  read from the device tree). It is recommanded to execute this command at {{Highlight|step 0}}. The modified values are applied at the correct [[#DDR steps]].
The "print" and "edit" commands directly access the CTRL and PHY registers, so the values can be overidden by the input parameters when the driver executes the intialization steps. These commands are used for detailed debug of the DDR initialization.


=== Examples ===
=== Examples ===
Line 122: Line 118:
=== DDR test ===
=== DDR test ===


To execute the DDR test you need to be in the step 'DDR ready' (= step 3).
To execute the DDR test you need to be in the 'DDR ready' step (step 3).


To have the list of the test, execute the command 'test' without parameter:
To generate the list of tests, execute the 'test' command  without any parameters:


   DDR>step 3
   DDR>step 3
Line 150: Line 146:
   18:infinite write:[addr]
   18:infinite write:[addr]


Each test can be executed individually, identified by its number:
Each test can be executed individually, and is identified by its number:
   DDR>test 1
   DDR>test 1
   execute 1:Simple DataBus
   execute 1:Simple DataBus
Line 188: Line 184:
**  {{CodeSource | U-Boot | arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | stm32mp15-ddr3-1x4Gb-1066-binG.dtsi}}
**  {{CodeSource | U-Boot | arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | stm32mp15-ddr3-1x4Gb-1066-binG.dtsi}}
**  {{CodeSource | U-Boot | arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi | stm32mp15-ddr3-1x4Gb-1066-binF.dtsi}}
**  {{CodeSource | U-Boot | arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi | stm32mp15-ddr3-1x4Gb-1066-binF.dtsi}}
**  {{CodeSource | U-Boot | arch/arm/dts/stm32mp15-lpddr2-4Gb-1066.dtsi | stm32mp15-lpddr2-4Gb-1066.dtsi}}
**  {{CodeSource | U-Boot | arch/arm/dts/stm32mp15-lpddr3-8Gb-1066.dtsi | stm32mp15-lpddr3-8Gb-1066.dtsi}}


These files provide a list of define:
These files provide a list of defines:
   #define DDR_<NAME>  <VALUE>
   #define DDR_<NAME>  <VALUE>
and include {{CodeSource | U-Boot |arch/arm/dts/stm32mp15-ddr.dtsi|stm32mp15-ddr.dtsi}}) to provide each register values for the DDR controller and PHY.
and include {{CodeSource | U-Boot |arch/arm/dts/stm32mp15-ddr.dtsi|stm32mp15-ddr.dtsi}} to provide each register value for the DDR controller and PHY.


These DDR files are included in the needed board files stm32mp157c_<board>-uboot.dts to build the device tree with the needed DDR configuration nodes.
These DDR files are included in the board files stm32mp157c_<board>-uboot.dts needed to build the device tree with the required DDR configuration nodes.


== Load SPL in embedded RAM ==
== Load the SPL into embedded RAM ==


To execute SPL in the DDR interactive mode and to tune the DDR settings, SPL needs to be loaded in embedded RAM:
To execute the SPL in DDR interactive mode, and to tune the DDR settings, the SPL needs to be loaded into embedded RAM:
* manually (to be repeated after each reset):
* manually (to be repeated after each reset):
** [[#with STM32CubeProgrammer]] ([[#USB]] or [[#UART]])
** [[#with STM32CubeProgrammer]] ([[#USB]] or [[#UART]])
** [[#with GDB]]
** [[#with GDB]]
* automatically by ROM code after each reset:
* automatically by ROM code after each reset:
** [[#Boot from SD Card]]
** [[#Boot from SD card]]


=== with [[STM32CubeProgrammer]] ===
=== with [[STM32CubeProgrammer]] ===


You can use the CLI command to directly load SPL in the embedded RAM for peripheral boot on USB or UART.
You can use the CLI command to directly load the SPL into the embedded RAM for peripheral boot on USB or UART.


In this case the load with STM32Programmer needs to be repeated after each reset.
In this case the load with STM32Programmer needs to be repeated after each reset.
Line 214: Line 208:
{{Warning|The manual connection is difficult in parallel of STM32Programmer: it is recommended to activate the compilation flag DDR_INTERACTIVE to [[#DDR_interactive_mode|force the interactive mode]].}}
{{Warning|The manual connection is difficult in parallel of STM32Programmer: it is recommended to activate the compilation flag DDR_INTERACTIVE to [[#DDR_interactive_mode|force the interactive mode]].}}


In the next example, we use Linux cli but you can use also ST32CubeProgrammer for Windows (.bat file) with same parameter.
The next example uses the Linux cli, but you can also use ST32CubeProgrammer for Windows (.bat file) with the same parameters.


==== USB ====
==== USB ====
Line 239: Line 233:
   (gdb) restore spl/u-boot-spl.dtb binary $dtb
   (gdb) restore spl/u-boot-spl.dtb binary $dtb


Warning: SPL DTB is not included in the ELF file by default, you need to load it manually with [[GDB]] at the correct location.
Warning: SPL DTB is not included in the ELF file by default; you need to load it manually with [[GDB]] at the correct location.


=== Boot from SD Card ===
=== Boot from SD card ===


You can directly update SPL on the SD card used and let Boot ROM code to load the binary for the next boot form SD Card.
You can directly update SPL on the SD card used, and let the Boot ROM code load the binary for the next boot form SD card.


In this case you activate the DDR mode by pressing the 'd' key continously ([[#DDR_interactive_mode|DDR_INTERACTIVE=1]] is not mandatory).
In this case, activate the DDR mode by pressing the 'd' key continously ([[#DDR_interactive_mode|DDR_INTERACTIVE=1]] is not mandatory).


==== writing SPL in SDMMC on Linux PC ====
==== Writing the SPL to SDMMC on Linux PC ====


See [[How_to_update_U-Boot_on_an_SD_card]] to update partition 1 and 2 with partition <n> = /dev/mmcblk0p<n> or /dev/sdb<n> :
See [[How_to_update_U-Boot_on_an_SD_card]] to update partition 1 and 2 with partition <n> = /dev/mmcblk0p<n> or /dev/sdb<n> :


   {{PC$}} dd if=u-boot-spl.stm32 of=<dev>1 conv=fdatasync
   {{PC$}} dd if=u-boot-spl.stm32 of=<dev>1 conv=fdatasync
   {{PC$}} dd if=u-boot-spl.stm32 of=<dev>2 conv=fdatasync
   {{PC$}} dd if=u-boot-spl.stm32 of=<dev>2 conv=fdatasync


==== writing SPL in SDMMC with [[STM32CubeProgrammer]] ====
==== Writing SPL in SDMMC with [[STM32CubeProgrammer]] ====


Warning: we need the DDR working to allow U-Boot execution<br/>
Warning: [[STM32CubeProgrammer]] uses the DDR for U-Boot execution, so this method cannot be used during debug of the DDR settings and execution of the unitary (DDR)  test..
So it can be only using for the stress test / tuning.


to boot from SDCARD, we need to write in 2 partitions the generated files
To boot from SDCARD, the generated files must be written in 2 partitions :
* 1: spl/u-boot-spl.stm32
* 1: spl/u-boot-spl.stm32
* 4: u-boot.img
* 4: u-boot.img


on Linux, the command is:
The Linux command is:
<pre>
  {{PC$}} STM32_Programmer.sh -c port=usb1  -w FlashLayout.tsv
$> STM32_Programmer.sh -c port=usb1  -w FlashLayout.tsv
</pre>


with FlashLayout.tsv following [[STM32CubeProgrammer_flashlayout]] format, for example:
With FlashLayout.tsv following [[STM32CubeProgrammer_flashlayout]] format, for example:


<pre>
<pre>
Line 277: Line 268:
</pre>
</pre>


You can use also programmer for Windows (.bat file) with same parameter.
You can also use programmer for Windows (.bat file) with the same parameters.
 
<noinclude>
[[Category:U-Boot]]
{{PublicationRequestId | 12897 | 2019-08-01}}
</noinclude>

Latest revision as of 12:52, 27 January 2020

In U-Boot, the U-Boot SPL can provide a debug console for DDR configuration.

It is the embedded part used by the STM32CubeMX DDR tuning tools.

1. DDR interactive mode

This mode is defined under the compilation flag CONFIG_STM32MP1_DDR_INTERACTIVE.

When this configuration flag is activated, there are two ways to enter interactive mode:

  1. load SPL and key press the character 'd' (for DDR) in the console.
    Polling is only done during 200 ms of the boot sequence.
    It is therefore difficult to do manually and you should keep the key "d" pressed during the SPL startup until the DDR> prompt
  2. compile to force DDR_INTERACTIVE mode by adding DDR_INTERACTIVE=1 in the make option
    the SPL then automatically enters DDR mode:
   DEVICE_TREE=<device tree name> DDR_INTERACTIVE=1 make

When the DDR tool console is available, the following output is displayed after the SPL information banner:

  0:DDR_RESET
  DDR>

Interactive mode uses the same UART as the SPL console, by default the STMicroelectronics boards use UART4 with Bps=115200 Bit=8 Parity=None Stop=1

1.1. DDR steps

DDR interactive mode uses 5 steps to initialize the DDR controller and the PHY (including the "Mode Register" 0-3 sent to DDR during initialization) with parameters found in the device tree:

step name Description DDR CTL
state
DDR PHY
state
DDR CTL
registers
DDR PHY
registers
0 DDR_RESET Initial state
Clock initialized
'param' initialized with Device Tree
Reset Reset Reset Values Reset Values
1 DDR_CTRL_INIT_DONE Controller init done Clocked Reset Init done with 'param.ctl'
CTL register can be updated (command edit)
Reset Values
2 DDR PHY_INIT_DONE DDR PHY init done Runnig
Waiting PHY
Clocked - Init done with 'param.phy'
PHY register can be updated (command edit)
3 DDR_READY DDR ready and ports are open
test can be executed
Running Running - -
4 RUN Continue execution (U-Boot load) Running Running - -

1.2. commands available

with :

  • <type> = ctl, phy (for all DDR controller or PHY registers)
    or one category: static, timing, map, perf, cal, dyn
  • <reg> = name of the register (dx0dqstr for example)

You can execute the commands:

  • help: displays help
  • info: manages the DDR information (step, name, size and speed)
    • info: displays the DDR information
    • info <param> <val>: changes the <param> with <value> (<param> = "step", "name", "size" or "speed")
  • freq: manages the DDR PHY frequency
    • freq: displays the DDR frequency
    • freq <frequency>: changes the frequency (in kHz), allowed only in step 0
 DDR>freq
 DDRPHY = 40000 kHz
 DDR> freq 523000
 DDRPHY = 522999 kHz
  • param: manages the input parameters (read from the device tree)
    • param [type|reg]: prints input parameters
    • param <reg> <val>: edits parameters in step 0
  • print [type|reg]: dump register
  • edit: modifies register in the DDR controller and DDR PHY
    need to be done at the correct step, AFTER the initialization from the input parameters (values from device tree )
  • step 1 => CTRL register update allowed
  • step 2 => PHY register update allowed
  • step 3 => DDR ready (only for dynamic register for controller and PHY)
    • edit [type|reg]: modifies value register in DDR controller or PHY
  • step: manages the step
    • step: lists the available steps
    • step [n]: goes to the step <n>
      you can reset and restart init sequence with "step 0"
 0:DDR_RESET
 1:DDR_CTRL_INIT_DONE
 2:DDR PHY_INIT_DONE
 3:DDR_READY
 4:RUN
  • next: goes to the next step
  • go: continues the U-Boot SPL execution (load u-boot, same than "step 4")
  • reset: reboots the machine
  • test: test management : see next chapter
  • tuning: executes the tuning command, today only one sub command
    • tuning <n>: executing tuning procedure <n>
    • tuning help: displays the help message, lists available tuning procedures
 0:Read DQS gating:software read DQS Gating
 1:Bit de-skew:
 2:Eye Training:or DQS training
 3:Display registers:
 4:Bist config:[nbErr] [seed]

The "param" command is a simple way to test the modified settings, as it modifies the input parameters ( 'param' read from the device tree). It is recommanded to execute this command at step 0. The modified values are applied at the correct #DDR steps.

The "print" and "edit" commands directly access the CTRL and PHY registers, so the values can be overidden by the input parameters when the driver executes the intialization steps. These commands are used for detailed debug of the DDR initialization.

1.3. Examples

 DDR>info
 step = 3 : DDR_READY
 name = DDR3-1066/888 bin G 2x4Gb 533MHz v1.40
 size = 0x40000000
 speed = 533000 kHz
 DDR>param cal
 ==phy.cal==
 dx0dllcr= 0x40000000
 dx0dqtr= 0xffffffff
 dx0dqstr= 0x3db02000
 dx1dllcr= 0x40000000
 dx1dqtr= 0xffffffff
 dx1dqstr= 0x3db02000
 dx2dllcr= 0x40000000
 dx2dqtr= 0xffffffff
 dx2dqstr= 0x3db02000
 dx3dllcr= 0x40000000
 dx3dqtr= 0xffffffff
 dx3dqstr= 0x3db02000
 DDR>print dx0dqstr
 dx0dqstr= 0x3db03001
 DDR>print mstr
 mstr= 0x00040401

1.4. DDR test

To execute the DDR test you need to be in the 'DDR ready' step (step 3).

To generate the list of tests, execute the 'test' command without any parameters:

 DDR>step 3
 DDR>test
 test:25
 0:All:
 1:Simple DataBus:[addr]
 2:DataBusWalking0:[loop] [addr]
 3:DataBusWalking1:[loop] [addr]
 4:AddressBus:[size] [addr]
 5:MemDevice:[size] [addr]
 6:SimultaneousSwitchingOutput:[size] [addr] 
 7:Noise:[pattern] [addr]
 8:NoiseBurst:[size] [pattern] [addr]
 9:Random:[size] [loop] [addr]
 10:FrequencySelectivePattern :[size]
 11:BlockSequential:[size]
 12:Checkerboard:[size]
 13:BitSpread:[size]
 14:BitFlip:[size]
 15:WalkingOnes:[size]
 16:WalkingZeroes:[size]
 17:infinite read:[addr]
 18:infinite write:[addr]

Each test can be executed individually, and is identified by its number:

 DDR>test 1
 execute 1:Simple DataBus
 Result: Pass [address 0xc0000000]

All tests can be executed with test 0:

 DDR>test 0
 execute 0:All
 execute 1:Simple DataBus
 result 1:Simple DataBus = Passed
 
 execute 2:DataBusWalking0
 running 100 loops at 0xc0000000
 result 2:DataBusWalking0 = Passed
 
 execute 3:DataBusWalking1
 running 100 loops at 0xc0000000
 result 3:DataBusWalking1 = Passed
 ....
 check buffer.
 pattern = 00000001.
 check buffer.
 result 15:WalkingOnes = Passed
 
 Result: Pass [0/16 test failed]

2. Source code organization

These files provide a list of defines:

  #define DDR_<NAME>   <VALUE>

and include stm32mp15-ddr.dtsi to provide each register value for the DDR controller and PHY.

These DDR files are included in the board files stm32mp157c_<board>-uboot.dts needed to build the device tree with the required DDR configuration nodes.

3. Load the SPL into embedded RAM

To execute the SPL in DDR interactive mode, and to tune the DDR settings, the SPL needs to be loaded into embedded RAM:

3.1. with STM32CubeProgrammer

You can use the CLI command to directly load the SPL into the embedded RAM for peripheral boot on USB or UART.

In this case the load with STM32Programmer needs to be repeated after each reset.

Warning white.png Warning
The manual connection is difficult in parallel of STM32Programmer: it is recommended to activate the compilation flag DDR_INTERACTIVE to force the interactive mode.

The next example uses the Linux cli, but you can also use ST32CubeProgrammer for Windows (.bat file) with the same parameters.

3.1.1. USB

  STM32_Programmer.sh -c port=usb1 -w spl/u-boot-spl.stm32 0x01 --start 0x01

3.1.2. UART

  STM32_Programmer.sh -c port=/dev/ttyS0 br=115200 -w spl/u-boot-spl.stm32 0x01 --start 0x01

3.2. with GDB

 (gdb) file u-boot-spl.elf
 (gdb) load
 (gdb) set $dtb =  __bss_end
 (gdb) restore spl/u-boot-spl.dtb binary $dtb

Warning: SPL DTB is not included in the ELF file by default; you need to load it manually with GDB at the correct location.

3.3. Boot from SD card

You can directly update SPL on the SD card used, and let the Boot ROM code load the binary for the next boot form SD card.

In this case, activate the DDR mode by pressing the 'd' key continously (DDR_INTERACTIVE=1 is not mandatory).

3.3.1. Writing the SPL to SDMMC on Linux PC

See How_to_update_U-Boot_on_an_SD_card to update partition 1 and 2 with partition <n> = /dev/mmcblk0p<n> or /dev/sdb<n> :

  dd if=u-boot-spl.stm32 of=<dev>1 conv=fdatasync
  dd if=u-boot-spl.stm32 of=<dev>2 conv=fdatasync

3.3.2. Writing SPL in SDMMC with STM32CubeProgrammer

Warning: STM32CubeProgrammer uses the DDR for U-Boot execution, so this method cannot be used during debug of the DDR settings and execution of the unitary (DDR) test..

To boot from SDCARD, the generated files must be written in 2 partitions :

  • 1: spl/u-boot-spl.stm32
  • 4: u-boot.img

The Linux command is:

  STM32_Programmer.sh -c port=usb1  -w FlashLayout.tsv

With FlashLayout.tsv following STM32CubeProgrammer_flashlayout format, for example:

#Option	Id	Name	Type	Device	Offset		Binary
P	0x01	fsbl1	Binary	SDMMC1	0x00004400	spl/u-boot-spl.stm32
PE	0x02	fsbl2	Binary	SDMMC1	0x00044400	none
P	0x03	ssbl	Binary	SDMMC1	0x00084400	u-boot.img.bin

You can also use programmer for Windows (.bat file) with the same parameters.