[PATCH] nand: denali: enable SoC64 SPL NAND boot with proper Kconfig selection
Chee, Tien Fong
tienfong.chee at altera.com
Wed Nov 19 04:30:46 CET 2025
Hi Dinesh,
On 5/11/2025 1:19 am, dinesh.maniyam at altera.com wrote:
> 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
Are these strictly required for all Denali users?
If these are only needed for SoC64, it would be better to move them into:
arch/arm/Kconfig under SOCFPGA / SOC64, or the SoC64 defconfig
> 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
This should not be added here in the common Kconfig.
If SoC64 does not require this option, simply disable it in:
SoC64 defconfig, or arch/arm/Kconfig under SOCFPGA
The common Denali code should not embed SoCFPGA-specific constraints.
> 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)
Cannot add the platform specific change here in the common driver.
The Denali SPL driver is shared across platforms, so we should not add
SoCFPGA-specific logic here.
The function:
int nand_spl_load_image(...)
should be moved to platform-specific code, e.g.:
arch/arm/mach-socfpga/misc_soc64.c
Similarly, helper functions such as:
nand_get_mtd()
nand_spl_load_image()
#include "nand_util.c"
> +
> +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
> +
Thanks.
Tien Fong
More information about the U-Boot
mailing list