[PATCH v4 1/4] imx9: Add support for saving DDR training data to NVM

Kumar, Udit u-kumar1 at ti.com
Thu May 28 07:25:23 CEST 2026



On 4/30/2026 2:03 PM, Simona Toaca (OSS) wrote:
> From: Simona Toaca <simona.toaca at nxp.com>
> 
> DDR training data can be saved to NVM and be available
> to OEI at boot time, which will trigger QuickBoot flow.
> 
> U-Boot only checks for data integrity (CRC32), while
> OEI is in charge of authentication when it tries to
> load the data from NVM.
> 
> On iMX95 A0/A1, 'authentication' is done via another
> CRC32. On the other SoCs, authentication is done by
> using ELE to check the MAC stored in the ddrphy_qb_state
> structure.
> 
> Supported platforms: iMX94, iMX95, iMX952 (using OEI)
> Supported storage types: eMMC, SD, SPI flash.
> 
> Signed-off-by: Viorel Suman <viorel.suman at nxp.com>
> Signed-off-by: Ye Li <ye.li at nxp.com>
> Signed-off-by: Simona Toaca <simona.toaca at nxp.com>
> ---
>  arch/arm/include/asm/arch-imx9/ddr.h |  48 +++-
>  arch/arm/include/asm/mach-imx/qb.h   |  15 +
>  arch/arm/mach-imx/Kconfig            |   9 +
>  arch/arm/mach-imx/imx9/Makefile      |   6 +-
>  arch/arm/mach-imx/imx9/qb.c          | 403 +++++++++++++++++++++++++++
>  arch/arm/mach-imx/imx9/scmi/soc.c    |   7 +
>  drivers/ddr/imx/imx9/Kconfig         |   7 +
>  7 files changed, 492 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm/include/asm/mach-imx/qb.h
>  create mode 100644 arch/arm/mach-imx/imx9/qb.c
> 
> diff --git a/arch/arm/include/asm/arch-imx9/ddr.h b/arch/arm/include/asm/arch-imx9/ddr.h
> index a8e3f7354c7..bba12369f06 100644
> --- a/arch/arm/include/asm/arch-imx9/ddr.h
> +++ b/arch/arm/include/asm/arch-imx9/ddr.h
> @@ -1,6 +1,6 @@
>  /* SPDX-License-Identifier: GPL-2.0+ */
>  /*
> - * Copyright 2022 NXP
> + * Copyright 2022-2026 NXP
>   */
>  
>  #ifndef __ASM_ARCH_IMX8M_DDR_H
> @@ -100,6 +100,52 @@ struct dram_timing_info {
>  
>  extern struct dram_timing_info dram_timing;
>  
> +/* Quick Boot related */
> +#define DDRPHY_QB_CSR_SIZE	5168
> +#define DDRPHY_QB_ACSM_SIZE	(4 * 1024)
> +#define DDRPHY_QB_MSB_SIZE	0x200
> +#define DDRPHY_QB_PSTATES	0
> +#define DDRPHY_QB_PST_SIZE	(DDRPHY_QB_PSTATES * 4 * 1024)

[..]
Sorry for basic question, in case OEI layer changes format due to one of
other reason then how you are making sure, struct ddrphy_qb_state is
aligned

+ * This structure needs to be aligned with the one in OEI.


[..]
> +
> +bool imx_qb_check(void)
> +{
> +	struct ddrphy_qb_state *qb_state;
> +	u32 size, crc;
> +
> +	/**
> +	 * Ensure CRC is not empty, the reason is that
> +	 * the data is invalidated after first save run
> +	 * or after it is overwritten.
> +	 */

In case OEI layer using saved DDR training data, then will
passed CRC will be zero ?

> +	qb_state = (struct ddrphy_qb_state *)CONFIG_QB_SAVED_STATE_BASE;

If yes then you can return from here, if no CRC found instead of doing
crc calculation.

> +	size = sizeof(struct ddrphy_qb_state) - sizeof(qb_state->crc);
> +	crc = crc32(0, (u8 *)qb_state->mac, size);
> +
> +	if (!qb_state->crc || crc != qb_state->crc)
> +		return false;
> +
> +	return true;
> +}
> +
[..]
> +
> +void spl_imx_qb_save(void)
> +{
> +	/* Save QB data on current boot device */
> +	if (imx_qb("auto", "", true))
> +		printf("QB save failed\n");

In case, of 3rd boot or so, there is no need to save training data,
whereas you will return error, in case this feature is auto enabled.

> +}
[..]


More information about the U-Boot mailing list