[PATCH 4/5] board: nxp: imx9{4,5}_evk: Add qb save option in SPL
Simona Toaca
simona.toaca at oss.nxp.com
Tue Mar 10 16:27:45 CET 2026
Hi Emanuele,
On Tue, Mar 10, 2026 at 04:04:19PM +0100, Emanuele Ghidoli wrote:
>
>
> On 3/10/26 12:54, Simona Toaca (OSS) wrote:
> > From: Simona Toaca <simona.toaca at nxp.com>
> >
> > Call qb save automatically in the board-specific
> > spl_board_init(), if SPL_QB option is enabled. This
> > makes sure qb_save is called before any image loading
> > is done by the SPL.
> >
> > Signed-off-by: Simona Toaca <simona.toaca at nxp.com>
> > ---
> > arch/arm/include/asm/mach-imx/qb.h | 2 ++
> > arch/arm/mach-imx/Kconfig | 7 +++++++
> > arch/arm/mach-imx/imx9/Makefile | 4 +++-
> > arch/arm/mach-imx/imx9/qb.c | 9 +++++++++
> > board/nxp/imx94_evk/spl.c | 6 +++++-
> > board/nxp/imx95_evk/spl.c | 6 +++++-
> > 6 files changed, 31 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/include/asm/mach-imx/qb.h b/arch/arm/include/asm/mach-imx/qb.h
> > index 5efe68f0a60..4f923d79e7a 100644
> > --- a/arch/arm/include/asm/mach-imx/qb.h
> > +++ b/arch/arm/include/asm/mach-imx/qb.h
> > @@ -10,4 +10,6 @@
> >
> > bool qb_check(void);
> > int qb(int qb_dev, int qb_bootdev, bool save);
> > +void spl_qb_save(void);
> > +
> > #endif
> > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > index 17aad696648..069b25c6241 100644
> > --- a/arch/arm/mach-imx/Kconfig
> > +++ b/arch/arm/mach-imx/Kconfig
> > @@ -71,6 +71,13 @@ config CSF_SIZE
> > Define the maximum size for Command Sequence File (CSF) binary
> > this information is used to define the image boot data.
> >
> > +config SPL_IMX_QB
> > + bool "Run qb save during SPL"
> > + default n
> > + depends on SPL && IMX_SNPS_DDR_PHY_QB_GEN && (IMX95 || IMX94)
> > + help
> > + Run qb save on bootdev automatically during SPL.
> > +
> > config CMD_IMX_QB
> > bool "Support the 'qb' command"
> > default y
> > diff --git a/arch/arm/mach-imx/imx9/Makefile b/arch/arm/mach-imx/imx9/Makefile
> > index 7dee144e0f4..3207013812a 100644
> > --- a/arch/arm/mach-imx/imx9/Makefile
> > +++ b/arch/arm/mach-imx/imx9/Makefile
> > @@ -15,7 +15,9 @@ obj-y += imx_bootaux.o
> > endif
> >
> > ifeq ($(CONFIG_IMX_SNPS_DDR_PHY_QB_GEN),y)
> > -ifneq ($(CONFIG_XPL_BUILD),y)
> > +ifeq ($(CONFIG_XPL_BUILD),y)
> > +obj-$(CONFIG_SPL_IMX_QB) += qb.o
> > +else
> > obj-$(CONFIG_CMD_IMX_QB) += qb.o
> > endif
> > endif
> > diff --git a/arch/arm/mach-imx/imx9/qb.c b/arch/arm/mach-imx/imx9/qb.c
> > index fc01d8e22e9..79573741d39 100644
> > --- a/arch/arm/mach-imx/imx9/qb.c
> > +++ b/arch/arm/mach-imx/imx9/qb.c
> > @@ -428,3 +428,12 @@ int qb(int qb_dev, int qb_bootdev, bool save)
> >
> > return 0;
> > }
> > +
> > +void spl_qb_save(void)
> > +{
> > + int dev = spl_boot_device();
> > +
> > + /** Save QB data on current boot device */
> > + if (qb(dev, dev, true))
> > + printf("QB save failed\n");
> > +}
> > diff --git a/board/nxp/imx94_evk/spl.c b/board/nxp/imx94_evk/spl.c
> > index cc5b7f9ef0f..1d25795eb17 100644
> > --- a/board/nxp/imx94_evk/spl.c
> > +++ b/board/nxp/imx94_evk/spl.c
> > @@ -1,6 +1,6 @@
> > // SPDX-License-Identifier: GPL-2.0+
> > /*
> > - * Copyright 2025 NXP
> > + * Copyright 2025-2026 NXP
> > */
> >
> > #include <hang.h>
> > @@ -14,6 +14,7 @@
> > #include <asm/arch/sys_proto.h>
> > #include <asm/mach-imx/boot_mode.h>
> > #include <asm/mach-imx/ele_api.h>
> > +#include <asm/mach-imx/qb.h>
> >
> > DECLARE_GLOBAL_DATA_PTR;
> >
> > @@ -44,6 +45,9 @@ void spl_board_init(void)
> > ret = ele_start_rng();
> > if (ret)
> > printf("Fail to start RNG: %d\n", ret);
> > +
> > + if (IS_ENABLED(CONFIG_SPL_IMX_QB))
> > + spl_qb_save();
> Does it write to MMC/NOR/SD at every boot? Is that necessary if a quick boot
> was performed and the data has not changed?
> > }
No, the qb() method calls qb_check, which returns true only if OEI
saved valid data to volatile memory (meaning it has run Training flow).
So, if Quickboot flow is run, the data in volatile memory is not valid,
qb_check fails -> qb returns and does not write anything to the NVM.
Also, another thing to keep in mind is that after a successfull
qb save, the data in volatile memory is invalidated -> qb check will
fail as well even if OEI doesn't run (so on a warm reboot).
> >
> > /* SCMI support by default */
> > diff --git a/board/nxp/imx95_evk/spl.c b/board/nxp/imx95_evk/spl.c
> > index 761a1a4a0f6..35e4458f2b7 100644
> > --- a/board/nxp/imx95_evk/spl.c
> > +++ b/board/nxp/imx95_evk/spl.c
> > @@ -1,6 +1,6 @@
> > // SPDX-License-Identifier: GPL-2.0+
> > /*
> > - * Copyright 2025 NXP
> > + * Copyright 2025-2026 NXP
> > */
> >
> > #include <hang.h>
> > @@ -13,6 +13,7 @@
> > #include <asm/arch/sys_proto.h>
> > #include <asm/mach-imx/boot_mode.h>
> > #include <asm/mach-imx/ele_api.h>
> > +#include <asm/mach-imx/qb.h>
> >
> > DECLARE_GLOBAL_DATA_PTR;
> >
> > @@ -41,6 +42,9 @@ void spl_board_init(void)
> > ret = ele_start_rng();
> > if (ret)
> > printf("Fail to start RNG: %d\n", ret);
> > +
> > + if (IS_ENABLED(CONFIG_SPL_IMX_QB))
> > + spl_qb_save();
> > }
> >
> > void board_init_f(ulong dummy)
>
> Kind regards,
> Emanuele
>
Best regards,
Simona
More information about the U-Boot
mailing list