cancel
Showing results for 
Search instead for 
Did you mean: 

STM32MP257D custom board DDR4 bring-up: read training failure after CA/RxEn/WL pass

sergei.poselenov
Associate II

Hello all,

We are bringing up DDR4 memory on a custom STM32MP257D-based SOM. We have made significant progress but are now blocked on a specific PHY training failure that we cannot diagnose without access to the Synopsys PHY firmware streaming message documentation. We would appreciate any help interpreting the failure and identifying the root cause.

Board Overview

  • SoC: STM32MP257DAK3 (VFBGA424)
  • DRAM: 2× Alliance AS4C512M16D4A-62BIN (DDR4-3200, 8 Gbit × 16, 1.2V, VPP 2.5V)
  • Topology: 32-bit bus, 2 GB total, single rank, soldered down
  • PMIC: STPMIC25APQR (I²C7)
  • Reference HSE: 40 MHz crystal
  • Tool chain: STM32CubeMX 6.16.1, STM32CubeIDE 2.0.0, STM32DDRFW-UTIL, STM32CubeProgrammer 2.22

    Bring-up Status

    We are using STM32DDRFW-UTIL with verbose PHY messaging enabled (hdtctrl = 0x05, custom g_waitfwdone.c patched to decode major messages and dump streaming messages).

    Power Rails (all verified by HW measurement)

    • VDD_DDR: 1.20 V :white_heavy_check_mark:
    • VTT_DDR: 0.60 V :white_heavy_check_mark:
    • VREF_DDR: 0.60 V :white_heavy_check_mark:
    • VPP_DDR: 2.49 V :white_heavy_check_mark: (Note: ST BSP code uses 0x1E for LDO5 which produces 2.39 V; we changed to 0x20 to get 2.5 V per JEDEC spec)
    • VDDA18DDR / V1V8: 1.80 V :white_heavy_check_mark:

    Clock Configuration (matches STM32MP257F-DK reference)

    • HSE → PLL2: FBDIV=30, FREFDIV=1, POSTDIV1=1, POSTDIV2=2
    • PLL2 output = 600 MHz → MEMCLK = 1200 MHz (DDR4-2400 data rate)

    Software Configuration

    • STM32MP_DDR4_TYPE=1 in build
    • DDR controller registers (DDRC, ADDRMAP, DRAMTMG, DFITMG, INIT) match the EV1 reference template, with the expected ADDRMAP7 difference accounting for our 8 Gbit chip density vs EV1's 16 Gbit
    • All UIB/UIA/UIM PHY user input parameters match the EV1 reference values
    • UIS_SWIZZLE values match the mainline stm32mp2xx-ddr4-2x16Gbits-2x16bits-1200MHz.h template

    Initialization Sequence Progress (PHY firmware messages)

    Step 0 (DDR_RESET) and Step 1 (DDR_CTRL_INIT_DONE) complete successfully. During Step 2 (DDR_PHY_INIT_DONE), the PHY firmware reports:

[PHY-MSG] 0x00 - end of CA training              ✅
[PHY-MSG] 0x02 - end of read enable training     ✅
[PHY-MSG] 0x01 - end of write leveling coarse delay ✅
[PHY-STREAM] header=0x00470002, len=2            (RxClkDly_Tg0, msg[0]=msg[1]=0)
[PHY-STREAM] header=0x04020000, len=0            ← failure
[PHY-MSG] 0xFF - TRAINING FAILED​

We measured that DDR_RESETN goes high during step 3, confirming the PHY firmware is functional up to this point.

Key Observations

  1. We tested at both MEMCLK = 1200 MHz and MEMCLK = 800 MHz (via POSTDIV2=2 vs POSTDIV2=3 + regenerated config). The training fails at the identical point with identical error code at both frequencies. This appears to rule out signal integrity as the cause.
  2. CA training (msg 0x00), Read Enable training (msg 0x02), and Write Leveling coarse delay (msg 0x01) all complete successfully, suggesting the basic bus connectivity and clock/strobe alignment are good.
  3. The failure is in what appears to be the next training stage (DQS gate / Read DQ training).
  4. The PCB has a byte-lane swap on U7 (SoC byte 2 routes to U7 upper byte, byte 3 routes to U7 lower byte). Per ST community guidance, this should be transparent to DDR4 training, but we mention it for completeness.
  5. HW cannot perform continuity tests on DQ lines (all routed on internal PCB layers between BGA packages) and cannot scope the DDR clock (>600 MHz exceeds available equipment).

    Questions:

    1. What is the meaning of PHY streaming message ID 0x0402 (header=0x04020000)? We'd like to see the Synopsys DDR5/4 PHY Training Firmware Application Note's decoding for this code to understand which sub-step of which training stage failed.
    2. What is the meaning of the streaming message header=0x00470002 with both data values = 0 that immediately precedes the failure? Is this an expected intermediate result or already an error indication?
    3. Are there known issues or required PHY parameter overrides for the STM32MP257D in the VFBGA424 package using DDR4 32-bit topology with 2× 8 Gbit chips at MEMCLK = 1200 MHz?
    4. Are there specific recommended values for any of the following parameters that we may not have set correctly?
      • TRAIN2D (currently 0)
      • HARDMACROVER (currently 3)
      • DRAMBYTESWAP (currently 0 — though our PCB has byte swap on the second DRAM chip)
    5. Could the documented CubeMX 6.16.1 DDR_UIS_SWIZZLE reload bug affect DQ training behavior on DDR4, or is it strictly limited to the CA path (HwtSwizzle + DDR34_AC_SWIZZLE)?

    I'm attaching full UART boot logs for MEMCLK=1200MHz and 800MHz, generated stm32mp25-mx.dtsi (for 1200MHz).


    Regards,
    Sergei
7 REPLIES 7
PatrickF
ST Employee

Hi @sergei.poselenov 

could you share you schematics (all DDR4 to STM32MP25 connections and surrounding components) ?

This might higlight issues Vs recommendation in AN5489.

According to provided .dtsi, your DDR4 connections are :

DDR4 case
STM32MP2 pin name Output signal
DDR_A0 CKE0 (CKE)
DDR_A1 -
DDR_A2 CS0N (CS_n)
DDR_A3 ODT0 (ODT)
DDR_A4 CLKP (CK_t)
DDR_A5 CLKN (CK_c)
DDR_A6 -
DDR_A7 -
DDR_A8 A3
DDR_A9 BA1
DDR_A10 A12 / BC_n
DDR_A11 RAS_n / A16 (DDR4)
DDR_A12 A6
DDR_A13 A0
DDR_A14 A2
DDR_A15 A8
DDR_A16 -
DDR_A17 ACT_n (DDR4 only)
DDR_A18 BG0 (DDR4 only)
DDR_A19 -
DDR_A20 WE_n / A14 (DDR4)
DDR_A21 BA0
DDR_A22 A4
DDR_A23 A10 / AP
DDR_A24 -
DDR_A25 A13
DDR_A26 A5
DDR_A27 A9
DDR_A28 A11
DDR_A29 A7
DDR_A30 CAS_n / A15 (DDR4)
DDR_A31 A1

 

Regards,

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Tip of the day: Try Sidekick STM32 AI agent, see here

Hello Patrick,

No, our mapping is different. I'm quoting your table with the additional column showing our mapping. Also, I'm attaching the DDR page of our schematics.

DDR4 case 
STM32MP2 pin nameOutput signal (from dtsi)Output signal (schematic)
DDR_A0CKE0 (CKE)DDR_CKE
DDR_A1--
DDR_A2CS0N (CS_n)DDR_CSN
DDR_A3ODT0 (ODT)DDR_ODT
DDR_A4CLKP (CK_t)DDR_CLK_P
DDR_A5CLKN (CK_c)DDR_CLKN
DDR_A6--
DDR_A7--
DDR_A8A3DDR_A3
DDR_A9BA1DDR_CASN
DDR_A10A12 / BC_nDDR_RASN
DDR_A11RAS_n / A16 (DDR4)DDR_A11
DDR_A12A6DDR_A0
DDR_A13A0DDR_A6
DDR_A14A2DDR_A8
DDR_A15A8DDR_A2
DDR_A16-DDR_BA0
DDR_A17ACT_n (DDR4 only)DDR_A10
DDR_A18BG0 (DDR4 only)-
DDR_A19--
DDR_A20WE_n / A14 (DDR4)DDR_A4
DDR_A21BA0DDR_BG0
DDR_A22A4DDR_ACTN
DDR_A23A10 / APDDR_WEN
DDR_A24--
DDR_A25A13DDR_A5
DDR_A26A5DDR_A9
DDR_A27A9DDR_BA1
DDR_A28A11DDR_A13
DDR_A29A7DDR_A1
DDR_A30CAS_n / A15 (DDR4)DDR_A7
DDR_A31A1DDR_A12


I also double-checked our mapping in the CubeMX .ioc project, it matches our mapping the above (IOC project report PDF with the relevant pages is attached).

Do you think that the .dtsi has been generated incorrectly? I tried CubeMX 6.17.0, migrated our project there, and it generates the same stm32mp25-mx.dtsi.

Thank you for looking into this!

Regards,

Sergei

Hi @sergei.poselenov 

until .dtsi is wrong, DDR4 will not work. 

I cannot help more on this, maybe try to start from an empty CubeMX project (just provide DDR4 and associated clock settings) and generates the .dtsi to see if different than the default EV1 one. Then you could manually paste the .dtsi in your compilation environment (or paste it here for double check).

Regard.

 

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Tip of the day: Try Sidekick STM32 AI agent, see here
Kevin HUBER
ST Employee

Hello @sergei.poselenov ,

 

Unfortunately this a known issue visible in the version of cubeMX before the 6.17.0.
This is mentioned  in the release note available here for 6.15.0 and 6.16.0: https://wiki.st.com/stm32mpu/wiki/STM32CubeMX_release_note#With_STM32MP2https://wiki.st.com/stm32mpu/wiki/STM32CubeMX_release_note

 

The explanation is not complete because it also impact MP25 and all the type of DDR.

To bypass this problem, it is annoying, but as explain in the Restriction, you should:

- create a new IOC

- Do again your swizzle mapping configuration and DDR configuration
- Click on "Generate Project" and save your DDR configuration generated somewhere because you will have to copy them manually if you regenerate a project.

 

----

Why did you encounter this error with CubeMX6.17.0?
This is surely due to your IOC that was already corrupted. Creating a new project from scratch on CubeMX 6.17.0 or even better on 6.18.0, will allows you to generate the correct DDR configuration related to your board.

BR,
kevin

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
NEW ! Sidekick STM32 AI agent, see here

Hello Patrick,

Thank you for the hint. I just did exactly this:

* Loaded the original STM32MP257F-EV1 CubeMX 6.17.0 project and built it, then saved stm32mp25-mx.dtsi.

*  Modified this project to match our DDR configuration (size, density and mappings), and re-generated the code.

I see that the swizzle values now are different (compared to what CubeMX produces with our project). And STM32DDRFW-UTIL calibration finally passed on our SOM!

 

Update: It turns out we encountered a STM32CubeMX bug first documented in version 6.15.0
(https://wiki.st.com/stm32mpu/wiki/STM32CubeMX_release_note#STM32CubeMX_v6-15-0_-_MPU_support:(

/"The DDR_UIS_SWIZZLE parameters are initially generated with the
correct values for the STM32MP23 projects when activating the DDR3L
memory. However, upon subsequent re-opening of the IOC, these
correct values are overwritten with erroneous ones."/

Although we are using version 6.17.0, this bug is not mentioned in this
version's release notes.

To prevent this from happening again, we developed a Python utility
(attached) that automatically generates the correct |DDR_UIS_SWIZZLE_xx|
constants from signal mappings (via a text file or |.ioc| file). We
integrated this utility into the CubeMX post-build script, allowing us
to reliably produce the correct |stm32mp25-mx.dtsi| file every time.

Thanks!

Regards,

Sergei

Hello Kevin,

Correct, we have figured this out. However, I confirmed the bug is still present for 6.17.0.

Thanks!

 

Regards,

Sergei

Forgot the attachment