LPDDR4 initialization for new chips using the Synopsys uMCTL2 controller should be based on a combination of the i.MX8M driver logic with the STM32MP1 device tree architecture. The i.MX8M implementation provides production-tested LPDDR4 initialization—a complete 26-step sequence with PHY training, mode register programming, and DFI protocol.
However, its C-structure-based configuration makes supporting multiple board variants cumbersome, requiring recompilation for every timing change. Defining all DDR timing parameters as preprocessor macros in .dtsi files provides more flexibility, separating board-specific configuration from the complex driver code. This means different board variants only need new device tree files.
The combined approach consists of device tree macros defining register values, the STM32MP1 parser layer that reads and validates them and feeds the configuration into i.MX8M’s initialization sequence.
ST supports DDR3 initialization for 32-bit STM32MP1x boards in TF-A and U-Boot.
In U-Boot the latest update to the corresponding devicetrees was in
November 2025, so it appears to be actively maintained. When
TFABOOT from arch/arm/Kconfig is disabled then
U-Boot is responsible for DDR initialization. Of the 38 STM32 defconfigs
only the following have TFABOOT enabled:
stm32mp13_defconfigstm32mp15_defconfigstm32mp15_trusted_defconfigstm32mp15-odyssey_defconfigstm32mp1-ddr.dtsi declares arrays of register values.
Then stm32mp13-ddr.dtsi and stm32mp15-ddr.dtsi
contain more specific register arrays. The values of those registers is
defined in various dtsi files. Interestingly, there are 8
dtsi in U-Boot and 5 in TF-A.
For 64-bit STM32MP2x processors ST uses IP that supports DDR3L, LPDDR4 and DDR4. DDR initialization is supported exclusively in TF-A with 4 LPDDR4 dtsi files and 2 DDR4 dtsi files. There is no upstream configuration for DDR3. Although, U-Boot references the 5x, 3x (low cost), and 1x (low power) variants, TF-A only mentions the 5x.
stm32mp25-ddr.dtsi is 253 lines while
stm32mp15-ddr.dtsi is 112 lines, hinting at the increased
complexity of DDR4 support.
Note that the following tables were generated using Claude Sonnet 4.5 9/29/2025.
Bootloader implementation style legend:
| Board / SoC Family | DDR IP Vendor | Type | Initialization Code Location | Style |
|---|---|---|---|---|
| NXP i.MX8M Plus EVK | Synopsys (uMCTL2) | LP4 | drivers/ddr/imx/imx8m/ddr_init.c |
C |
| ST STM32MP157C-DK2 | Synopsys (uMCTL2) | 3/3L/LP2/LP3 | drivers/ram/stm32mp1/stm32mp1_ddr.c |
DT |
| TI AM625 SK / BeaglePlay | Cadence (DDRSS) | 4/LP4 | drivers/ram/k3-ddrss/k3-ddrss.c |
DT |
| Xilinx ZCU102 (ZynqMP) | Synopsys (uMCTL2) | 3/3L/4/LP3/LP4 | board/xilinx/zynqmp/psu_init_gpl.c |
G |
| Rockchip RK3399 Sapphire | Synopsys (PUBL) | 3/LP3/LP4 | drivers/ram/rockchip/sdram_rk3399.c |
C |
| Aspeed AST2700 EVB | Synopsys (uMCTL2) | 4/5 | drivers/ram/aspeed/sdram_ast2700.c |
C, B |
| Intel Stratix 10 / Agilex | Synopsys (uMCTL2) | 3/4 | drivers/ddr/altera/sdram_s10.c |
H |
| NXP Layerscape (LS1046A) | Freescale (Proprietary) | 3/4 | drivers/ddr/fsl/main.c |
C |
| MediaTek MT7629 | MediaTek (Proprietary) | 3 | drivers/ram/mediatek/ddr3-mt7629.c |
C |
| Allwinner D1 (Sun20i) | Allwinner (Proprietary) | 3/LP3 | drivers/ram/sunxi/dram_sun20i_d1.c |
C |
| Renesas R-Car Gen3 | Renesas (Proprietary) | 3/LP4 | drivers/ram/renesas/dbsc5/dram.c |
C |
| TI BeagleBone Black (AM335x) | TI (Proprietary/EMIF) | 2/3 | arch/arm/mach-omap2/am33xx/board.c |
C |
TrustedFirmware-A (formerly arm-trusted-firmware) contains DDR initialization code run during boot as well as runtime code like dynamic voltage and frequency scaling, power management like suspend and resume, error correction code management, and thermal/performance throttling.
| Board / SoC Family | DDR IP Vendor | Type | Initialization Code Location | Style |
|---|---|---|---|---|
| ST STM32MP15x (MP157/MP153) | Synopsys (uMCTL2) | 3/3L/LP2/LP3 | drivers/st/ddr/stm32mp1_ram.c |
DT |
| ST STM32MP2x (MP25x) | Synopsys (uMCTL2) | 4/LP4 | drivers/st/ddr/stm32mp2_ram.c |
DT |
| Intel Stratix 10 / Agilex | Synopsys (uMCTL2) | 3/4 | plat/intel/soc/common/drivers/ddr/ddr.c |
M |
| Intel Agilex5 / Agilex7M | Synopsys (uMCTL2) | 4/5 | plat/intel/soc/agilex5/soc/agilex5_ddr.c |
M, H |
| Rockchip RK3399 | Synopsys (PUBL PHY) | 3/LP3/LP4 | plat/rockchip/rk3399/drivers/dram/ |
C |
| NXP Layerscape (LS1046A/LS1088A) | NXP (Proprietary) | 3/4 | plat/nxp/soc-ls1046a/*/ddr_init.c |
C |
| NXP i.MX8ULP | Cadence (DDRSS/Denali) | LP4/LP4X | plat/imx/imx8ulp/dram.c |
C |
| Renesas R-Car (H3/M3) | Renesas (Proprietary) | 3/LP4 | drivers/renesas/common/ddr/ddr_b/boot_init_dram.c |
C |
| Marvell Armada A8K | Marvell (mv_ddr) |
3/4 | plat/marvell/armada/a8k/.../dram_port.c |
L |
| Board / SoC Family | DDR IP Vendor | Type | Initialization Code Location | Style |
|---|---|---|---|---|
| Rockchip RK3399 Sapphire | Synopsys (PUBL PHY) | 3/LP3/LP4 | src/soc/rockchip/rk3399/sdram.c |
C |
| Rockchip RK3288 Firefly | Synopsys (PUBL PHY) | 3/LP3 | src/soc/rockchip/rk3288/sdram.c |
C |
| SiFive FU540 / FU740 | Cadence (Denali) | 4/LP4 | src/soc/sifive/fu540/sdram.c |
C |
| Nvidia Tegra210 / T124 | Nvidia (Proprietary) | LP4/LP4X | src/soc/nvidia/tegra210/sdram.c |
C, B |
| MediaTek MT8192 / MT8195 | MediaTek (Proprietary) | 4/LP4/LP4X | src/soc/mediatek/common/memory.c |
B |
| Qualcomm IPQ40xx / IPQ806x | Qualcomm (Proprietary) | 3 | src/soc/qualcomm/ipq40xx/blobs_init.c |
B |
| Intel Broadwell | Intel (Proprietary) | 3 | src/soc/intel/broadwell/raminit.c |
B |
| Cavium CN81xx / ThunderX | Cavium (Proprietary) | 3/4 | src/soc/cavium/cn81xx/sdram.c |
L |
| TI AM335x | TI (EMIF4) | 2/3 | src/soc/ti/am335x/sdram.c |
C |
| AMD Picasso / Cezanne | AMD (FSP-based) | 4 | src/soc/amd/picasso/fsp_m_params.c |
B |
| Intel Alder Lake / Tiger Lake | Intel (FSP-based) | 4/5 | src/soc/intel/alderlake/romstage/romstage.c |
B |
| Qualcomm SC7180 / SC7280 | Qualcomm (Proprietary) | 4/LP4X | src/soc/qualcomm/sc7180/qclib.c |
B |
Linux includes supports the runtime functionality mentioned under TF-A, either by communicating with TF-A or directly accessing he DRAM controller/PHY. There is a trend for SoC and IP vendors to add more runtime firmware in systems. It adds complexity and limits how the kernel can operate. It is nearly always the case that the code in the kernel is higher quality, has more functionality and is better supported.
New chips using the Synopsys uMCTL2 controller and LPDDR4 should
first look at drivers/edac/synopsys_edac.c, which includes
EDAC support. Then look at drivers/devfreq/imx8m-ddrc.c for
DVFS support. Finally, the i.MX perf drivers for performance
monitoring.
| SoC / Platform | DDR IP Vendor | Type | Support | drivers/ |
|---|---|---|---|---|
| Xilinx Zynq / ZynqMP | Synopsys (uMCTL2) | 3/LP3/4/LP4 | E | edac/synopsys_edac.c |
| Xilinx ZynqMP | Synopsys (uMCTL2 v2.40a) | 4 | E | edac/zynqmp_edac.c |
| ARM DMC-520 | ARM (DMC-520) | 3/4 | E | edac/dmc520_edac.c |
| NXP Layerscape / QorIQ | NXP (FSL DDR) | 3/4/LP4 | E | edac/fsl_ddr_edac.c |
| NXP i.MX8M (Plus/Mini/Nano) | Synopsys (uMCTL2) | LP4 | D | devfreq/imx8m-ddrc.c |
| Nvidia Tegra210 | Nvidia (EMC) | LP2/LP4 | D, T | memory/tegra/tegra210-emc-core.c |
| Nvidia Tegra186/194 | Nvidia (EMC) | LP4/LP4X | D | memory/tegra/tegra186-emc.c |
| Rockchip (RK3xxx) | Synopsys (PUBL PHY) | 3/LP3/LP4 | C | clk/rockchip/clk-ddr.c |
| NXP i.MX8 / i.MX8M | Synopsys (uMCTL2) | LP4 | P | perf/fsl_imx8_ddr_perf.c |
| NXP i.MX9 | Synopsys (uMCTL2) | LP4X | P | perf/fsl_imx9_ddr_perf.c |
| Amlogic Meson G12 / A1 | Amlogic (Proprietary) | 3/4/LP3/LP4 | P | perf/amlogic/meson_ddr_pmu_core.c |
| TI DA8xx | TI (Proprietary) | 2 | C | memory/da8xx-ddrctl.c |
| Intel Broadwell / Skylake | Intel (Proprietary) | 3/4 | E | edac/sb_edac.c /
edac/skx_edac.c |
| AMD Zen / Epyc | AMD (Proprietary) | 4/5 | E | edac/amd64_edac.c |
| Aspeed AST2600 | Aspeed (Proprietary) | 4 | E | edac/aspeed_edac.c |
| Marvell Armada XP | Marvell (Proprietary) | 3 | E | edac/armada_xp_edac.c |
Clock/Controller refers to the following.
clk/rockchip/clk-ddr.c manages DR clock rates as part of
DVFS, but integrated into the clock subsystem rather than devfreq.
memory/da8xx-ddrctl.c does low-level controller tuning that
doesn’t fall into the other categories.
snps,dw-umctl2-ddrcSerge Semin attempted to add mainline support for the Russian Baikal-T1 SoC (see [PATCH v2 00/15] EDAC/synopsys: Add generic resources and Baikal-T1 support). It appears than only DT bindings from the series were applied, but the series includes additional functionality.
That binding defines compatible = "snps,dw-umctl2-ddrc",
but synopsys_edac.c was never updated and instead includes
the following compatibles:
xlnx,zynq-ddrc-a05xlnx,zynqmp-ddrc-2.40asnps,ddrc-3.80a