* [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-17 14:54 ` Sean Anderson
2026-02-18 8:42 ` Anshul Dalal
2026-02-17 11:21 ` [PATCH 2/7] spl: mtd: Remove MTD device after loading images Anurag Dutta
` (6 subsequent siblings)
7 siblings, 2 replies; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Apurva Nandan <a-nandan@ti.com>
Introduce support for using MTD subsystem for loading images from
memory flashes. This will provide the support of using mtd functions
which are abstracted over the type of flash being used, to load the
boot images from the flash.
Currently, add support for only SPI NAND flashes. This can be extended
to all other flash types, when required.
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
common/spl/spl_mtd.c | 90 +++++++++++++++++++++++++++++++++++++++
common/spl/spl_mtd_nand.c | 31 ++++++++++++++
include/spl.h | 18 ++++++++
3 files changed, 139 insertions(+)
create mode 100644 common/spl/spl_mtd.c
create mode 100644 common/spl/spl_mtd_nand.c
diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
new file mode 100644
index 00000000000..341e1a73392
--- /dev/null
+++ b/common/spl/spl_mtd.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * FIT image loader functions using MTD read
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
+ * Apurva Nandan <a-nandan@ti.com>
+ */
+#include <config.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <mtd.h>
+
+uint32_t __weak spl_mtd_get_uboot_offs(void)
+{
+ return CONFIG_SYS_MTD_U_BOOT_OFFS;
+}
+
+static ulong spl_mtd_fit_read(struct spl_load_info *load, ulong offs,
+ ulong size, void *dst)
+{
+ struct mtd_info *mtd = load->priv;
+ int err;
+ size_t ret_len;
+
+ err = mtd_read(mtd, offs, size, &ret_len, dst);
+ if (!err)
+ return ret_len;
+
+ return 0;
+}
+
+struct mtd_info *spl_prepare_mtd(uint boot_device)
+{
+ struct mtd_info *mtd = NULL;
+
+ mtd_probe_devices();
+
+ switch (boot_device) {
+ case BOOT_DEVICE_SPINAND:
+ mtd = get_mtd_device_nm("spi-nand0");
+ break;
+ default:
+ puts(PHASE_PROMPT "Unsupported MTD Boot Device!\n");
+ break;
+ }
+
+ return mtd;
+}
+
+int spl_mtd_load(struct spl_image_info *spl_image,
+ struct mtd_info *mtd, struct spl_boot_device *bootdev)
+{
+ int err;
+ struct legacy_img_hdr *header;
+ __maybe_unused struct spl_load_info load;
+ size_t ret_len;
+
+ header = spl_get_load_buffer(0, sizeof(*header));
+
+ err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
+ &ret_len, (void *)header);
+ if (err)
+ return err;
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ debug("Found FIT\n");
+ load.priv = mtd;
+ load.bl_len = 1;
+ load.read = spl_mtd_fit_read;
+ return spl_load_simple_fit(spl_image, &load,
+ spl_mtd_get_uboot_offs(), header);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ load.priv = mtd;
+ load.bl_len = 1;
+ load.read = spl_mtd_fit_read;
+ return spl_load_imx_container(spl_image, &load,
+ spl_mtd_get_uboot_offs());
+ } else {
+ err = spl_parse_image_header(spl_image, bootdev, header);
+ if (err)
+ return err;
+ return mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
+ &ret_len, (void *)(ulong)spl_image->load_addr);
+ }
+
+ return -EINVAL;
+}
diff --git a/common/spl/spl_mtd_nand.c b/common/spl/spl_mtd_nand.c
new file mode 100644
index 00000000000..9bc6ff86ee8
--- /dev/null
+++ b/common/spl/spl_mtd_nand.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * FIT image loader using MTD read
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
+ * Anurag Dutta <a-dutta@ti.com>
+ */
+#include <config.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <mtd.h>
+
+static int spl_mtd_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct mtd_info *mtd;
+ int ret;
+
+ mtd = spl_prepare_mtd(BOOT_DEVICE_SPINAND);
+ if (IS_ERR_OR_NULL(mtd)) {
+ printf("MTD device %s not found, ret %ld\n", "spi-nand",
+ PTR_ERR(mtd));
+ return -EINVAL;
+ }
+
+ return spl_mtd_load(spl_image, mtd, bootdev);
+}
+
+SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_mtd_load_image);
diff --git a/include/spl.h b/include/spl.h
index 06dc28362d3..c4442be4fdb 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -1219,4 +1219,22 @@ int spl_reloc_prepare(struct spl_image_info *image, ulong *addrp);
*/
int spl_reloc_jump(struct spl_image_info *image, spl_jump_to_image_t func);
+/* SPL MTD functions */
+/**
+ * spl_prepare_mtd() - Prepares the mtd for the corresponidng boot device
+ *
+ * @boot_device: A number indicating the BOOT_DEVICE type
+ */
+struct mtd_info *spl_prepare_mtd(uint boot_device);
+
+/**
+ * spl_mtd_load() - FIT Image loader
+ *
+ * @spl_image: SPL image to jump to
+ * @mtd: MTD device descriptor with geometry, flags, and read/write/erase function pointers
+ * @bootdev: boot device used by SPL
+ */
+int spl_mtd_load(struct spl_image_info *spl_image, struct mtd_info *mtd,
+ struct spl_boot_device *bootdev);
+
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD
2026-02-17 11:21 ` [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD Anurag Dutta
@ 2026-02-17 14:54 ` Sean Anderson
2026-02-17 15:14 ` Sean Anderson
2026-02-18 8:42 ` Anshul Dalal
1 sibling, 1 reply; 15+ messages in thread
From: Sean Anderson @ 2026-02-17 14:54 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
On 2/17/26 06:21, Anurag Dutta wrote:
> From: Apurva Nandan <a-nandan@ti.com>
>
> Introduce support for using MTD subsystem for loading images from
> memory flashes. This will provide the support of using mtd functions
> which are abstracted over the type of flash being used, to load the
> boot images from the flash.
>
> Currently, add support for only SPI NAND flashes. This can be extended
> to all other flash types, when required.
>
> Signed-off-by: Apurva Nandan <a-nandan@ti.com>
> Signed-off-by: Anurag Dutta <a-dutta@ti.com>
> ---
> common/spl/spl_mtd.c | 90 +++++++++++++++++++++++++++++++++++++++
> common/spl/spl_mtd_nand.c | 31 ++++++++++++++
> include/spl.h | 18 ++++++++
> 3 files changed, 139 insertions(+)
> create mode 100644 common/spl/spl_mtd.c
> create mode 100644 common/spl/spl_mtd_nand.c
>
> diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
> new file mode 100644
> index 00000000000..341e1a73392
> --- /dev/null
> +++ b/common/spl/spl_mtd.c
> @@ -0,0 +1,90 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * FIT image loader functions using MTD read
> + *
> + * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
> + * Apurva Nandan <a-nandan@ti.com>
> + */
> +#include <config.h>
> +#include <image.h>
> +#include <log.h>
> +#include <spl.h>
> +#include <asm/io.h>
> +#include <mtd.h>
> +
> +uint32_t __weak spl_mtd_get_uboot_offs(void)
> +{
> + return CONFIG_SYS_MTD_U_BOOT_OFFS;
> +}
> +
> +static ulong spl_mtd_fit_read(struct spl_load_info *load, ulong offs,
> + ulong size, void *dst)
> +{
> + struct mtd_info *mtd = load->priv;
> + int err;
> + size_t ret_len;
> +
> + err = mtd_read(mtd, offs, size, &ret_len, dst);
> + if (!err)
> + return ret_len;
> +
> + return 0;
> +}
> +
> +struct mtd_info *spl_prepare_mtd(uint boot_device)
> +{
> + struct mtd_info *mtd = NULL;
> +
> + mtd_probe_devices();
> +
> + switch (boot_device) {
> + case BOOT_DEVICE_SPINAND:
> + mtd = get_mtd_device_nm("spi-nand0");
> + break;
> + default:
> + puts(PHASE_PROMPT "Unsupported MTD Boot Device!\n");
> + break;
> + }
> +
> + return mtd;
> +}
> +
> +int spl_mtd_load(struct spl_image_info *spl_image,
> + struct mtd_info *mtd, struct spl_boot_device *bootdev)
> +{
> + int err;
> + struct legacy_img_hdr *header;
> + __maybe_unused struct spl_load_info load;
> + size_t ret_len;
> +
> + header = spl_get_load_buffer(0, sizeof(*header));
> +
> + err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
> + &ret_len, (void *)header);
> + if (err)
> + return err;
> +
> + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
> + image_get_magic(header) == FDT_MAGIC) {
> + debug("Found FIT\n");
> + load.priv = mtd;
> + load.bl_len = 1;
> + load.read = spl_mtd_fit_read;
> + return spl_load_simple_fit(spl_image, &load,
> + spl_mtd_get_uboot_offs(), header);
> + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
> + load.priv = mtd;
> + load.bl_len = 1;
> + load.read = spl_mtd_fit_read;
> + return spl_load_imx_container(spl_image, &load,
> + spl_mtd_get_uboot_offs());
> + } else {
> + err = spl_parse_image_header(spl_image, bootdev, header);
> + if (err)
> + return err;
> + return mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
> + &ret_len, (void *)(ulong)spl_image->load_addr);
> + }
>
Please use spl_load instead of hard-coding the image types. Thanks.
--Sean
> + return -EINVAL;
> +}
> diff --git a/common/spl/spl_mtd_nand.c b/common/spl/spl_mtd_nand.c
> new file mode 100644
> index 00000000000..9bc6ff86ee8
> --- /dev/null
> +++ b/common/spl/spl_mtd_nand.c
> @@ -0,0 +1,31 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * FIT image loader using MTD read
> + *
> + * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
> + * Anurag Dutta <a-dutta@ti.com>
> + */
> +#include <config.h>
> +#include <image.h>
> +#include <log.h>
> +#include <spl.h>
> +#include <asm/io.h>
> +#include <mtd.h>
> +
> +static int spl_mtd_load_image(struct spl_image_info *spl_image,
> + struct spl_boot_device *bootdev)
> +{
> + struct mtd_info *mtd;
> + int ret;
> +
> + mtd = spl_prepare_mtd(BOOT_DEVICE_SPINAND);
> + if (IS_ERR_OR_NULL(mtd)) {
> + printf("MTD device %s not found, ret %ld\n", "spi-nand",
> + PTR_ERR(mtd));
> + return -EINVAL;
> + }
> +
> + return spl_mtd_load(spl_image, mtd, bootdev);
> +}
> +
> +SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_mtd_load_image);
> diff --git a/include/spl.h b/include/spl.h
> index 06dc28362d3..c4442be4fdb 100644
> --- a/include/spl.h
> +++ b/include/spl.h
> @@ -1219,4 +1219,22 @@ int spl_reloc_prepare(struct spl_image_info *image, ulong *addrp);
> */
> int spl_reloc_jump(struct spl_image_info *image, spl_jump_to_image_t func);
>
> +/* SPL MTD functions */
> +/**
> + * spl_prepare_mtd() - Prepares the mtd for the corresponidng boot device
> + *
> + * @boot_device: A number indicating the BOOT_DEVICE type
> + */
> +struct mtd_info *spl_prepare_mtd(uint boot_device);
> +
> +/**
> + * spl_mtd_load() - FIT Image loader
> + *
> + * @spl_image: SPL image to jump to
> + * @mtd: MTD device descriptor with geometry, flags, and read/write/erase function pointers
> + * @bootdev: boot device used by SPL
> + */
> +int spl_mtd_load(struct spl_image_info *spl_image, struct mtd_info *mtd,
> + struct spl_boot_device *bootdev);
> +
> #endif
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD
2026-02-17 14:54 ` Sean Anderson
@ 2026-02-17 15:14 ` Sean Anderson
0 siblings, 0 replies; 15+ messages in thread
From: Sean Anderson @ 2026-02-17 15:14 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
On 2/17/26 09:54, Sean Anderson wrote:
> On 2/17/26 06:21, Anurag Dutta wrote:
>> From: Apurva Nandan <a-nandan@ti.com>
>>
>> Introduce support for using MTD subsystem for loading images from
>> memory flashes. This will provide the support of using mtd functions
>> which are abstracted over the type of flash being used, to load the
>> boot images from the flash.
>>
>> Currently, add support for only SPI NAND flashes. This can be extended
>> to all other flash types, when required.
>>
>> Signed-off-by: Apurva Nandan <a-nandan@ti.com>
>> Signed-off-by: Anurag Dutta <a-dutta@ti.com>
>> ---
>> common/spl/spl_mtd.c | 90 +++++++++++++++++++++++++++++++++++++++
>> common/spl/spl_mtd_nand.c | 31 ++++++++++++++
>> include/spl.h | 18 ++++++++
>> 3 files changed, 139 insertions(+)
>> create mode 100644 common/spl/spl_mtd.c
>> create mode 100644 common/spl/spl_mtd_nand.c
>>
>> diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
>> new file mode 100644
>> index 00000000000..341e1a73392
>> --- /dev/null
>> +++ b/common/spl/spl_mtd.c
>> @@ -0,0 +1,90 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * FIT image loader functions using MTD read
>> + *
>> + * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
>> + * Apurva Nandan <a-nandan@ti.com>
>> + */
>> +#include <config.h>
>> +#include <image.h>
>> +#include <log.h>
>> +#include <spl.h>
>> +#include <asm/io.h>
>> +#include <mtd.h>
>> +
>> +uint32_t __weak spl_mtd_get_uboot_offs(void)
>> +{
>> + return CONFIG_SYS_MTD_U_BOOT_OFFS;
>> +}
>> +
>> +static ulong spl_mtd_fit_read(struct spl_load_info *load, ulong offs,
>> + ulong size, void *dst)
>> +{
>> + struct mtd_info *mtd = load->priv;
>> + int err;
>> + size_t ret_len;
>> +
>> + err = mtd_read(mtd, offs, size, &ret_len, dst);
>> + if (!err)
>> + return ret_len;
>> +
>> + return 0;
>> +}
>> +
>> +struct mtd_info *spl_prepare_mtd(uint boot_device)
>> +{
>> + struct mtd_info *mtd = NULL;
>> +
>> + mtd_probe_devices();
>> +
>> + switch (boot_device) {
>> + case BOOT_DEVICE_SPINAND:
>> + mtd = get_mtd_device_nm("spi-nand0");
>> + break;
>> + default:
>> + puts(PHASE_PROMPT "Unsupported MTD Boot Device!\n");
>> + break;
>> + }
>> +
>> + return mtd;
>> +}
>> +
>> +int spl_mtd_load(struct spl_image_info *spl_image,
>> + struct mtd_info *mtd, struct spl_boot_device *bootdev)
>> +{
>> + int err;
>> + struct legacy_img_hdr *header;
>> + __maybe_unused struct spl_load_info load;
>> + size_t ret_len;
>> +
>> + header = spl_get_load_buffer(0, sizeof(*header));
>> +
>> + err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
>> + &ret_len, (void *)header);
>> + if (err)
>> + return err;
>> +
>> + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
>> + image_get_magic(header) == FDT_MAGIC) {
>> + debug("Found FIT\n");
>> + load.priv = mtd;
>> + load.bl_len = 1;
>> + load.read = spl_mtd_fit_read;
>> + return spl_load_simple_fit(spl_image, &load,
>> + spl_mtd_get_uboot_offs(), header);
>> + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
>> + load.priv = mtd;
>> + load.bl_len = 1;
>> + load.read = spl_mtd_fit_read;
>> + return spl_load_imx_container(spl_image, &load,
>> + spl_mtd_get_uboot_offs());
>> + } else {
>> + err = spl_parse_image_header(spl_image, bootdev, header);
>> + if (err)
>> + return err;
>> + return mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
>> + &ret_len, (void *)(ulong)spl_image->load_addr);
>> + }
>>
>
> Please use spl_load instead of hard-coding the image types. Thanks.
>
> --Sean
https://lore.kernel.org/u-boot/2b5ebaa9-76f1-e2b0-4e8c-fc8b6c197136@gmail.com/T/#m4f33f294f050574baafef1cbfaa7e88a2a47eb5c
has a very similar approach.
--Sean
>> + return -EINVAL;
>> +}
>> diff --git a/common/spl/spl_mtd_nand.c b/common/spl/spl_mtd_nand.c
>> new file mode 100644
>> index 00000000000..9bc6ff86ee8
>> --- /dev/null
>> +++ b/common/spl/spl_mtd_nand.c
>> @@ -0,0 +1,31 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * FIT image loader using MTD read
>> + *
>> + * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
>> + * Anurag Dutta <a-dutta@ti.com>
>> + */
>> +#include <config.h>
>> +#include <image.h>
>> +#include <log.h>
>> +#include <spl.h>
>> +#include <asm/io.h>
>> +#include <mtd.h>
>> +
>> +static int spl_mtd_load_image(struct spl_image_info *spl_image,
>> + struct spl_boot_device *bootdev)
>> +{
>> + struct mtd_info *mtd;
>> + int ret;
>> +
>> + mtd = spl_prepare_mtd(BOOT_DEVICE_SPINAND);
>> + if (IS_ERR_OR_NULL(mtd)) {
>> + printf("MTD device %s not found, ret %ld\n", "spi-nand",
>> + PTR_ERR(mtd));
>> + return -EINVAL;
>> + }
>> +
>> + return spl_mtd_load(spl_image, mtd, bootdev);
>> +}
>> +
>> +SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_mtd_load_image);
>> diff --git a/include/spl.h b/include/spl.h
>> index 06dc28362d3..c4442be4fdb 100644
>> --- a/include/spl.h
>> +++ b/include/spl.h
>> @@ -1219,4 +1219,22 @@ int spl_reloc_prepare(struct spl_image_info *image, ulong *addrp);
>> */
>> int spl_reloc_jump(struct spl_image_info *image, spl_jump_to_image_t func);
>> +/* SPL MTD functions */
>> +/**
>> + * spl_prepare_mtd() - Prepares the mtd for the corresponidng boot device
>> + *
>> + * @boot_device: A number indicating the BOOT_DEVICE type
>> + */
>> +struct mtd_info *spl_prepare_mtd(uint boot_device);
>> +
>> +/**
>> + * spl_mtd_load() - FIT Image loader
>> + *
>> + * @spl_image: SPL image to jump to
>> + * @mtd: MTD device descriptor with geometry, flags, and read/write/erase function pointers
>> + * @bootdev: boot device used by SPL
>> + */
>> +int spl_mtd_load(struct spl_image_info *spl_image, struct mtd_info *mtd,
>> + struct spl_boot_device *bootdev);
>> +
>> #endif
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD
2026-02-17 11:21 ` [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD Anurag Dutta
2026-02-17 14:54 ` Sean Anderson
@ 2026-02-18 8:42 ` Anshul Dalal
1 sibling, 0 replies; 15+ messages in thread
From: Anshul Dalal @ 2026-02-18 8:42 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
On Tue Feb 17, 2026 at 4:51 PM IST, Anurag Dutta wrote:
> From: Apurva Nandan <a-nandan@ti.com>
>
> Introduce support for using MTD subsystem for loading images from
> memory flashes. This will provide the support of using mtd functions
> which are abstracted over the type of flash being used, to load the
> boot images from the flash.
>
> Currently, add support for only SPI NAND flashes. This can be extended
> to all other flash types, when required.
>
> Signed-off-by: Apurva Nandan <a-nandan@ti.com>
> Signed-off-by: Anurag Dutta <a-dutta@ti.com>
Asides form what Sean said, I have a few comments below:
> ---
> common/spl/spl_mtd.c | 90 +++++++++++++++++++++++++++++++++++++++
> common/spl/spl_mtd_nand.c | 31 ++++++++++++++
> include/spl.h | 18 ++++++++
> 3 files changed, 139 insertions(+)
> create mode 100644 common/spl/spl_mtd.c
> create mode 100644 common/spl/spl_mtd_nand.c
>
> diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
> new file mode 100644
> index 00000000000..341e1a73392
> --- /dev/null
> +++ b/common/spl/spl_mtd.c
> @@ -0,0 +1,90 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * FIT image loader functions using MTD read
> + *
> + * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
> + * Apurva Nandan <a-nandan@ti.com>
> + */
> +#include <config.h>
> +#include <image.h>
> +#include <log.h>
> +#include <spl.h>
> +#include <asm/io.h>
> +#include <mtd.h>
> +
> +uint32_t __weak spl_mtd_get_uboot_offs(void)
> +{
> + return CONFIG_SYS_MTD_U_BOOT_OFFS;
NIT: The symbol is used here but is not added until 4/7 of the series.
> +}
> +
> +static ulong spl_mtd_fit_read(struct spl_load_info *load, ulong offs,
> + ulong size, void *dst)
> +{
> + struct mtd_info *mtd = load->priv;
> + int err;
> + size_t ret_len;
> +
> + err = mtd_read(mtd, offs, size, &ret_len, dst);
> + if (!err)
> + return ret_len;
> +
> + return 0;
> +}
> +
> +struct mtd_info *spl_prepare_mtd(uint boot_device)
> +{
> + struct mtd_info *mtd = NULL;
> +
> + mtd_probe_devices();
> +
> + switch (boot_device) {
> + case BOOT_DEVICE_SPINAND:
> + mtd = get_mtd_device_nm("spi-nand0");
> + break;
> + default:
> + puts(PHASE_PROMPT "Unsupported MTD Boot Device!\n");
> + break;
> + }
> +
> + return mtd;
> +}
> +
> +int spl_mtd_load(struct spl_image_info *spl_image,
> + struct mtd_info *mtd, struct spl_boot_device *bootdev)
> +{
> + int err;
> + struct legacy_img_hdr *header;
> + __maybe_unused struct spl_load_info load;
> + size_t ret_len;
> +
> + header = spl_get_load_buffer(0, sizeof(*header));
> +
> + err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
> + &ret_len, (void *)header);
> + if (err)
> + return err;
> +
> + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
> + image_get_magic(header) == FDT_MAGIC) {
> + debug("Found FIT\n");
> + load.priv = mtd;
> + load.bl_len = 1;
> + load.read = spl_mtd_fit_read;
> + return spl_load_simple_fit(spl_image, &load,
> + spl_mtd_get_uboot_offs(), header);
> + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
> + load.priv = mtd;
> + load.bl_len = 1;
> + load.read = spl_mtd_fit_read;
> + return spl_load_imx_container(spl_image, &load,
> + spl_mtd_get_uboot_offs());
> + } else {
> + err = spl_parse_image_header(spl_image, bootdev, header);
> + if (err)
> + return err;
> + return mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
> + &ret_len, (void *)(ulong)spl_image->load_addr);
> + }
> +
> + return -EINVAL;
> +}
> diff --git a/common/spl/spl_mtd_nand.c b/common/spl/spl_mtd_nand.c
> new file mode 100644
> index 00000000000..9bc6ff86ee8
> --- /dev/null
> +++ b/common/spl/spl_mtd_nand.c
> @@ -0,0 +1,31 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * FIT image loader using MTD read
> + *
> + * Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/
> + * Anurag Dutta <a-dutta@ti.com>
> + */
> +#include <config.h>
> +#include <image.h>
> +#include <log.h>
> +#include <spl.h>
> +#include <asm/io.h>
> +#include <mtd.h>
> +
> +static int spl_mtd_load_image(struct spl_image_info *spl_image,
> + struct spl_boot_device *bootdev)
> +{
> + struct mtd_info *mtd;
> + int ret;
> +
> + mtd = spl_prepare_mtd(BOOT_DEVICE_SPINAND);
> + if (IS_ERR_OR_NULL(mtd)) {
> + printf("MTD device %s not found, ret %ld\n", "spi-nand",
> + PTR_ERR(mtd));
> + return -EINVAL;
> + }
> +
> + return spl_mtd_load(spl_image, mtd, bootdev);
> +}
> +
> +SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_mtd_load_image);
> diff --git a/include/spl.h b/include/spl.h
> index 06dc28362d3..c4442be4fdb 100644
> --- a/include/spl.h
> +++ b/include/spl.h
> @@ -1219,4 +1219,22 @@ int spl_reloc_prepare(struct spl_image_info *image, ulong *addrp);
> */
> int spl_reloc_jump(struct spl_image_info *image, spl_jump_to_image_t func);
>
> +/* SPL MTD functions */
> +/**
> + * spl_prepare_mtd() - Prepares the mtd for the corresponidng boot device
> + *
> + * @boot_device: A number indicating the BOOT_DEVICE type
> + */
> +struct mtd_info *spl_prepare_mtd(uint boot_device);
> +
> +/**
> + * spl_mtd_load() - FIT Image loader
> + *
> + * @spl_image: SPL image to jump to
> + * @mtd: MTD device descriptor with geometry, flags, and read/write/erase function pointers
> + * @bootdev: boot device used by SPL
> + */
> +int spl_mtd_load(struct spl_image_info *spl_image, struct mtd_info *mtd,
> + struct spl_boot_device *bootdev);
> +
> #endif
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 2/7] spl: mtd: Remove MTD device after loading images
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
2026-02-17 11:21 ` [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-17 11:21 ` [PATCH 3/7] spl: mtd: Add bad block handling for SPL image loading Anurag Dutta
` (5 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Apurva Nandan <a-nandan@ti.com>
Releasing the flash into proper state, after the loading completes,
is important for the next stage bootloader/kernel to be able to use
the MTD device. This would enable to reset the device for fresh
use by next boot stage.
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
common/spl/spl_mtd.c | 19 ++++++++++---------
common/spl/spl_mtd_nand.c | 10 +++++++---
drivers/mtd/mtd-uclass.c | 12 ++++++++++++
drivers/mtd/nand/spi/core.c | 12 ++++++++----
include/mtd.h | 2 +-
5 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
index 341e1a73392..95c0c8ce8cd 100644
--- a/common/spl/spl_mtd.c
+++ b/common/spl/spl_mtd.c
@@ -62,7 +62,7 @@ int spl_mtd_load(struct spl_image_info *spl_image,
err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
&ret_len, (void *)header);
if (err)
- return err;
+ goto out_err;
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
image_get_magic(header) == FDT_MAGIC) {
@@ -70,21 +70,22 @@ int spl_mtd_load(struct spl_image_info *spl_image,
load.priv = mtd;
load.bl_len = 1;
load.read = spl_mtd_fit_read;
- return spl_load_simple_fit(spl_image, &load,
- spl_mtd_get_uboot_offs(), header);
+ err = spl_load_simple_fit(spl_image, &load,
+ spl_mtd_get_uboot_offs(), header);
} else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
load.priv = mtd;
load.bl_len = 1;
load.read = spl_mtd_fit_read;
- return spl_load_imx_container(spl_image, &load,
- spl_mtd_get_uboot_offs());
+ err = spl_load_imx_container(spl_image, &load,
+ spl_mtd_get_uboot_offs());
} else {
err = spl_parse_image_header(spl_image, bootdev, header);
if (err)
- return err;
- return mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
- &ret_len, (void *)(ulong)spl_image->load_addr);
+ goto out_err;
+ err = mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
+ &ret_len, (void *)(ulong)spl_image->load_addr);
}
- return -EINVAL;
+out_err:
+ return err;
}
diff --git a/common/spl/spl_mtd_nand.c b/common/spl/spl_mtd_nand.c
index 9bc6ff86ee8..2eb7458e599 100644
--- a/common/spl/spl_mtd_nand.c
+++ b/common/spl/spl_mtd_nand.c
@@ -16,16 +16,20 @@ static int spl_mtd_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
struct mtd_info *mtd;
- int ret;
+ int err;
mtd = spl_prepare_mtd(BOOT_DEVICE_SPINAND);
if (IS_ERR_OR_NULL(mtd)) {
printf("MTD device %s not found, ret %ld\n", "spi-nand",
PTR_ERR(mtd));
- return -EINVAL;
+ err = PTR_ERR(mtd);
+ goto remove_mtd_device;
}
- return spl_mtd_load(spl_image, mtd, bootdev);
+ err = spl_mtd_load(spl_image, mtd, bootdev);
+remove_mtd_device:
+ mtd_remove(mtd);
+ return err;
}
SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_mtd_load_image);
diff --git a/drivers/mtd/mtd-uclass.c b/drivers/mtd/mtd-uclass.c
index 720bd824c4d..598eedae6a5 100644
--- a/drivers/mtd/mtd-uclass.c
+++ b/drivers/mtd/mtd-uclass.c
@@ -10,6 +10,18 @@
#include <errno.h>
#include <mtd.h>
+/**
+ * mtd_remove - Remove the device @dev
+ *
+ * @dev: U-Boot device to probe
+ *
+ * @return 0 on success, an error otherwise.
+ */
+int mtd_remove(struct mtd_info *mtd)
+{
+ return device_remove(mtd->dev, DM_REMOVE_NORMAL);
+}
+
/*
* Implement a MTD uclass which should include most flash drivers.
* The uclass private is pointed to mtd_info.
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 14af4264612..9bd8cce58f2 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1718,26 +1718,28 @@ err_spinand_cleanup:
return ret;
}
-#ifndef __UBOOT__
static int spinand_remove(struct udevice *slave)
{
struct spinand_device *spinand;
struct mtd_info *mtd;
- int ret;
+ int ret = 0;
- spinand = spi_mem_get_drvdata(slave);
+ spinand = dev_get_priv(slave);
mtd = spinand_to_mtd(spinand);
free(mtd->name);
+#ifndef __UBOOT__
ret = mtd_device_unregister(mtd);
if (ret)
return ret;
+#endif
spinand_cleanup(spinand);
- return 0;
+ return ret;
}
+#ifndef __UBOOT__
static const struct spi_device_id spinand_ids[] = {
{ .name = "spi-nand" },
{ /* sentinel */ },
@@ -1783,4 +1785,6 @@ U_BOOT_DRIVER(spinand) = {
.probe = spinand_probe,
.bind = spinand_bind,
.plat_auto = sizeof(struct spinand_plat),
+ .remove = spinand_remove,
+ .flags = DM_FLAG_OS_PREPARE,
};
diff --git a/include/mtd.h b/include/mtd.h
index f9e5082446a..740f1bb76db 100644
--- a/include/mtd.h
+++ b/include/mtd.h
@@ -11,7 +11,7 @@
#include <linux/mtd/mtd.h>
int mtd_probe_devices(void);
-
+int mtd_remove(struct mtd_info *mtd);
void board_mtdparts_default(const char **mtdids, const char **mtdparts);
/* compute the max size for the string associated to a dev type */
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 3/7] spl: mtd: Add bad block handling for SPL image loading
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
2026-02-17 11:21 ` [PATCH 1/7] common: spl: mtd: Add support for loading images from MTD Anurag Dutta
2026-02-17 11:21 ` [PATCH 2/7] spl: mtd: Remove MTD device after loading images Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-19 8:38 ` Anshul Dalal
2026-02-17 11:21 ` [PATCH 4/7] spl: Add MTD loading support configuration Anurag Dutta
` (4 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Santhosh Kumar K <s-k6@ti.com>
Implement bad block skipping functionality in SPL MTD loader to ensure
reliable boot from flash devices with bad blocks. Without this, the
SPL would fail to load images if bad blocks were encountered.
Signed-off-by: Santhosh Kumar K <s-k6@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
common/spl/spl_mtd.c | 78 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 68 insertions(+), 10 deletions(-)
diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
index 95c0c8ce8cd..d635aa2b476 100644
--- a/common/spl/spl_mtd.c
+++ b/common/spl/spl_mtd.c
@@ -17,15 +17,64 @@ uint32_t __weak spl_mtd_get_uboot_offs(void)
return CONFIG_SYS_MTD_U_BOOT_OFFS;
}
+static ulong spl_mtd_read_skip_bad(struct mtd_info *mtd, loff_t offs,
+ size_t size, void *dst)
+{
+ size_t remaining = size;
+ size_t ret_len;
+ loff_t current_offs = offs;
+ loff_t block_aligned_offs, next_block;
+ u_char *buf = (u_char *)dst;
+ int err;
+
+ while (remaining > 0) {
+ size_t read_size;
+ size_t block_remaining;
+
+ block_aligned_offs = current_offs & ~(mtd->erasesize - 1);
+
+ if (mtd_block_isbad(mtd, block_aligned_offs)) {
+ debug("SPL: Skipping bad block at 0x%llx, jumping to 0x%llx\n",
+ block_aligned_offs, next_block);
+
+ next_block = block_aligned_offs + mtd->erasesize;
+ current_offs = next_block;
+ continue;
+ }
+
+ block_remaining = mtd->erasesize -
+ (current_offs & (mtd->erasesize - 1));
+ read_size = remaining < block_remaining ? remaining : block_remaining;
+
+ err = mtd_read(mtd, current_offs, read_size, &ret_len, buf);
+ if (err) {
+ printf("SPL: Read error at offset 0x%llx: %d\n",
+ current_offs, err);
+ return size - remaining;
+ }
+
+ buf += ret_len;
+ current_offs += ret_len;
+ remaining -= ret_len;
+
+ if (current_offs >= mtd->size) {
+ printf("SPL: Reached end of device, read %zu/%zu bytes\n",
+ size - remaining, size);
+ break;
+ }
+ }
+
+ return size - remaining;
+}
+
static ulong spl_mtd_fit_read(struct spl_load_info *load, ulong offs,
ulong size, void *dst)
{
struct mtd_info *mtd = load->priv;
- int err;
size_t ret_len;
- err = mtd_read(mtd, offs, size, &ret_len, dst);
- if (!err)
+ ret_len = spl_mtd_read_skip_bad(mtd, offs, size, dst);
+ if (ret_len > 0)
return ret_len;
return 0;
@@ -52,17 +101,19 @@ struct mtd_info *spl_prepare_mtd(uint boot_device)
int spl_mtd_load(struct spl_image_info *spl_image,
struct mtd_info *mtd, struct spl_boot_device *bootdev)
{
- int err;
+ int err = 0;
struct legacy_img_hdr *header;
__maybe_unused struct spl_load_info load;
size_t ret_len;
header = spl_get_load_buffer(0, sizeof(*header));
-
- err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
- &ret_len, (void *)header);
- if (err)
+ ret_len = spl_mtd_read_skip_bad(mtd, spl_mtd_get_uboot_offs(),
+ sizeof(*header), (void *)header);
+ if (ret_len != sizeof(*header)) {
+ printf("SPL: Failed to read image header\n");
+ err = -EIO;
goto out_err;
+ }
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
image_get_magic(header) == FDT_MAGIC) {
@@ -82,8 +133,15 @@ int spl_mtd_load(struct spl_image_info *spl_image,
err = spl_parse_image_header(spl_image, bootdev, header);
if (err)
goto out_err;
- err = mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
- &ret_len, (void *)(ulong)spl_image->load_addr);
+
+ ret_len = spl_mtd_read_skip_bad(mtd, spl_mtd_get_uboot_offs(),
+ spl_image->size,
+ (void *)(ulong)spl_image->load_addr);
+ if (ret_len != spl_image->size) {
+ printf("SPL: Failed to read full image: %zu/%u bytes\n",
+ ret_len, spl_image->size);
+ err = -EIO;
+ }
}
out_err:
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 3/7] spl: mtd: Add bad block handling for SPL image loading
2026-02-17 11:21 ` [PATCH 3/7] spl: mtd: Add bad block handling for SPL image loading Anurag Dutta
@ 2026-02-19 8:38 ` Anshul Dalal
0 siblings, 0 replies; 15+ messages in thread
From: Anshul Dalal @ 2026-02-19 8:38 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
On Tue Feb 17, 2026 at 4:51 PM IST, Anurag Dutta wrote:
> From: Santhosh Kumar K <s-k6@ti.com>
>
> Implement bad block skipping functionality in SPL MTD loader to ensure
> reliable boot from flash devices with bad blocks. Without this, the
> SPL would fail to load images if bad blocks were encountered.
>
> Signed-off-by: Santhosh Kumar K <s-k6@ti.com>
> Signed-off-by: Anurag Dutta <a-dutta@ti.com>
> ---
> common/spl/spl_mtd.c | 78 ++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 68 insertions(+), 10 deletions(-)
>
> diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
> index 95c0c8ce8cd..d635aa2b476 100644
> --- a/common/spl/spl_mtd.c
> +++ b/common/spl/spl_mtd.c
> @@ -17,15 +17,64 @@ uint32_t __weak spl_mtd_get_uboot_offs(void)
> return CONFIG_SYS_MTD_U_BOOT_OFFS;
> }
>
> +static ulong spl_mtd_read_skip_bad(struct mtd_info *mtd, loff_t offs,
> + size_t size, void *dst)
> +{
> + size_t remaining = size;
> + size_t ret_len;
> + loff_t current_offs = offs;
NIT: Do we really need to have a current_offs here when we aren't gonna
use offs later anyway? Would be more clear to use offs directly imo.
> + loff_t block_aligned_offs, next_block;
> + u_char *buf = (u_char *)dst;
> + int err;
> +
> + while (remaining > 0) {
> + size_t read_size;
> + size_t block_remaining;
> +
> + block_aligned_offs = current_offs & ~(mtd->erasesize - 1);
We could make use of ALIGN macro here.
> +
> + if (mtd_block_isbad(mtd, block_aligned_offs)) {
> + debug("SPL: Skipping bad block at 0x%llx, jumping to 0x%llx\n",
> + block_aligned_offs, next_block);
On the first bad bock, next_block would be uninitialized data and
printing it here doesn't make sense.
> +
> + next_block = block_aligned_offs + mtd->erasesize;
> + current_offs = next_block;
> + continue;
> + }
> +
> + block_remaining = mtd->erasesize -
> + (current_offs & (mtd->erasesize - 1));
> + read_size = remaining < block_remaining ? remaining : block_remaining;
We could instead do 'read_size = min(remaining, block_remaining).
> +
> + err = mtd_read(mtd, current_offs, read_size, &ret_len, buf);
> + if (err) {
> + printf("SPL: Read error at offset 0x%llx: %d\n",
> + current_offs, err);
> + return size - remaining;
> + }
> +
> + buf += ret_len;
> + current_offs += ret_len;
> + remaining -= ret_len;
> +
> + if (current_offs >= mtd->size) {
> + printf("SPL: Reached end of device, read %zu/%zu bytes\n",
> + size - remaining, size);
> + break;
> + }
> + }
> +
> + return size - remaining;
> +}
> +
> static ulong spl_mtd_fit_read(struct spl_load_info *load, ulong offs,
> ulong size, void *dst)
> {
> struct mtd_info *mtd = load->priv;
> - int err;
> size_t ret_len;
>
> - err = mtd_read(mtd, offs, size, &ret_len, dst);
> - if (!err)
> + ret_len = spl_mtd_read_skip_bad(mtd, offs, size, dst);
> + if (ret_len > 0)
> return ret_len;
>
> return 0;
> @@ -52,17 +101,19 @@ struct mtd_info *spl_prepare_mtd(uint boot_device)
> int spl_mtd_load(struct spl_image_info *spl_image,
> struct mtd_info *mtd, struct spl_boot_device *bootdev)
> {
> - int err;
> + int err = 0;
> struct legacy_img_hdr *header;
> __maybe_unused struct spl_load_info load;
> size_t ret_len;
>
> header = spl_get_load_buffer(0, sizeof(*header));
> -
> - err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
> - &ret_len, (void *)header);
> - if (err)
> + ret_len = spl_mtd_read_skip_bad(mtd, spl_mtd_get_uboot_offs(),
> + sizeof(*header), (void *)header);
> + if (ret_len != sizeof(*header)) {
> + printf("SPL: Failed to read image header\n");
> + err = -EIO;
> goto out_err;
> + }
>
> if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
> image_get_magic(header) == FDT_MAGIC) {
> @@ -82,8 +133,15 @@ int spl_mtd_load(struct spl_image_info *spl_image,
> err = spl_parse_image_header(spl_image, bootdev, header);
> if (err)
> goto out_err;
> - err = mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
> - &ret_len, (void *)(ulong)spl_image->load_addr);
> +
> + ret_len = spl_mtd_read_skip_bad(mtd, spl_mtd_get_uboot_offs(),
> + spl_image->size,
> + (void *)(ulong)spl_image->load_addr);
> + if (ret_len != spl_image->size) {
> + printf("SPL: Failed to read full image: %zu/%u bytes\n",
> + ret_len, spl_image->size);
> + err = -EIO;
> + }
> }
>
> out_err:
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 4/7] spl: Add MTD loading support configuration
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
` (2 preceding siblings ...)
2026-02-17 11:21 ` [PATCH 3/7] spl: mtd: Add bad block handling for SPL image loading Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-17 11:21 ` [PATCH 5/7] mtd: nand: spi: Enable spinand build Kconfig option for spl Anurag Dutta
` (3 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Apurva Nandan <a-nandan@ti.com>
Add Kconfig options to enable SPL loading of U-Boot from MTD devices:
- SPL_MTD_LOAD: Enable loading via MTD framework
- SYS_MTD_U_BOOT_OFFS: Configure U-Boot offset in MTD flash
(default 0x80000 for K3, 0x0 otherwise)
This provides a unified boot path for all MTD devices.
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
common/spl/Kconfig | 22 ++++++++++++++++++++++
common/spl/Makefile | 2 ++
2 files changed, 24 insertions(+)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 996c9b8db4f..fb167933c60 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -973,6 +973,28 @@ config SPL_MTD
devices. See SPL_NAND_SUPPORT and SPL_ONENAND_SUPPORT for how
to enable specific MTD drivers.
+config SPL_MTD_LOAD
+ bool "Support loading from MTD framework"
+ depends on SPL_MTD
+ help
+ Enable support for loading next stage, U-Boot or otherwise, from
+ MTD Framework in U-Boot SPL.
+
+config SPL_MTD_NAND_LOAD
+ bool "Support loading from MTD framework for NAND flashes"
+ depends on SPL_MTD_LOAD
+ help
+ Enable support for loading next stage, U-Boot or otherwise, from
+ MTD Framework in U-Boot SPL for NAND flashes.
+
+config SYS_MTD_U_BOOT_OFFS
+ hex "address of u-boot payload in MTD flash"
+ default 0x80000 if ARCH_K3
+ default 0x0
+ depends on SPL_MTD_LOAD
+ help
+ Address within MTD Flash from where the u-boot payload is fetched.
+
config SPL_MUSB_NEW
bool "Support new Mentor Graphics USB"
help
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 4c9482bd309..ae87523f45d 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -35,6 +35,8 @@ obj-$(CONFIG_$(PHASE_)NVME) += spl_nvme.o
obj-$(CONFIG_$(PHASE_)SEMIHOSTING) += spl_semihosting.o
obj-$(CONFIG_$(PHASE_)DFU) += spl_dfu.o
obj-$(CONFIG_$(PHASE_)SPI_LOAD) += spl_spi.o
+obj-$(CONFIG_$(PHASE_)MTD_LOAD) += spl_mtd.o
+obj-$(CONFIG_$(PHASE_)MTD_NAND_LOAD) += spl_mtd_nand.o
obj-$(CONFIG_$(PHASE_)RAM_SUPPORT) += spl_ram.o
obj-$(CONFIG_$(PHASE_)USB_SDP_SUPPORT) += spl_sdp.o
endif
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 5/7] mtd: nand: spi: Enable spinand build Kconfig option for spl
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
` (3 preceding siblings ...)
2026-02-17 11:21 ` [PATCH 4/7] spl: Add MTD loading support configuration Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-17 11:21 ` [PATCH 6/7] arm: spl: Enumerate SPINAND as a boot device Anurag Dutta
` (2 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Apurva Nandan <a-nandan@ti.com>
Only RAW NANDs are supported in the SPL, so create a new Kconfig
config for building SPI NAND subsystem in the SPL build using
SPL_NAND_SPI_SUPPORT Kconfig option.
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
common/spl/Kconfig | 8 ++++++++
drivers/mtd/Makefile | 1 +
drivers/mtd/nand/Makefile | 3 ++-
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index fb167933c60..1a28eb257dd 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1071,6 +1071,14 @@ config SPL_RELOC_LOADER
to temporary memory, then copying it into place afterwards, then
jumping to it.
+config SPL_NAND_SPI_SUPPORT
+ bool "Support loading from SPI NAND flash"
+ depends on SPL_MTD_LOAD
+ help
+ Enable support for SPI NAND flash devices in SPL boot flow.
+ When enabled, SPL can load U-Boot from SPI NAND using the MTD
+ subsystem.
+
config SPL_UBI
bool "Support UBI"
help
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index ce05e206073..a1f9a1ddeda 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -35,6 +35,7 @@ ifneq ($(mtd-y),)
obj-$(CONFIG_SPL_MTD) += mtd.o
endif
obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += nand/
+obj-$(CONFIG_$(PHASE_)NAND_SPI_SUPPORT) += nand/
obj-$(CONFIG_SPL_ONENAND_SUPPORT) += onenand/
obj-$(CONFIG_$(PHASE_)SPI_FLASH_SUPPORT) += spi/
obj-$(CONFIG_SPL_UBI) += ubispl/
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index c8169cf7390..44cdf8ac1b2 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -1,10 +1,11 @@
# SPDX-License-Identifier: GPL-2.0+
-ifeq ($(CONFIG_XPL_BUILD)$(CONFIG_TPL_BUILD),)
nandcore-objs := core.o bbt.o
+ifeq ($(CONFIG_XPL_BUILD)$(CONFIG_TPL_BUILD),)
obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
obj-$(CONFIG_MTD_RAW_NAND) += raw/
obj-$(CONFIG_MTD_SPI_NAND) += spi/
else
obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += raw/
+obj-$(CONFIG_$(PHASE_)NAND_SPI_SUPPORT) += spi/ nandcore.o
endif
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 6/7] arm: spl: Enumerate SPINAND as a boot device
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
` (4 preceding siblings ...)
2026-02-17 11:21 ` [PATCH 5/7] mtd: nand: spi: Enable spinand build Kconfig option for spl Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-18 8:34 ` Anshul Dalal
2026-02-17 11:21 ` [PATCH 7/7] include: environment: ti: Add ospi_nand environment variables Anurag Dutta
2026-02-17 13:31 ` [PATCH 0/7] OSPI NAND MTD load and boot support Santhosh Kumar K
7 siblings, 1 reply; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Apurva Nandan <a-nandan@ti.com>
Add enum BOOT_DEVICE_SPINAND in spl.h
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
arch/arm/include/asm/spl.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h
index ee79a19c05c..cd9b7942fca 100644
--- a/arch/arm/include/asm/spl.h
+++ b/arch/arm/include/asm/spl.h
@@ -20,6 +20,7 @@ enum {
BOOT_DEVICE_NAND,
BOOT_DEVICE_ONENAND,
BOOT_DEVICE_NOR,
+ BOOT_DEVICE_SPINAND,
BOOT_DEVICE_UART,
BOOT_DEVICE_SPI,
BOOT_DEVICE_USB,
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 6/7] arm: spl: Enumerate SPINAND as a boot device
2026-02-17 11:21 ` [PATCH 6/7] arm: spl: Enumerate SPINAND as a boot device Anurag Dutta
@ 2026-02-18 8:34 ` Anshul Dalal
0 siblings, 0 replies; 15+ messages in thread
From: Anshul Dalal @ 2026-02-18 8:34 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
On Tue Feb 17, 2026 at 4:51 PM IST, Anurag Dutta wrote:
> From: Apurva Nandan <a-nandan@ti.com>
>
> Add enum BOOT_DEVICE_SPINAND in spl.h
>
> Signed-off-by: Apurva Nandan <a-nandan@ti.com>
> Signed-off-by: Anurag Dutta <a-dutta@ti.com>
> ---
> arch/arm/include/asm/spl.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h
> index ee79a19c05c..cd9b7942fca 100644
> --- a/arch/arm/include/asm/spl.h
> +++ b/arch/arm/include/asm/spl.h
> @@ -20,6 +20,7 @@ enum {
> BOOT_DEVICE_NAND,
> BOOT_DEVICE_ONENAND,
> BOOT_DEVICE_NOR,
> + BOOT_DEVICE_SPINAND,
> BOOT_DEVICE_UART,
> BOOT_DEVICE_SPI,
> BOOT_DEVICE_USB,
NIT: Shouldn't this come before 1/7 of the series since we are making
use of the symbol there?
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 7/7] include: environment: ti: Add ospi_nand environment variables
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
` (5 preceding siblings ...)
2026-02-17 11:21 ` [PATCH 6/7] arm: spl: Enumerate SPINAND as a boot device Anurag Dutta
@ 2026-02-17 11:21 ` Anurag Dutta
2026-02-17 13:31 ` [PATCH 0/7] OSPI NAND MTD load and boot support Santhosh Kumar K
7 siblings, 0 replies; 15+ messages in thread
From: Anurag Dutta @ 2026-02-17 11:21 UTC (permalink / raw)
To: jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, a-dutta, s-k6,
gehariprasath, vigneshr, u-kumar1, u-boot
From: Apurva Nandan <a-nandan@ti.com>
Add common OSPI NAND flash environment configuration that can be
shared across multiple K3 platforms. This consolidates OSPI NAND
boot and flash operation variables into a reusable environment file.
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Anurag Dutta <a-dutta@ti.com>
---
include/env/ti/ospi_nand.env | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 include/env/ti/ospi_nand.env
diff --git a/include/env/ti/ospi_nand.env b/include/env/ti/ospi_nand.env
new file mode 100644
index 00000000000..04a4fb1dbb3
--- /dev/null
+++ b/include/env/ti/ospi_nand.env
@@ -0,0 +1,22 @@
+mtdids=spi-nand0=spi-nand0
+mtdparts=mtdparts=spi-nand0:512k(ospi_nand.tiboot3),2m(ospi_nand.tispl),\
+ 4m(ospi_nand.u-boot),256k(ospi_nand.env),256k(ospi_nand.env.backup),\
+ 98048k@32m(ospi_nand.rootfs),256k@130816k(ospi_nand.phypattern)
+ospi_nand_bootpart=ospi_nand.rootfs
+ospi_nand_bootvolume=ubi0:rootfs
+ospi_nand_ubi_init=ubi part ${ospi_nand_bootpart}; ubifsmount ${ospi_nand_bootvolume};
+args_ospi_nand=setenv bootargs console=${console}
+ ${optargs} ubi.mtd=${ospi_nand_bootpart}
+ root=${ospi_nand_bootvolume} rootfstype=ubifs
+init_ospi_nand=run args_all args_ospi_nand ospi_nand_ubi_init
+get_fdt_ospi_nand=ubifsload ${fdtaddr} ${bootdir}/dtb/${fdtfile};
+get_overlay_ospi_nand=
+ fdt address ${fdtaddr}
+ fdt resize 0x100000;
+ for overlay in $name_overlays;
+ do;
+ ubifsload ${dtboaddr} ${bootdir}/dtb/${overlay} &&
+ fdt apply ${dtboaddr};
+ done;
+get_kern_ospi_nand=ubifsload ${loadaddr} ${bootdir}/${name_kern}
+get_fit_ospi_nand=ubifsload ${addr_fit} ${bootdir}/${name_fit}
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 0/7] OSPI NAND MTD load and boot support
2026-02-17 11:21 [PATCH 0/7] OSPI NAND MTD load and boot support Anurag Dutta
` (6 preceding siblings ...)
2026-02-17 11:21 ` [PATCH 7/7] include: environment: ti: Add ospi_nand environment variables Anurag Dutta
@ 2026-02-17 13:31 ` Santhosh Kumar K
2026-02-17 13:37 ` Santhosh Kumar K
7 siblings, 1 reply; 15+ messages in thread
From: Santhosh Kumar K @ 2026-02-17 13:31 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, gehariprasath,
vigneshr, u-kumar1, u-boot, s-k6
On 17/02/26 16:51, Anurag Dutta wrote:
> Hi all
> The series adds SPL support for loading images via the MTD subsystem,
> including handling of bad blocks during read operations and removal of
> the MTD device after image loading to allow reuse by later boot stages.
> These changes enable SPL to load U-Boot proper from SPI NAND in a generic
> and reusable manner.
>
> Tested on j784s4: https://gist.github.com/anuragdutta731/e873fb91098e71c1613fb9a3472d94e7
Tested on AM62x LP SK:
http://serenity.dal.design.ti.com:7777/vuvucodapo.yaml
Tested-by: Santhosh Kumar K <s-k6@ti.com>
>
> Apurva Nandan (6):
> common: spl: mtd: Add support for loading images from MTD
> spl: mtd: Remove MTD device after loading images
> spl: Add MTD loading support configuration
> mtd: nand: spi: Enable spinand build Kconfig option for spl
> arm: spl: Enumerate SPINAND as a boot device
> include: environment: ti: Add ospi_nand environment variables
>
> Santhosh Kumar K (1):
> spl: mtd: Add bad block handling for SPL image loading
>
> arch/arm/include/asm/spl.h | 1 +
> common/spl/Kconfig | 30 +++++++
> common/spl/Makefile | 2 +
> common/spl/spl_mtd.c | 149 +++++++++++++++++++++++++++++++++++
> common/spl/spl_mtd_nand.c | 35 ++++++++
> drivers/mtd/Makefile | 1 +
> drivers/mtd/mtd-uclass.c | 12 +++
> drivers/mtd/nand/Makefile | 3 +-
> drivers/mtd/nand/spi/core.c | 12 ++-
> include/env/ti/ospi_nand.env | 22 ++++++
> include/mtd.h | 2 +-
> include/spl.h | 18 +++++
> 12 files changed, 281 insertions(+), 6 deletions(-)
> create mode 100644 common/spl/spl_mtd.c
> create mode 100644 common/spl/spl_mtd_nand.c
> create mode 100644 include/env/ti/ospi_nand.env
>
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 0/7] OSPI NAND MTD load and boot support
2026-02-17 13:31 ` [PATCH 0/7] OSPI NAND MTD load and boot support Santhosh Kumar K
@ 2026-02-17 13:37 ` Santhosh Kumar K
0 siblings, 0 replies; 15+ messages in thread
From: Santhosh Kumar K @ 2026-02-17 13:37 UTC (permalink / raw)
To: Anurag Dutta, jagan, trini
Cc: michal.simek, venkatesh.abbarapu, boon.khai.ng, gehariprasath,
vigneshr, u-kumar1, u-boot, s-k6
On 17/02/26 19:01, Santhosh Kumar K wrote:
>
>
> On 17/02/26 16:51, Anurag Dutta wrote:
>> Hi all
>> The series adds SPL support for loading images via the MTD subsystem,
>> including handling of bad blocks during read operations and removal of
>> the MTD device after image loading to allow reuse by later boot stages.
>> These changes enable SPL to load U-Boot proper from SPI NAND in a generic
>> and reusable manner.
>>
>> Tested on j784s4: https://gist.github.com/anuragdutta731/
>> e873fb91098e71c1613fb9a3472d94e7
>
> Tested on AM62x LP SK: http://serenity.dal.design.ti.com:7777/
> vuvucodapo.yaml
>
> Tested-by: Santhosh Kumar K <s-k6@ti.com>
Ignore this mail - I responded to the wrong thread, my bad!
- Santhosh.
>
>>
>> Apurva Nandan (6):
>> common: spl: mtd: Add support for loading images from MTD
>> spl: mtd: Remove MTD device after loading images
>> spl: Add MTD loading support configuration
>> mtd: nand: spi: Enable spinand build Kconfig option for spl
>> arm: spl: Enumerate SPINAND as a boot device
>> include: environment: ti: Add ospi_nand environment variables
>>
>> Santhosh Kumar K (1):
>> spl: mtd: Add bad block handling for SPL image loading
>>
>> arch/arm/include/asm/spl.h | 1 +
>> common/spl/Kconfig | 30 +++++++
>> common/spl/Makefile | 2 +
>> common/spl/spl_mtd.c | 149 +++++++++++++++++++++++++++++++++++
>> common/spl/spl_mtd_nand.c | 35 ++++++++
>> drivers/mtd/Makefile | 1 +
>> drivers/mtd/mtd-uclass.c | 12 +++
>> drivers/mtd/nand/Makefile | 3 +-
>> drivers/mtd/nand/spi/core.c | 12 ++-
>> include/env/ti/ospi_nand.env | 22 ++++++
>> include/mtd.h | 2 +-
>> include/spl.h | 18 +++++
>> 12 files changed, 281 insertions(+), 6 deletions(-)
>> create mode 100644 common/spl/spl_mtd.c
>> create mode 100644 common/spl/spl_mtd_nand.c
>> create mode 100644 include/env/ti/ospi_nand.env
>>
>
^ permalink raw reply [flat|nested] 15+ messages in thread