2026-05-22 7:49 AM - last edited on 2026-05-22 8:06 AM by Andrew Neil
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.
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).
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 FAILEDWe measured that DDR_RESETN goes high during step 3, confirming the PHY firmware is functional up to this point.
2026-05-22 8:12 AM
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,
2026-05-25 3:32 AM
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 name | Output signal (from dtsi) | Output signal (schematic) |
| DDR_A0 | CKE0 (CKE) | DDR_CKE |
| DDR_A1 | - | - |
| DDR_A2 | CS0N (CS_n) | DDR_CSN |
| DDR_A3 | ODT0 (ODT) | DDR_ODT |
| DDR_A4 | CLKP (CK_t) | DDR_CLK_P |
| DDR_A5 | CLKN (CK_c) | DDR_CLKN |
| DDR_A6 | - | - |
| DDR_A7 | - | - |
| DDR_A8 | A3 | DDR_A3 |
| DDR_A9 | BA1 | DDR_CASN |
| DDR_A10 | A12 / BC_n | DDR_RASN |
| DDR_A11 | RAS_n / A16 (DDR4) | DDR_A11 |
| DDR_A12 | A6 | DDR_A0 |
| DDR_A13 | A0 | DDR_A6 |
| DDR_A14 | A2 | DDR_A8 |
| DDR_A15 | A8 | DDR_A2 |
| DDR_A16 | - | DDR_BA0 |
| DDR_A17 | ACT_n (DDR4 only) | DDR_A10 |
| DDR_A18 | BG0 (DDR4 only) | - |
| DDR_A19 | - | - |
| DDR_A20 | WE_n / A14 (DDR4) | DDR_A4 |
| DDR_A21 | BA0 | DDR_BG0 |
| DDR_A22 | A4 | DDR_ACTN |
| DDR_A23 | A10 / AP | DDR_WEN |
| DDR_A24 | - | - |
| DDR_A25 | A13 | DDR_A5 |
| DDR_A26 | A5 | DDR_A9 |
| DDR_A27 | A9 | DDR_BA1 |
| DDR_A28 | A11 | DDR_A13 |
| DDR_A29 | A7 | DDR_A1 |
| DDR_A30 | CAS_n / A15 (DDR4) | DDR_A7 |
| DDR_A31 | A1 | DDR_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
2026-05-25 4:43 AM
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.
2026-05-28 2:49 AM
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
2026-05-28 2:55 AM
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
2026-05-28 2:57 AM
Hello Kevin,
Correct, we have figured this out. However, I confirmed the bug is still present for 6.17.0.
Thanks!
Regards,
Sergei
2026-05-28 3:00 AM
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.