From: Fabio Estevam <festevam@gmail.com>
To: kever.yang@rock-chips.com
Cc: trini@konsulko.com, u-boot@lists.denx.de,
Fabio Estevam <festevam@nabladev.com>
Subject: [PATCH 5/7] spl: Add SPI NAND support via MTD in SPL
Date: Sat, 31 Jan 2026 21:44:54 -0300 [thread overview]
Message-ID: <20260201004456.763107-6-festevam@gmail.com> (raw)
In-Reply-To: <20260201004456.763107-1-festevam@gmail.com>
From: Fabio Estevam <festevam@nabladev.com>
Add support for booting U-Boot SPL from SPI NAND devices
using the MTD subsystem.
- Introduce CONFIG_SPL_SPI_NAND_LOAD to enable SPL loading
from SPI NAND flash.
- Implement spl_spi_nand.c as a dedicated SPL loader that
reads the FIT image from SPI NAND via MTD.
- Update common/spl/Kconfig and Makefiles to include the
new loader in SPL builds.
- Adjust drivers/mtd/Makefile and drivers/mtd/nand/Makefile
to build the necessary SPI NAND MTD objects only when
CONFIG_SPL_SPI_NAND_LOAD is enabled, avoiding size impact
on other boards.
This allows boards like the Omega4 RV1103 to boot SPL directly
from SPI NAND, keeping the SPL small and avoiding unnecessary
inclusion of SPI NOR code.
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
common/spl/Kconfig | 10 ++++-
common/spl/Makefile | 1 +
common/spl/spl_spi_nand.c | 82 +++++++++++++++++++++++++++++++++++++++
drivers/mtd/Makefile | 1 +
drivers/mtd/nand/Makefile | 13 ++++++-
5 files changed, 105 insertions(+), 2 deletions(-)
create mode 100644 common/spl/spl_spi_nand.c
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 2998b7acb75f..126855b804ce 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1576,13 +1576,21 @@ config SPL_SPI_LOAD
Enable support for loading next stage, U-Boot or otherwise, from
SPI NOR in U-Boot SPL.
+config SPL_SPI_NAND_LOAD
+ bool "Support loading from SPI NAND flash"
+ depends on SPL
+ depends on MTD && DM_MTD
+ help
+ Enable support for loading next stage, U-Boot or otherwise, from
+ SPI NAND in U-Boot SPL.
+
endif # SPL_SPI_FLASH_SUPPORT
config SYS_SPI_U_BOOT_OFFS
hex "address of u-boot payload in SPI flash"
default 0x8000 if ARCH_SUNXI
default 0x0
- depends on SPL_SPI_LOAD || SPL_SPI_SUNXI
+ depends on SPL_SPI_LOAD || SPL_SPI_NAND_LOAD || SPL_SPI_SUNXI
help
Address within SPI-Flash from where the u-boot payload is fetched
from.
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 4c9482bd3096..4628902e7e31 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -35,6 +35,7 @@ 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_)SPI_NAND_LOAD) += spl_spi_nand.o
obj-$(CONFIG_$(PHASE_)RAM_SUPPORT) += spl_ram.o
obj-$(CONFIG_$(PHASE_)USB_SDP_SUPPORT) += spl_sdp.o
endif
diff --git a/common/spl/spl_spi_nand.c b/common/spl/spl_spi_nand.c
new file mode 100644
index 000000000000..20b877f75a05
--- /dev/null
+++ b/common/spl/spl_spi_nand.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * SPL loader for SPI NAND devices using the MTD subsystem.
+ *
+ * Based on spl_spi.c, which is:
+ *
+ * Copyright (C) 2011 OMICRON electronics GmbH
+ *
+ * based on drivers/mtd/nand/raw/nand_spl_load.c
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ */
+
+#include <config.h>
+#include <image.h>
+#include <log.h>
+#include <errno.h>
+#include <spl.h>
+#include <spl_load.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+#include <dm/ofnode.h>
+#include <dm/uclass.h>
+#include <mtd.h>
+
+static struct mtd_info *spl_spi_nand_get_mtd(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ for (ret = uclass_first_device_err(UCLASS_MTD, &dev);
+ dev;
+ ret = uclass_next_device_err(&dev)) {
+ if (ret)
+ continue;
+ if (device_is_compatible(dev, "spi-nand"))
+ return dev_get_uclass_priv(dev);
+ }
+
+ return NULL;
+}
+
+static ulong spl_spinand_fit_read(struct spl_load_info *load, ulong offs,
+ ulong size, void *buf)
+{
+ struct mtd_info *mtd = load->priv;
+ size_t retlen = 0;
+ int ret;
+
+ ret = mtd_read(mtd, offs, size, &retlen, buf);
+ if (ret && ret != -EUCLEAN) {
+ printf("SPI NAND read failed offs=0x%lx size=0x%lx ret=%d\n",
+ offs, size, ret);
+ return 0;
+ }
+ if (retlen != size)
+ return 0;
+
+ return retlen;
+}
+
+static int spl_spinand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct spl_load_info load;
+ struct mtd_info *mtd;
+
+ mtd = spl_spi_nand_get_mtd();
+ if (!mtd) {
+ puts("SPI NAND probe failed.\n");
+ return -ENODEV;
+ }
+
+ spl_load_init(&load, spl_spinand_fit_read, mtd, 1);
+
+ return spl_load(spl_image, bootdev, &load, 0, CONFIG_SYS_SPI_U_BOOT_OFFS);
+}
+
+/* Use priority 1 so that boards can override this */
+SPL_LOAD_IMAGE_METHOD("SPI NAND", 1, BOOT_DEVICE_SPI, spl_spinand_load_image);
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index ce05e206073d..a12d880a9e90 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -34,6 +34,7 @@ else
ifneq ($(mtd-y),)
obj-$(CONFIG_SPL_MTD) += mtd.o
endif
+obj-$(CONFIG_SPL_SPI_NAND_LOAD) += nand/
obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += nand/
obj-$(CONFIG_SPL_ONENAND_SUPPORT) += onenand/
obj-$(CONFIG_$(PHASE_)SPI_FLASH_SUPPORT) += spi/
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index c8169cf73902..7cd2a5f1af9b 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -1,10 +1,21 @@
# 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),)
+
+# U-Boot proper
obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
obj-$(CONFIG_MTD_RAW_NAND) += raw/
obj-$(CONFIG_MTD_SPI_NAND) += spi/
+
else
+
+# SPL / XPL / TPL
+# SPL has no MTD_NAND_CORE symbol, so we must key off SPI NAND usage
+obj-$(CONFIG_SPL_SPI_NAND_LOAD) += nandcore.o
+obj-$(CONFIG_SPL_SPI_NAND_LOAD) += spi/
+
+# raw NAND still follows the normal SPL rule
obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += raw/
endif
--
2.34.1
next prev parent reply other threads:[~2026-02-01 0:45 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-01 0:44 [PATCH 0/7] ARM: Add RV1103 Omega4 board support Fabio Estevam
2026-02-01 0:44 ` [PATCH 1/7] pinctrl: rockchip: Add support for RV1103 Fabio Estevam
2026-02-01 1:28 ` Jonas Karlman
2026-02-01 0:44 ` [PATCH 2/7] clk: " Fabio Estevam
2026-02-01 0:44 ` [PATCH 3/7] tools: rkcommon: Add rv1103 support Fabio Estevam
2026-02-01 1:44 ` Jonas Karlman
2026-02-01 0:44 ` [PATCH 4/7] rockchip: spl-boot-order: Add SPI NAND support Fabio Estevam
2026-02-01 0:44 ` Fabio Estevam [this message]
2026-02-01 0:44 ` [PATCH 6/7] ARM: dts: Add RV1103 Omega4 support Fabio Estevam
2026-02-01 0:44 ` [PATCH 7/7] omega4-rv1103: Add initial support Fabio Estevam
2026-02-01 1:12 ` [PATCH 0/7] ARM: Add RV1103 Omega4 board support Jonas Karlman
2026-02-03 15:10 ` Fabio Estevam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260201004456.763107-6-festevam@gmail.com \
--to=festevam@gmail.com \
--cc=festevam@nabladev.com \
--cc=kever.yang@rock-chips.com \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox