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.
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