[PATCH] nand: denali: enable SoC64 SPL NAND boot with proper Kconfig selection

dinesh.maniyam at altera.com dinesh.maniyam at altera.com
Tue Nov 4 18:19:02 CET 2025


From: Dinesh Maniyam <dinesh.maniyam at altera.com>

Add SoC64-specific NAND SPL load support in denali_spl.c and update the
related Kconfig dependencies.

This patch introduces new helper functions to enable NAND boot support
for SoCFPGA SoC64 devices using the Denali NAND controller during the
SPL stage:

- nand_get_mtd(): safely retrieves the active NAND device instance.
- nand_spl_load_image(): supports image loading with page alignment and
  bad block skipping using nand_read_skip_bad().
- Includes nand_util.c for required NAND utility helpers.
- Wrapped under IS_ENABLED(CONFIG_TARGET_SOCFPGA_SOC64) to limit
  inclusion to SoC64 targets.

In addition, the SPL_NAND_DENALI Kconfig entry has been updated to:
- Select required NAND SPL components (BASE, DRIVERS, IDENT, INIT, ECC).
- Exclude NAND_DENALI_SPARE_AREA_SKIP_BYTES from SoC64 builds, as SoC64
  NAND handling no longer uses this configuration.

These changes collectively enable functional NAND SPL image loading
support for SoCFPGA SoC64 devices with Denali NAND.

Signed-off-by: Dinesh Maniyam <dinesh.maniyam at altera.com>
---
 drivers/mtd/nand/raw/Kconfig      |  7 ++-
 drivers/mtd/nand/raw/denali_spl.c | 73 +++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 754b99bf3eb..5e567ca4993 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -781,6 +781,11 @@ config SPL_NAND_CADENCE
 
 config SPL_NAND_DENALI
 	bool "Support Denali NAND controller for SPL"
+	select SPL_NAND_BASE
+	select SPL_NAND_DRIVERS
+	select SPL_NAND_IDENT
+	select SPL_NAND_INIT
+	select SPL_NAND_ECC
 	depends on SPL_NAND_SUPPORT
 	help
 	  This is a small implementation of the Denali NAND controller
@@ -788,7 +793,7 @@ config SPL_NAND_DENALI
 
 config NAND_DENALI_SPARE_AREA_SKIP_BYTES
 	int "Number of bytes skipped in OOB area"
-	depends on SPL_NAND_DENALI
+	depends on SPL_NAND_DENALI && !TARGET_SOCFPGA_SOC64
 	range 0 63
 	help
 	  This option specifies the number of bytes to skip from the beginning
diff --git a/drivers/mtd/nand/raw/denali_spl.c b/drivers/mtd/nand/raw/denali_spl.c
index b1e2c9d8161..78cdab51a5a 100644
--- a/drivers/mtd/nand/raw/denali_spl.c
+++ b/drivers/mtd/nand/raw/denali_spl.c
@@ -5,13 +5,84 @@
  */
 
 #include <config.h>
+#include <hang.h>
 #include <log.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <nand.h>
+#include <system-constants.h>
 #include <asm/io.h>
 #include <asm/unaligned.h>
 #include <linux/delay.h>
 #include <linux/mtd/rawnand.h>
 #include "denali.h"
 
+/* Only compile this code for SoCFPGA SoC64 targets */
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_SOC64)
+
+struct mtd_info *nand_get_mtd(void)
+{
+	struct mtd_info *mtd;
+
+	mtd = get_nand_dev_by_index(nand_curr_device);
+	if (!mtd)
+		hang();
+
+	return mtd;
+}
+
+int nand_spl_load_image(u32 offset, u32 len, void *dst)
+{
+	size_t count = len, actual = 0, page_align_overhead = 0;
+	u32 page_align_offset = 0;
+	u8 *page_buffer;
+	int err = 0;
+	struct mtd_info *mtd;
+
+	if (!len || !dst)
+		return -EINVAL;
+
+	mtd = nand_get_mtd();
+
+	if ((offset & (mtd->writesize - 1)) != 0) {
+		page_buffer = malloc_cache_aligned(mtd->writesize);
+		if (!page_buffer) {
+			debug("Error: allocating buffer\n");
+			return -ENOMEM;
+		}
+
+		page_align_overhead = offset % mtd->writesize;
+		page_align_offset = (offset / mtd->writesize) * mtd->writesize;
+		count = mtd->writesize;
+
+		err = nand_read_skip_bad(mtd, page_align_offset, &count,
+					 &actual, mtd->size, page_buffer);
+
+		if (err)
+			return err;
+
+		count -= page_align_overhead;
+		count = min((size_t)len, count);
+		memcpy(dst, page_buffer + page_align_overhead, count);
+		free(page_buffer);
+
+		len -= count;
+		if (!len)
+			return err;
+
+		offset += count;
+		dst += count;
+		count = len;
+	}
+
+	return nand_read_skip_bad(mtd, offset, &count, &actual, mtd->size, dst);
+}
+
+void nand_deselect(void) {}
+#include "nand_util.c"
+
+#else
+
 #define DENALI_MAP01		(1 << 26)	/* read/write pages in PIO */
 #define DENALI_MAP10		(2 << 26)	/* high-level control plane */
 
@@ -240,3 +311,5 @@ unsigned int nand_page_size(void)
 }
 
 void nand_deselect(void) {}
+#endif
+
-- 
2.43.7



More information about the U-Boot mailing list