Merge patch series "nand: Add sandbox tests"
authorTom Rini <trini@konsulko.com>
Thu, 16 Nov 2023 17:46:09 +0000 (12:46 -0500)
committerTom Rini <trini@konsulko.com>
Thu, 16 Nov 2023 18:49:13 +0000 (13:49 -0500)
To quote the author:

This series tests raw nand flash in sandbox and fixes various bugs discovered in
the process. I've tried to do things in a contemporary manner, avoiding the
(numerous) variations present on only a few boards. The test is pretty minimal.
Future work could test the rest of the nand API as well as the MTD API.

Bloat (for v1) at [1] (for boards with SPL_NAND_SUPPORT enabled). Almost
everything grows by a few bytes due to nand_page_size. A few boards grow more,
mostly those using nand_spl_loaders.c. CI at [2].

[1] https://gist.github.com/Forty-Bot/9694f3401893c9e706ccc374922de6c2
[2] https://source.denx.de/u-boot/custodians/u-boot-clk/-/pipelines/18443

103 files changed:
README
arch/sandbox/cpu/os.c
arch/sandbox/dts/test.dts
arch/sandbox/include/asm/spl.h
cmd/nand.c
common/spl/Kconfig
common/spl/spl_legacy.c
common/spl/spl_nand.c
configs/am335x_baltos_defconfig
configs/am335x_evm_defconfig
configs/am335x_evm_spiboot_defconfig
configs/am335x_guardian_defconfig
configs/am335x_hs_evm_defconfig
configs/am335x_hs_evm_uart_defconfig
configs/am335x_igep003x_defconfig
configs/am335x_sl50_defconfig
configs/am3517_evm_defconfig
configs/am43xx_evm_defconfig
configs/am43xx_evm_rtconly_defconfig
configs/am43xx_evm_usbhost_boot_defconfig
configs/am43xx_hs_evm_defconfig
configs/am62ax_evm_r5_defconfig
configs/am65x_evm_a53_defconfig
configs/axm_defconfig
configs/chiliboard_defconfig
configs/cm_t43_defconfig
configs/corvus_defconfig
configs/da850evm_nand_defconfig
configs/devkit3250_defconfig
configs/devkit8000_defconfig
configs/dra7xx_evm_defconfig
configs/draco_defconfig
configs/etamin_defconfig
configs/gardena-smart-gateway-at91sam_defconfig
configs/igep00x0_defconfig
configs/imx6ulz_smm_m2_defconfig
configs/imx8mn_bsh_smm_s2_defconfig
configs/j7200_evm_a72_defconfig
configs/j7200_evm_r5_defconfig
configs/j721e_evm_a72_defconfig
configs/j721e_evm_r5_defconfig
configs/j721s2_evm_a72_defconfig
configs/j721s2_evm_r5_defconfig
configs/m53menlo_defconfig
configs/omap35_logic_defconfig
configs/omap35_logic_somlv_defconfig
configs/omap3_beagle_defconfig
configs/omap3_evm_defconfig
configs/omap3_logic_defconfig
configs/omap3_logic_somlv_defconfig
configs/omapl138_lcdk_defconfig
configs/phycore-am335x-r2-regor_defconfig
configs/phycore-am335x-r2-wega_defconfig
configs/pxm2_defconfig
configs/rastaban_defconfig
configs/rut_defconfig
configs/sama5d3_xplained_nandflash_defconfig
configs/sama5d3xek_nandflash_defconfig
configs/sama5d4_xplained_nandflash_defconfig
configs/sama5d4ek_nandflash_defconfig
configs/sandbox64_defconfig
configs/sandbox_defconfig
configs/sandbox_noinst_defconfig
configs/smartweb_defconfig
configs/socfpga_secu1_defconfig
configs/stm32746g-eval_spl_defconfig
configs/stm32f746-disco_spl_defconfig
configs/stm32f769-disco_spl_defconfig
configs/stm32mp15_basic_defconfig
configs/stm32mp15_dhcom_basic_defconfig
configs/stm32mp15_dhcor_basic_defconfig
configs/taurus_defconfig
configs/thuban_defconfig
doc/device-tree-bindings/nand/sandbox,nand.txt [new file with mode: 0644]
drivers/mtd/Makefile
drivers/mtd/nand/raw/Kconfig
drivers/mtd/nand/raw/Makefile
drivers/mtd/nand/raw/am335x_spl_bch.c
drivers/mtd/nand/raw/atmel_nand.c
drivers/mtd/nand/raw/denali_spl.c
drivers/mtd/nand/raw/fsl_ifc_spl.c
drivers/mtd/nand/raw/lpc32xx_nand_mlc.c
drivers/mtd/nand/raw/mt7621_nand_spl.c
drivers/mtd/nand/raw/mxc_nand_spl.c
drivers/mtd/nand/raw/mxs_nand_spl.c
drivers/mtd/nand/raw/nand.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/nand/raw/nand_spl_loaders.c
drivers/mtd/nand/raw/nand_spl_simple.c
drivers/mtd/nand/raw/omap_gpmc.c
drivers/mtd/nand/raw/sand_nand.c [new file with mode: 0644]
drivers/mtd/nand/raw/sunxi_nand_spl.c
drivers/mtd/onenand/onenand_uboot.c
include/linux/mtd/mtd.h
include/mtd/cfi_flash.h
include/nand.h
include/os.h
include/system-constants.h
test/dm/Makefile
test/dm/nand.c [new file with mode: 0644]
test/image/Kconfig
test/image/Makefile
test/image/spl_load_nand.c [new file with mode: 0644]

diff --git a/README b/README
index 60c6b8a..00d4227 100644 (file)
--- a/README
+++ b/README
@@ -1191,11 +1191,10 @@ The following options need to be configured:
                Support for a lightweight UBI (fastmap) scanner and
                loader
 
-               CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
-               CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
-               CONFIG_SYS_NAND_BLOCK_SIZE, CONFIG_SYS_NAND_BAD_BLOCK_POS,
-               CFG_SYS_NAND_ECCPOS, CFG_SYS_NAND_ECCSIZE,
-               CFG_SYS_NAND_ECCBYTES
+               CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_SIZE,
+               CONFIG_SYS_NAND_OOBSIZE, CONFIG_SYS_NAND_BLOCK_SIZE,
+               CONFIG_SYS_NAND_BAD_BLOCK_POS, CFG_SYS_NAND_ECCPOS,
+               CFG_SYS_NAND_ECCSIZE, CFG_SYS_NAND_ECCBYTES
                Defines the size and behavior of the NAND that SPL uses
                to read U-Boot
 
index 85d0d6a..8847c4c 100644 (file)
@@ -282,6 +282,23 @@ int os_persistent_file(char *buf, int maxsize, const char *fname)
        return 0;
 }
 
+int os_mktemp(char *fname, off_t size)
+{
+       int fd;
+
+       fd = mkostemp(fname, O_CLOEXEC);
+       if (fd < 0)
+               return -errno;
+
+       if (unlink(fname) < 0)
+               return -errno;
+
+       if (ftruncate(fd, size))
+               return -errno;
+
+       return fd;
+}
+
 /* Restore tty state when we exit */
 static struct termios orig_term;
 static bool term_setup;
index 2887f6c..6fd62fc 100644 (file)
                                compatible = "sandbox,arm-ffa";
                };
        };
+
+       nand-controller {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "sandbox,nand";
+
+               nand@0 {
+                       reg = <0>;
+                       nand-ecc-mode = "soft";
+                       sandbox,id = [00 e3];
+                       sandbox,erasesize = <(8 * 1024)>;
+                       sandbox,oobsize = <16>;
+                       sandbox,pagesize = <512>;
+                       sandbox,pages = <0x2000>;
+                       sandbox,err-count = <1>;
+                       sandbox,err-step-size = <512>;
+               };
+
+               /* MT29F64G08AKABA */
+               nand@1 {
+                       reg = <1>;
+                       nand-ecc-mode = "soft_bch";
+                       sandbox,id = [2C 48 00 26 89 00 00 00];
+                       sandbox,onfi = [
+                               4f 4e 46 49 0e 00 5a 00
+                               ff 01 00 00 00 00 03 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               4d 49 43 52 4f 4e 20 20
+                               20 20 20 20 4d 54 32 39
+                               46 36 34 47 30 38 41 4b
+                               41 42 41 43 35 20 20 20
+                               2c 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 10 00 00 e0 00 00 02
+                               00 00 1c 00 80 00 00 00
+                               00 10 00 00 02 23 01 50
+                               00 01 05 01 00 00 04 00
+                               04 01 1e 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               0e 1f 00 1f 00 f4 01 ac
+                               0d 19 00 c8 00 00 00 00
+                               00 00 00 00 00 00 0a 07
+                               19 00 00 00 00 00 00 00
+                               00 00 00 00 01 00 01 00
+                               00 00 04 10 01 81 04 02
+                               02 01 1e 90 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 00 00 00
+                               00 00 00 00 00 03 20 7d
+                       ];
+                       sandbox,erasesize = <(512 * 1024)>;
+                       sandbox,oobsize = <224>;
+                       sandbox,pagesize = <4096>;
+                       sandbox,pages = <0x200000>;
+                       sandbox,err-count = <3>;
+                       sandbox,err-step-size = <512>;
+               };
+       };
 };
 
 #include "sandbox_pmic.dtsi"
index f349ea1..4fab24c 100644 (file)
@@ -15,6 +15,7 @@ enum {
        BOOT_DEVICE_CPGMAC,
        BOOT_DEVICE_NOR,
        BOOT_DEVICE_SPI,
+       BOOT_DEVICE_NAND,
 };
 
 /**
index 71b8f96..fe834c4 100644 (file)
@@ -34,6 +34,7 @@
 #include <env.h>
 #include <watchdog.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <asm/byteorder.h>
 #include <jffs2/jffs2.h>
 #include <nand.h>
@@ -432,7 +433,7 @@ static void nand_print_and_set_info(int idx)
        env_set_hex("nand_erasesize", mtd->erasesize);
 }
 
-static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
+static int raw_access(struct mtd_info *mtd, void *buf, loff_t off,
                      ulong count, int read, int no_verify)
 {
        int ret = 0;
@@ -440,8 +441,8 @@ static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
        while (count--) {
                /* Raw access */
                mtd_oob_ops_t ops = {
-                       .datbuf = (u8 *)addr,
-                       .oobbuf = ((u8 *)addr) + mtd->writesize,
+                       .datbuf = buf,
+                       .oobbuf = buf + mtd->writesize,
                        .len = mtd->writesize,
                        .ooblen = mtd->oobsize,
                        .mode = MTD_OPS_RAW
@@ -461,7 +462,7 @@ static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
                        break;
                }
 
-               addr += mtd->writesize + mtd->oobsize;
+               buf += mtd->writesize + mtd->oobsize;
                off += mtd->writesize;
        }
 
@@ -675,6 +676,7 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc,
                int read;
                int raw = 0;
                int no_verify = 0;
+               void *buf;
 
                if (argc < 4)
                        goto usage;
@@ -730,32 +732,32 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc,
                }
 
                mtd = get_nand_dev_by_index(dev);
+               buf = map_sysmem(addr, maxsize);
 
                if (!s || !strcmp(s, ".jffs2") ||
                    !strcmp(s, ".e") || !strcmp(s, ".i")) {
                        if (read)
                                ret = nand_read_skip_bad(mtd, off, &rwsize,
-                                                        NULL, maxsize,
-                                                        (u_char *)addr);
+                                                        NULL, maxsize, buf);
                        else
                                ret = nand_write_skip_bad(mtd, off, &rwsize,
-                                                         NULL, maxsize,
-                                                         (u_char *)addr,
+                                                         NULL, maxsize, buf,
                                                          WITH_WR_VERIFY);
 #ifdef CONFIG_CMD_NAND_TRIMFFS
                } else if (!strcmp(s, ".trimffs")) {
                        if (read) {
                                printf("Unknown nand command suffix '%s'\n", s);
+                               unmap_sysmem(buf);
                                return 1;
                        }
                        ret = nand_write_skip_bad(mtd, off, &rwsize, NULL,
-                                               maxsize, (u_char *)addr,
+                                               maxsize, buf,
                                                WITH_DROP_FFS | WITH_WR_VERIFY);
 #endif
                } else if (!strcmp(s, ".oob")) {
                        /* out-of-band data */
                        mtd_oob_ops_t ops = {
-                               .oobbuf = (u8 *)addr,
+                               .oobbuf = buf,
                                .ooblen = rwsize,
                                .mode = MTD_OPS_RAW
                        };
@@ -765,13 +767,15 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc,
                        else
                                ret = mtd_write_oob(mtd, off, &ops);
                } else if (raw) {
-                       ret = raw_access(mtd, addr, off, pagecount, read,
+                       ret = raw_access(mtd, buf, off, pagecount, read,
                                         no_verify);
                } else {
                        printf("Unknown nand command suffix '%s'.\n", s);
+                       unmap_sysmem(buf);
                        return 1;
                }
 
+               unmap_sysmem(buf);
                printf(" %zu bytes %s: %s\n", rwsize,
                       read ? "read" : "written", ret ? "ERROR" : "OK");
 
index 25cd18a..00332cf 100644 (file)
@@ -857,7 +857,7 @@ config SPL_MPC8XXX_INIT_DDR
          allows DRAM to be set up before loading U-Boot into that DRAM,
          where it can run.
 
-config SPL_MTD_SUPPORT
+config SPL_MTD
        bool "Support MTD drivers"
        help
          Enable support for MTD (Memory Technology Device) within SPL. MTD
index 51656fb..9189576 100644 (file)
@@ -133,25 +133,31 @@ int spl_load_legacy_img(struct spl_image_info *spl_image,
                           map_sysmem(spl_image->load_addr, spl_image->size));
                break;
 
-       case IH_COMP_LZMA:
+       case IH_COMP_LZMA: {
+               ulong overhead, size;
+
                lzma_len = LZMA_LEN;
 
                /* dataptr points to compressed payload  */
-               dataptr = offset + sizeof(*hdr);
+               dataptr = ALIGN_DOWN(sizeof(*hdr), load->bl_len);
+               overhead = sizeof(*hdr) - dataptr;
+               size = ALIGN(spl_image->size + overhead, load->bl_len);
+               dataptr += offset;
 
                debug("LZMA: Decompressing %08lx to %08lx\n",
                      dataptr, spl_image->load_addr);
-               src = malloc(spl_image->size);
+               src = malloc(size);
                if (!src) {
                        printf("Unable to allocate %d bytes for LZMA\n",
                               spl_image->size);
                        return -ENOMEM;
                }
 
-               load->read(load, dataptr, spl_image->size, src);
+               load->read(load, dataptr, size, src);
                ret = lzmaBuffToBuffDecompress(map_sysmem(spl_image->load_addr,
                                                          spl_image->size),
-                                              &lzma_len, src, spl_image->size);
+                                              &lzma_len, src + overhead,
+                                              spl_image->size);
                if (ret) {
                        printf("LZMA decompression error: %d\n", ret);
                        return ret;
@@ -159,7 +165,7 @@ int spl_load_legacy_img(struct spl_image_info *spl_image,
 
                spl_image->size = lzma_len;
                break;
-
+       }
        default:
                debug("Compression method %s is not supported\n",
                      genimg_get_comp_short_name(image_get_comp(hdr)));
index 07916be..b8cd640 100644 (file)
@@ -11,6 +11,7 @@
 #include <log.h>
 #include <spl.h>
 #include <asm/io.h>
+#include <mapmem.h>
 #include <nand.h>
 #include <linux/libfdt_env.h>
 #include <fdt.h>
@@ -32,7 +33,8 @@ static int spl_nand_load_image(struct spl_image_info *spl_image,
 
        nand_spl_load_image(spl_nand_get_uboot_raw_page(),
                            CFG_SYS_NAND_U_BOOT_SIZE,
-                           (void *)CFG_SYS_NAND_U_BOOT_DST);
+                           map_sysmem(CFG_SYS_NAND_U_BOOT_DST,
+                                      CFG_SYS_NAND_U_BOOT_SIZE));
        spl_set_header_raw_uboot(spl_image);
        nand_deselect();
 
@@ -72,23 +74,18 @@ static ulong spl_nand_legacy_read(struct spl_load_info *load, ulong offs,
        return size;
 }
 
-struct mtd_info * __weak nand_get_mtd(void)
-{
-       return NULL;
-}
-
 static int spl_nand_load_element(struct spl_image_info *spl_image,
                                 struct spl_boot_device *bootdev,
                                 int offset, struct legacy_img_hdr *header)
 {
-       struct mtd_info *mtd = nand_get_mtd();
-       int bl_len = mtd ? mtd->writesize : 1;
+       int bl_len;
        int err;
 
        err = nand_spl_load_image(offset, sizeof(*header), (void *)header);
        if (err)
                return err;
 
+       bl_len = nand_page_size();
        if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
            image_get_magic(header) == FDT_MAGIC) {
                struct spl_load_info load;
@@ -105,7 +102,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
                struct spl_load_info load;
 
                load.dev = NULL;
-               load.priv = NULL;
+               load.priv = &offset;
                load.filename = NULL;
                load.bl_len = bl_len;
                load.read = spl_nand_fit_read;
@@ -118,7 +115,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
                load.dev = NULL;
                load.priv = NULL;
                load.filename = NULL;
-               load.bl_len = 1;
+               load.bl_len = IS_ENABLED(CONFIG_SPL_LZMA) ? bl_len : 1;
                load.read = spl_nand_legacy_read;
 
                return spl_load_legacy_img(spl_image, bootdev, &load, offset, header);
@@ -127,7 +124,8 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
                if (err)
                        return err;
                return nand_spl_load_image(offset, spl_image->size,
-                                          (void *)(ulong)spl_image->load_addr);
+                                          map_sysmem(spl_image->load_addr,
+                                                     spl_image->size));
        }
 }
 
index 16993ef..0599ae2 100644 (file)
@@ -22,7 +22,7 @@ CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -67,7 +67,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index f048e60..5d38dad 100644 (file)
@@ -26,7 +26,7 @@ CONFIG_SPL_FIT_IMAGE_TINY=y
 CONFIG_SPL_ETH=y
 # CONFIG_SPL_FS_EXT4 is not set
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_MUSB_NEW=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
@@ -84,7 +84,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 9866246..b5b11fb 100644 (file)
@@ -28,7 +28,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_FIT_IMAGE_TINY=y
 # CONFIG_SPL_FS_EXT4 is not set
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_SPI_LOAD=y
index 01d848c..5369e46 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0x100
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index b961b6c..ea46e58 100644 (file)
@@ -27,7 +27,7 @@ CONFIG_SPL_FIT_IMAGE_TINY=y
 # CONFIG_SPL_ENV_SUPPORT is not set
 # CONFIG_SPL_FS_EXT4 is not set
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
index b5d8eac..7886557 100644 (file)
@@ -29,7 +29,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_FIT_IMAGE_TINY=y
 # CONFIG_SPL_ENV_SUPPORT is not set
 # CONFIG_SPL_FS_EXT4 is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
index 4dd6366..e2c5b70 100644 (file)
@@ -24,7 +24,7 @@ CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -85,7 +85,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_MTD_UBI_FASTMAP=y
index 9ba376f..fb61dd7 100644 (file)
@@ -28,7 +28,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
index 0a83ac9..a96936c 100644 (file)
@@ -26,7 +26,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
 # CONFIG_SPL_FS_EXT4 is not set
 # CONFIG_SPL_I2C is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -75,7 +75,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 6571afd..d5ce299 100644 (file)
@@ -22,7 +22,7 @@ CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_ETH=y
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -72,7 +72,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index e84aed4..a0a9e8a 100644 (file)
@@ -21,7 +21,7 @@ CONFIG_SPL_MAX_SIZE=0x439e0
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -62,7 +62,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 0cae324..cd47806 100644 (file)
@@ -20,7 +20,7 @@ CONFIG_SPL_MAX_SIZE=0x37690
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -75,7 +75,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 370ee96..d721664 100644 (file)
@@ -28,7 +28,7 @@ CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_ETH=y
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -68,7 +68,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index d52de8b..4070415 100644 (file)
@@ -43,7 +43,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
 CONFIG_SPL_DMA=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_DOMAIN=y
index f436986..55289b9 100644 (file)
@@ -52,7 +52,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_DOMAIN=y
index f9c0214..e1a01b2 100644 (file)
@@ -86,7 +86,6 @@ CONFIG_MTD=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 06642d2..0cd649d 100644 (file)
@@ -63,7 +63,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 73ccefd..1a558b0 100644 (file)
@@ -37,7 +37,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x480
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
index ecf61f0..5eaa6db 100644 (file)
@@ -81,7 +81,6 @@ CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 5f6f5d7..62b8edd 100644 (file)
@@ -88,7 +88,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_DAVINCI=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index ec4031d..569b156 100644 (file)
@@ -73,7 +73,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_LPC32XX_SLC=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 # CONFIG_SYS_NAND_5_ADDR_CYCLE is not set
index ef16da1..a7f8244 100644 (file)
@@ -77,7 +77,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_HAM1_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 19ca89f..c3a3ec2 100644 (file)
@@ -104,7 +104,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index ee19920..2a82087 100644 (file)
@@ -100,7 +100,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index c0ce7a3..4ac0abc 100644 (file)
@@ -104,7 +104,6 @@ CONFIG_SYS_MAX_NAND_DEVICE=3
 CONFIG_NAND_OMAP_ECCSCHEME_BCH16_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x80000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x80
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 439fcc0..0fb92ff 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_MTD=y
 CONFIG_NAND_ATMEL=y
 CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 993bbe2..34439cf 100644 (file)
@@ -24,7 +24,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SPL_FS_EXT4 is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -78,7 +78,6 @@ CONFIG_SYS_MTDPARTS_RUNTIME=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index d6edc71..c471e04 100644 (file)
@@ -25,7 +25,7 @@ CONFIG_BOARD_LATE_INIT=y
 CONFIG_SPL_BSS_START_ADDR=0x84100000
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_DMA=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_CMD_DM=y
index 657eb35..a9c0297 100644 (file)
@@ -43,7 +43,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300
 CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_SPL_NAND_BASE=y
 CONFIG_SPL_NAND_IDENT=y
index cb4a141..01f1957 100644 (file)
@@ -50,7 +50,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
index d25dd81..10b7205 100644 (file)
@@ -48,7 +48,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
index 99e0e16..1d043f2 100644 (file)
@@ -50,7 +50,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
index e76ab59..55169bb 100644 (file)
@@ -53,7 +53,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
index 876f078..a7adb92 100644 (file)
@@ -49,7 +49,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
index 4990e27..c0fdd86 100644 (file)
@@ -55,7 +55,7 @@ CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
 CONFIG_SPL_DM_MAILBOX=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NOR_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
index ef9e15d..e1ddc0a 100644 (file)
@@ -90,7 +90,6 @@ CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_MXC=y
 CONFIG_MXC_NAND_HWECC=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 539b0cf..5040af0 100644 (file)
@@ -30,7 +30,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
 # CONFIG_SPL_FS_EXT4 is not set
 # CONFIG_SPL_I2C is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -74,7 +74,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index f14ce3d..1ea35c7 100644 (file)
@@ -31,7 +31,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
 # CONFIG_SPL_FS_EXT4 is not set
 # CONFIG_SPL_I2C is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -83,7 +83,6 @@ CONFIG_SYS_MAX_FLASH_SECT=256
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index cabd365..c8c9ae0 100644 (file)
@@ -22,7 +22,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SPL_FS_EXT4 is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -83,7 +83,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_HAM1_CODE_HW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 33ff39f..93427f3 100644 (file)
@@ -22,7 +22,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SPL_FS_EXT4 is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -74,7 +74,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 7d3d602..729586b 100644 (file)
@@ -29,7 +29,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
 # CONFIG_SPL_FS_EXT4 is not set
 # CONFIG_SPL_I2C is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -73,7 +73,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 0141a42..f0f326d 100644 (file)
@@ -31,7 +31,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
 # CONFIG_SPL_FS_EXT4 is not set
 # CONFIG_SPL_I2C is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_SIMPLE=y
@@ -84,7 +84,6 @@ CONFIG_SYS_MAX_FLASH_SECT=256
 CONFIG_MTD_RAW_NAND=y
 CONFIG_NAND_OMAP_ECCSCHEME_BCH8_CODE_HW_DETECTION_SW=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 47feff2..63554d5 100644 (file)
@@ -84,7 +84,6 @@ CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_USE_FLASH_BBT=y
 CONFIG_NAND_DAVINCI=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
index 4bdf882..cbfe1cf 100644 (file)
@@ -28,7 +28,7 @@ CONFIG_ARCH_MISC_INIT=y
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -76,7 +76,6 @@ CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 7644fbe..b91b966 100644 (file)
@@ -28,7 +28,7 @@ CONFIG_ARCH_MISC_INIT=y
 CONFIG_SPL_SYS_MALLOC=y
 CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_DRIVERS=y
 CONFIG_SPL_NAND_ECC=y
 CONFIG_SPL_NAND_BASE=y
@@ -76,7 +76,6 @@ CONFIG_DM_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 2ea007d..e1d1066 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 9f538a2..2149534 100644 (file)
@@ -100,7 +100,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index ccf2566..248073b 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index a1b6122..a0802f9 100644 (file)
@@ -86,7 +86,6 @@ CONFIG_PMECC_CAP=4
 CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 6278a6c..d96bb91 100644 (file)
@@ -90,7 +90,6 @@ CONFIG_PMECC_CAP=4
 CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index d12f749..68101a1 100644 (file)
@@ -84,7 +84,6 @@ CONFIG_PMECC_CAP=8
 CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 27bfcdf..b8062db 100644 (file)
@@ -81,7 +81,6 @@ CONFIG_PMECC_CAP=8
 CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x1000
 CONFIG_SYS_NAND_OOBSIZE=0xe0
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 6e80780..e3f7f11 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_TEXT_BASE=0
+CONFIG_SYS_MALLOC_LEN=0x6000000
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_ENV_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="sandbox64"
@@ -49,6 +50,7 @@ CONFIG_CMD_GPT_RENAME=y
 CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_LOADM=y
+CONFIG_CMD_MTD=y
 CONFIG_CMD_OSD=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_READ=y
@@ -166,6 +168,13 @@ CONFIG_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SANDBOX=y
 CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_SYS_MAX_NAND_DEVICE=8
+CONFIG_SYS_NAND_USE_FLASH_BBT=y
+CONFIG_NAND_SANDBOX=y
+CONFIG_SYS_NAND_ONFI_DETECTION=y
+CONFIG_SYS_NAND_PAGE_SIZE=0x200
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_BOOTDEV_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
index e615656..b7ae1f0 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_TEXT_BASE=0
+CONFIG_SYS_MALLOC_LEN=0x6000000
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_ENV_SIZE=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
@@ -73,6 +74,7 @@ CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_LOADM=y
 CONFIG_CMD_LSBLK=y
+CONFIG_CMD_MTD=y
 CONFIG_CMD_MUX=y
 CONFIG_CMD_OSD=y
 CONFIG_CMD_PCI=y
@@ -215,6 +217,13 @@ CONFIG_MMC_PCI=y
 CONFIG_MMC_SANDBOX=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_SYS_MAX_NAND_DEVICE=8
+CONFIG_SYS_NAND_USE_FLASH_BBT=y
+CONFIG_NAND_SANDBOX=y
+CONFIG_SYS_NAND_ONFI_DETECTION=y
+CONFIG_SYS_NAND_PAGE_SIZE=0x200
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_BOOTDEV_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
index 1fd074b..8cfe30b 100644 (file)
@@ -50,6 +50,13 @@ CONFIG_SPL_ETH=y
 CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C=y
 CONFIG_SPL_MMC_WRITE=y
+CONFIG_SPL_MTD=y
+CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_SPL_NAND_DRIVERS=y
+CONFIG_SPL_NAND_ECC=y
+CONFIG_SPL_NAND_SOFTECC=y
+CONFIG_SPL_NAND_BASE=y
+CONFIG_SPL_NAND_IDENT=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_NET=y
 CONFIG_SPL_NOR_SUPPORT=y
@@ -79,6 +86,7 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
+CONFIG_CMD_MTD=y
 CONFIG_CMD_OSD=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_REMOTEPROC=y
@@ -179,6 +187,18 @@ CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_FS_LOADER=y
 CONFIG_MMC_SANDBOX=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_SYS_MAX_NAND_DEVICE=8
+CONFIG_SYS_NAND_USE_FLASH_BBT=y
+CONFIG_NAND_SANDBOX=y
+CONFIG_SYS_NAND_BLOCK_SIZE=0x2000
+CONFIG_SYS_NAND_ONFI_DETECTION=y
+CONFIG_SYS_NAND_PAGE_SIZE=0x200
+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
+CONFIG_SYS_NAND_U_BOOT_OFFS=0x0
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_SPI_FLASH_ATMEL=y
 CONFIG_SPI_FLASH_EON=y
index 10cbccb..80d2c0f 100644 (file)
@@ -84,7 +84,6 @@ CONFIG_MTD=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index b8052f1..6a4106a 100644 (file)
@@ -43,7 +43,7 @@ CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK=y
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1
 # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE is not set
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_SYS_MAXARGS=32
 CONFIG_SYS_BOOTM_LEN=0x4000000
index 3864e21..f9711be 100644 (file)
@@ -34,7 +34,7 @@ CONFIG_SPL_PAD_TO=0x9000
 CONFIG_SPL_NO_BSS_LIMIT=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_XIP_SUPPORT=y
 CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x80c0000
 CONFIG_SPL_DM_RESET=y
index b2a7861..a2b740c 100644 (file)
@@ -34,7 +34,7 @@ CONFIG_SPL_PAD_TO=0x9000
 CONFIG_SPL_NO_BSS_LIMIT=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_XIP_SUPPORT=y
 CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x80c0000
 CONFIG_SPL_DM_RESET=y
index 3462203..37d22f8 100644 (file)
@@ -33,7 +33,7 @@ CONFIG_SPL_PAD_TO=0x9000
 CONFIG_SPL_NO_BSS_LIMIT=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_XIP_SUPPORT=y
 CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x81c0000
 CONFIG_SPL_DM_RESET=y
index 6df0935..be553ad 100644 (file)
@@ -40,7 +40,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_POWER=y
 CONFIG_SPL_SPI_FLASH_MTD=y
index b6cd0a4..3d5df30 100644 (file)
@@ -47,7 +47,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_POWER=y
 CONFIG_SPL_RAM_SUPPORT=y
index d1acf9c..50a8882 100644 (file)
@@ -45,7 +45,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C=y
-CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_MTD=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_POWER=y
 CONFIG_SPL_RAM_SUPPORT=y
index cc57551..9be30c8 100644 (file)
@@ -94,7 +94,6 @@ CONFIG_MTD=y
 # CONFIG_SYS_NAND_USE_FLASH_BBT is not set
 CONFIG_NAND_ATMEL=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index 116700e..1134624 100644 (file)
@@ -100,7 +100,6 @@ CONFIG_MTD=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
 CONFIG_SYS_NAND_ONFI_DETECTION=y
-CONFIG_SYS_NAND_PAGE_COUNT=0x40
 CONFIG_SYS_NAND_PAGE_SIZE=0x800
 CONFIG_SYS_NAND_OOBSIZE=0x40
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
diff --git a/doc/device-tree-bindings/nand/sandbox,nand.txt b/doc/device-tree-bindings/nand/sandbox,nand.txt
new file mode 100644 (file)
index 0000000..0a723d7
--- /dev/null
@@ -0,0 +1,57 @@
+Sandbox NAND
+============
+
+The sandbox NAND controller emulates a NAND controller and attached devices.
+
+Required properties:
+- compatible: "sandbox,nand"
+- #address-cells: Must be 1
+- #size-cells: Must be 0
+
+Any number of child nodes may be present, each representing a NAND device:
+
+Required Properties:
+- reg: The chip-select(s) to use. Only single-die devices are supported for now.
+- sandbox,id: An array of bytes to be reported by the READID (0x90) command
+- sandbox,erasesize: The block size (erase size) of the device, in bytes. Must
+                     be a power-of-two multiple of the page size.
+- sandbox,oobsize: The size of the OOB area per page, in bytes.
+- sandbox,pagesize: The page size (write size) of the device, in bytes. Must be
+                    a power of two.
+- sandbox,pages: The total number of pages in the device.
+- sandbox,err-count: Number of bit errors to inject per step.
+- sandbox,err-step-size: Size of the step to use when injecting errors, in
+                         bytes. Must evenly divide the page size.
+
+Optional properties:
+- sandbox,onfi: The complete ONFI parameter page, including the CRC. Should be
+                exactly 256 bytes.
+- Any common NAND chip properties as documented by Linux's
+  Documentation/devicetree/bindings/mtd/raw-nand-chip.yaml
+
+To match U-Boot's error correction capabilities, errors are only injected into
+the data area and the ECC codes. Other data in the OOB area is never corrupted.
+Generally, sandbox,err-step-size should be the same as the ECC step size, and
+sandbox,err-count should be less than the number of correctable bit errors (the
+ECC strength).
+
+Example
+-------
+
+nand-controller {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       compatible = "sandbox,nand";
+
+       nand@0 {
+               reg = <0>;
+               nand-ecc-mode = "soft";
+               sandbox,id = [00 e3];
+               sandbox,erasesize = <(8 * 1024)>;
+               sandbox,oobsize = <16>;
+               sandbox,pagesize = <512>;
+               sandbox,pages = <0x2000>;
+               sandbox,err-count = <1>;
+               sandbox,err-step-size = <512>;
+       };
+};
index c638980..c2fc80b 100644 (file)
@@ -31,7 +31,7 @@ obj-$(CONFIG_NVMXIP) += nvmxip/
 else
 
 ifneq ($(mtd-y),)
-obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd.o
+obj-$(CONFIG_SPL_MTD) += mtd.o
 endif
 obj-$(CONFIG_$(SPL_TPL_)NAND_SUPPORT) += nand/
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += onenand/
index a13e6f5..bb9994b 100644 (file)
@@ -447,6 +447,22 @@ config NAND_PXA3XX
          This enables the driver for the NAND flash device found on
          PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
 
+config NAND_SANDBOX
+       bool "Support for NAND in sandbox"
+       depends on SANDBOX
+       select SYS_NAND_SELF_INIT
+       select SPL_SYS_NAND_SELF_INIT
+       select SPL_NAND_INIT
+       select SYS_NAND_SOFT_ECC
+       select BCH
+       select NAND_ECC_BCH
+       imply CMD_NAND
+       help
+         Enable a dummy NAND driver for sandbox. It simulates any number of
+         arbitrary NAND chips with a RAM buffer. It will also inject errors to
+         test ECC. At the moment, only 8-bit busses and single-chip devices are
+         supported.
+
 config NAND_SUNXI
        bool "Support for NAND on Allwinner SoCs"
        default ARCH_SUNXI
@@ -659,20 +675,13 @@ config SYS_NAND_ONFI_DETECTION
          And fetching device parameters flashed on device, by parsing
          ONFI parameter page.
 
-config SYS_NAND_PAGE_COUNT
-       hex "NAND chip page count"
-       depends on SPL_NAND_SUPPORT && (NAND_ATMEL || NAND_MXC || \
-               SPL_NAND_AM33XX_BCH || SPL_NAND_LOAD || SPL_NAND_SIMPLE || \
-               NAND_OMAP_GPMC)
-       help
-         Number of pages in the NAND chip.
-
 config SYS_NAND_PAGE_SIZE
        hex "NAND chip page size"
        depends on ARCH_SUNXI || NAND_OMAP_GPMC || NAND_LPC32XX_SLC || \
                SPL_NAND_SIMPLE || (NAND_MXC && SPL_NAND_SUPPORT) || \
                MVEBU_SPL_BOOT_DEVICE_NAND || \
-               (NAND_ATMEL && SPL_NAND_SUPPORT) || SPL_GENERATE_ATMEL_PMECC_HEADER
+               (NAND_ATMEL && SPL_NAND_SUPPORT) || \
+               SPL_GENERATE_ATMEL_PMECC_HEADER || NAND_SANDBOX
        depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_MT7621
        help
          Number of data bytes in one page for the NAND chip on the
index add2b4c..ddbba89 100644 (file)
@@ -70,6 +70,7 @@ obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
 obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
+obj-$(CONFIG_NAND_SANDBOX) += sand_nand.o
 obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
 obj-$(CONFIG_NAND_MXIC) += mxic_nand.o
 obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
index 6ab3f1f..6831af9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <nand.h>
+#include <system-constants.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/mtd/nand_ecc.h>
@@ -32,7 +33,7 @@ static int nand_command(int block, int page, uint32_t offs,
        u8 cmd)
 {
        struct nand_chip *this = mtd_to_nand(mtd);
-       int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+       int page_addr = page + block * SYS_NAND_BLOCK_PAGES;
        void (*hwctrl)(struct mtd_info *mtd, int cmd,
                        unsigned int ctrl) = this->cmd_ctrl;
 
@@ -217,6 +218,11 @@ void nand_init(void)
        nand_command(0, 0, 0, NAND_CMD_RESET);
 }
 
+unsigned int nand_page_size(void)
+{
+       return nand_to_mtd(&nand_chip)->writesize;
+}
+
 /* Unselect after operation */
 void nand_deselect(void)
 {
index 6b17e74..6d94e7a 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <common.h>
 #include <log.h>
+#include <system-constants.h>
 #include <asm/gpio.h>
 #include <asm/arch/gpio.h>
 #include <dm/device_compat.h>
@@ -1258,7 +1259,7 @@ static struct nand_chip nand_chip;
 static int nand_command(int block, int page, uint32_t offs, u8 cmd)
 {
        struct nand_chip *this = mtd_to_nand(mtd);
-       int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+       int page_addr = page + block * SYS_NAND_BLOCK_PAGES;
        void (*hwctrl)(struct mtd_info *mtd, int cmd,
                        unsigned int ctrl) = this->cmd_ctrl;
 
@@ -1359,7 +1360,7 @@ int spl_nand_erase_one(int block, int page)
        if (nand_chip.select_chip)
                nand_chip.select_chip(mtd, 0);
 
-       page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+       page_addr = page + block * SYS_NAND_BLOCK_PAGES;
        hwctrl(mtd, NAND_CMD_ERASE1, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
        /* Row address */
        hwctrl(mtd, (page_addr & 0xff), NAND_CTRL_ALE | NAND_CTRL_CHANGE);
@@ -1451,6 +1452,11 @@ void nand_init(void)
                nand_chip.select_chip(mtd, 0);
 }
 
+unsigned int nand_page_size(void)
+{
+       return nand_to_mtd(&nand_chip)->writesize;
+}
+
 void nand_deselect(void)
 {
        if (nand_chip.select_chip)
index 690279c..165a233 100644 (file)
@@ -234,4 +234,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
        return 0;
 }
 
+unsigned int nand_page_size(void)
+{
+       return page_size;
+}
+
 void nand_deselect(void) {}
index c67065e..69d26f1 100644 (file)
@@ -106,6 +106,8 @@ static inline int bad_block(uchar *marker, int port_size)
                return __raw_readw((u16 *)marker) != 0xffff;
 }
 
+static int saved_page_size;
+
 int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
 {
        struct fsl_ifc_fcm *gregs = (void *)CFG_SYS_IFC_ADDR;
@@ -150,6 +152,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
                if (port_size == 8)
                        bad_marker = 5;
        }
+       saved_page_size = page_size;
 
        ver = ifc_in32(&gregs->ifc_rev);
        if (ver >= FSL_IFC_V2_0_0)
@@ -302,6 +305,11 @@ void nand_init(void)
 {
 }
 
+unsigned int nand_page_size(void)
+{
+       return saved_page_size;
+}
+
 void nand_deselect(void)
 {
 }
index ac2e669..f8ae216 100644 (file)
@@ -765,4 +765,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
        return 0;
 }
 
+unsigned int nand_page_size(void)
+{
+       return BYTES_PER_PAGE;
+}
+
 #endif /* CONFIG_SPL_BUILD */
index 114fc8b..a2be9ba 100644 (file)
@@ -203,6 +203,11 @@ unsigned long nand_size(void)
        return SZ_2G;
 }
 
+unsigned int nand_page_size(void)
+{
+       return nfc_dev.nand.mtd.writesize;
+}
+
 void nand_deselect(void)
 {
 }
index 309e75d..a855c99 100644 (file)
@@ -13,6 +13,7 @@
 #include <common.h>
 #include <hang.h>
 #include <nand.h>
+#include <system-constants.h>
 #include <linux/mtd/rawnand.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
@@ -304,13 +305,13 @@ int nand_spl_load_image(uint32_t from, unsigned int size, void *buf)
                 * Check if we have crossed a block boundary, and if so
                 * check for bad block.
                 */
-               if (!(page % CONFIG_SYS_NAND_PAGE_COUNT)) {
+               if (!(page % SYS_NAND_BLOCK_PAGES)) {
                        /*
                         * Yes, new block. See if this block is good. If not,
                         * loop until we find a good block.
                         */
                        while (is_badblock(page)) {
-                               page = page + CONFIG_SYS_NAND_PAGE_COUNT;
+                               page = page + SYS_NAND_BLOCK_PAGES;
                                /* Check i we've reached the end of flash. */
                                if (page >= maxpages)
                                        return -1;
@@ -350,3 +351,8 @@ __used void nand_boot(void)
 
 void nand_init(void) {}
 void nand_deselect(void) {}
+
+unsigned int nand_page_size(void)
+{
+       return CONFIG_SYS_NAND_PAGE_SIZE;
+}
index 3006629..f7d3f02 100644 (file)
@@ -295,6 +295,11 @@ int nand_default_bbt(struct mtd_info *mtd)
        return 0;
 }
 
+unsigned int nand_page_size(void)
+{
+       return nand_to_mtd(&nand_chip)->writesize;
+}
+
 void nand_deselect(void)
 {
 }
index eacd99c..4c18861 100644 (file)
@@ -60,13 +60,11 @@ int nand_register(int devnum, struct mtd_info *mtd)
        sprintf(dev_name[devnum], "nand%d", devnum);
        mtd->name = dev_name[devnum];
 
-#ifdef CONFIG_MTD
        /*
         * Add MTD device so that we can reference it later
         * via the mtdcore infrastructure (e.g. ubi).
         */
        add_mtd_device(mtd);
-#endif
 
        total_nand_size += mtd->size / 1024;
 
@@ -76,6 +74,23 @@ int nand_register(int devnum, struct mtd_info *mtd)
        return 0;
 }
 
+void nand_unregister(struct mtd_info *mtd)
+{
+       int devnum = nand_mtd_to_devnum(mtd);
+
+       if (devnum < 0)
+               return;
+
+       if (nand_curr_device == devnum)
+               nand_curr_device = -1;
+
+       total_nand_size -= mtd->size / 1024;
+
+       del_mtd_device(nand_info[devnum]);
+
+       nand_info[devnum] = NULL;
+}
+
 #if !CONFIG_IS_ENABLED(SYS_NAND_SELF_INIT)
 static void nand_init_chip(int i)
 {
@@ -100,6 +115,8 @@ static void nand_init_chip(int i)
 #endif
 
 #ifdef CONFIG_MTD_CONCAT
+struct mtd_info *concat_mtd;
+
 static void create_mtd_concat(void)
 {
        struct mtd_info *nand_info_list[CONFIG_SYS_MAX_NAND_DEVICE];
@@ -114,28 +131,40 @@ static void create_mtd_concat(void)
                }
        }
        if (nand_devices_found > 1) {
-               struct mtd_info *mtd;
                char c_mtd_name[16];
 
                /*
                 * We detected multiple devices. Concatenate them together.
                 */
                sprintf(c_mtd_name, "nand%d", nand_devices_found);
-               mtd = mtd_concat_create(nand_info_list, nand_devices_found,
-                                       c_mtd_name);
+               concat_mtd = mtd_concat_create(nand_info_list,
+                                              nand_devices_found, c_mtd_name);
 
-               if (mtd == NULL)
+               if (!concat_mtd)
                        return;
 
-               nand_register(nand_devices_found, mtd);
+               nand_register(nand_devices_found, concat_mtd);
        }
 
        return;
 }
+
+static void destroy_mtd_concat(void)
+{
+       if (!concat_mtd)
+               return;
+
+       mtd_concat_destroy(concat_mtd);
+       concat_mtd = NULL;
+}
 #else
 static void create_mtd_concat(void)
 {
 }
+
+static void destroy_mtd_concat(void)
+{
+}
 #endif
 
 unsigned long nand_size(void)
@@ -143,10 +172,10 @@ unsigned long nand_size(void)
        return total_nand_size;
 }
 
+static int initialized;
+
 void nand_init(void)
 {
-       static int initialized;
-
        /*
         * Avoid initializing NAND Flash multiple times,
         * otherwise it will calculate a wrong total size.
@@ -174,3 +203,22 @@ void nand_init(void)
 
        create_mtd_concat();
 }
+
+void nand_reinit(void)
+{
+       int i;
+
+       destroy_mtd_concat();
+       for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
+               assert(!nand_info[i]);
+
+       initialized = 0;
+       nand_init();
+}
+
+unsigned int nand_page_size(void)
+{
+       struct mtd_info *mtd = get_nand_dev_by_index(nand_curr_device);
+
+       return mtd ? mtd->writesize : 1;
+}
index 6b4adcf..44b6cb6 100644 (file)
@@ -4462,17 +4462,14 @@ ident_done:
        else if (chip->jedec_version)
                pr_info("%s %s\n", manufacturer_desc->name,
                        chip->jedec_params.model);
-       else
+       else if (manufacturer_desc)
                pr_info("%s %s\n", manufacturer_desc->name, type->name);
 #else
        if (chip->jedec_version)
                pr_info("%s %s\n", manufacturer_desc->name,
                        chip->jedec_params.model);
-       else
+       else if (manufacturer_desc)
                pr_info("%s %s\n", manufacturer_desc->name, type->name);
-
-       pr_info("%s %s\n", manufacturer_desc->name,
-               type->name);
 #endif
 
        pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
index 156b44d..db4213e 100644 (file)
@@ -12,8 +12,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
        while (block <= lastblock) {
                if (!nand_is_bad_block(block)) {
                        /* Skip bad blocks */
-                       while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
+                       while (size && page < SYS_NAND_BLOCK_PAGES) {
                                nand_read_page(block, page, dst);
+
+                               size -= min(size, CONFIG_SYS_NAND_PAGE_SIZE -
+                                                 page_offset);
                                /*
                                 * When offs is not aligned to page address the
                                 * extra offset is copied to dst as well. Copy
index 2f3af9e..80d6e0e 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <nand.h>
+#include <system-constants.h>
 #include <asm/io.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/rawnand.h>
@@ -27,7 +28,7 @@ static int nand_command(int block, int page, uint32_t offs,
        u8 cmd)
 {
        struct nand_chip *this = mtd_to_nand(mtd);
-       int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+       int page_addr = page + block * SYS_NAND_BLOCK_PAGES;
 
        while (!this->dev_ready(mtd))
                ;
@@ -59,7 +60,7 @@ static int nand_command(int block, int page, uint32_t offs,
        u8 cmd)
 {
        struct nand_chip *this = mtd_to_nand(mtd);
-       int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+       int page_addr = page + block * SYS_NAND_BLOCK_PAGES;
        void (*hwctrl)(struct mtd_info *mtd, int cmd,
                        unsigned int ctrl) = this->cmd_ctrl;
 
@@ -226,6 +227,11 @@ void nand_init(void)
                nand_chip.select_chip(mtd, 0);
 }
 
+unsigned int nand_page_size(void)
+{
+       return nand_to_mtd(&nand_chip)->writesize;
+}
+
 /* Unselect after operation */
 void nand_deselect(void)
 {
index 1a5ed0d..0e25bd5 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <log.h>
+#include <system-constants.h>
 #include <asm/io.h>
 #include <dm/uclass.h>
 #include <linux/errno.h>
@@ -1298,7 +1299,7 @@ static int nand_is_bad_block(int block)
 
 static int nand_read_page(int block, int page, uchar *dst)
 {
-       int page_addr = block * CONFIG_SYS_NAND_PAGE_COUNT + page;
+       int page_addr = block * SYS_NAND_BLOCK_PAGES + page;
        loff_t ofs = page_addr * CONFIG_SYS_NAND_PAGE_SIZE;
        int ret;
        size_t len = CONFIG_SYS_NAND_PAGE_SIZE;
diff --git a/drivers/mtd/nand/raw/sand_nand.c b/drivers/mtd/nand/raw/sand_nand.c
new file mode 100644 (file)
index 0000000..229d7b5
--- /dev/null
@@ -0,0 +1,707 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) Sean Anderson <seanga2@gmail.com>
+ */
+
+#define LOG_CATEGORY UCLASS_MTD
+#include <errno.h>
+#include <hexdump.h>
+#include <log.h>
+#include <nand.h>
+#include <os.h>
+#include <rand.h>
+#include <spl.h>
+#include <system-constants.h>
+#include <dm/device_compat.h>
+#include <dm/read.h>
+#include <dm/uclass.h>
+#include <asm/bitops.h>
+#include <linux/bitmap.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/sizes.h>
+
+enum sand_nand_state {
+       STATE_READY,
+       STATE_IDLE,
+       STATE_READ,
+       STATE_READ_ID,
+       STATE_READ_ONFI,
+       STATE_PARAM_ONFI,
+       STATE_STATUS,
+       STATE_PROG,
+       STATE_ERASE,
+};
+
+static const char *const state_name[] = {
+       [STATE_READY] = "READY",
+       [STATE_IDLE] = "IDLE",
+       [STATE_READ] = "READ",
+       [STATE_READ_ID] = "READ_ID",
+       [STATE_READ_ONFI] = "READ_ONFI",
+       [STATE_PARAM_ONFI] = "PARAM_ONFI",
+       [STATE_STATUS] = "STATUS",
+       [STATE_PROG] = "PROG",
+       [STATE_ERASE] = "ERASE",
+};
+
+/**
+ * struct sand_nand_chip - Per-device private data
+ * @nand: The nand chip
+ * @node: The next device in this controller
+ * @programmed: Bitmap of whether sectors are programmed
+ * @id: ID to report for NAND_CMD_READID
+ * @id_len: Length of @id
+ * @onfi: Three copies of ONFI parameter page
+ * @status: Status to report for NAND_CMD_STATUS
+ * @chunksize: Size of one "chunk" (page + oob) in bytes
+ * @pageize: Size of one page in bytes
+ * @pages: Total number of pages
+ * @pages_per_erase: Number of pages per eraseblock
+ * @err_count: Number of errors to inject per @err_step_bits of data
+ * @err_step_bits: Number of data bits per error "step"
+ * @err_steps: Number of err steps in a page
+ * @cs: Chip select for this device
+ * @state: Current state of the device
+ * @column: Column of the most-recent command
+ * @page_addr: Page address of the most-recent command
+ * @fd: File descriptor for the backing data
+ * @fd_page_addr: Page address that @fd is seek'd to
+ * @selected: Whether this device is selected
+ * @tmp: "Cache" buffer used to store transferred data before committing it
+ * @tmp_dirty: Whether @tmp is dirty (modified) or clean (all ones)
+ *
+ * Data is stored with the OOB area in-line. For example, with 512-byte pages
+ * and and 16-byte OOB areas, the first page would start at offset 0, the second
+ * at offset 528, the third at offset 1056, and so on
+ */
+struct sand_nand_chip {
+       struct nand_chip nand;
+       struct list_head node;
+       long *programmed;
+       const u8 *id;
+       u32 chunksize, pagesize, pages, pages_per_erase;
+       u32 err_count, err_step_bits, err_steps, ecc_bits;
+       unsigned int cs;
+       enum sand_nand_state state;
+       int column, page_addr, fd, fd_page_addr;
+       bool selected, tmp_dirty;
+       u8 status;
+       u8 id_len;
+       u8 tmp[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
+       u8 onfi[sizeof(struct nand_onfi_params) * 3];
+};
+
+#define SAND_DEBUG(chip, fmt, ...) \
+       dev_dbg((chip)->nand.mtd.dev, "%u (%s): " fmt, (chip)->cs, \
+               state_name[(chip)->state], ##__VA_ARGS__)
+
+static inline void to_state(struct sand_nand_chip *chip,
+                           enum sand_nand_state new_state)
+{
+       if (new_state != chip->state)
+               SAND_DEBUG(chip, "to state %s\n", state_name[new_state]);
+       chip->state = new_state;
+}
+
+static inline struct sand_nand_chip *to_sand_nand(struct nand_chip *nand)
+{
+       return container_of(nand, struct sand_nand_chip, nand);
+}
+
+struct sand_nand_priv {
+       struct list_head chips;
+};
+
+static int sand_nand_dev_ready(struct mtd_info *mtd)
+{
+       return 1;
+}
+
+static int sand_nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
+{
+       u8 status;
+
+       return nand_status_op(chip, &status) ?: status;
+}
+
+static int sand_nand_seek(struct sand_nand_chip *chip)
+{
+       if (chip->fd_page_addr == chip->page_addr)
+               return 0;
+
+       if (os_lseek(chip->fd, (off_t)chip->page_addr * chip->chunksize,
+                    OS_SEEK_SET) < 0) {
+               SAND_DEBUG(chip, "could not seek: %d\n", errno);
+               return -EIO;
+       }
+
+       chip->fd_page_addr = chip->page_addr;
+       return 0;
+}
+
+static void sand_nand_inject_error(struct sand_nand_chip *chip,
+                                  unsigned int step, unsigned int pos)
+{
+       int byte, index;
+
+       if (pos < chip->err_step_bits) {
+               __change_bit(step * chip->err_step_bits + pos, chip->tmp);
+               return;
+       }
+
+       /*
+        * Only ECC bytes are covered in the OOB area, so
+        * pretend that those are the only bytes which can have
+        * errors.
+        */
+       byte = (pos - chip->err_step_bits + step * chip->ecc_bits) / 8;
+       index = chip->nand.ecc.layout->eccpos[byte];
+       /* Avoid endianness issues by working with bytes */
+       chip->tmp[chip->pagesize + index] ^= BIT(pos & 0x7);
+}
+
+static int sand_nand_read(struct sand_nand_chip *chip)
+{
+       unsigned int i, stop = 0;
+
+       if (chip->column == chip->pagesize)
+               stop = chip->err_step_bits;
+
+       if (test_bit(chip->page_addr, chip->programmed)) {
+               if (sand_nand_seek(chip))
+                       return -EIO;
+
+               if (os_read(chip->fd, chip->tmp, chip->chunksize) !=
+                   chip->chunksize) {
+                       SAND_DEBUG(chip, "could not read: %d\n", errno);
+                       return -EIO;
+               }
+               chip->fd_page_addr++;
+       } else if (chip->tmp_dirty) {
+               memset(chip->tmp + chip->column, 0xff,
+                      chip->chunksize - chip->column);
+       }
+
+       /*
+        * Inject some errors; this is Method A from "An Efficient Algorithm for
+        * Sequential Random Sampling" (Vitter 87). This is still slow when
+        * generating a lot (dozens) of ECC errors.
+        *
+        * To avoid generating too many errors in any one ECC step, we separate
+        * our error generation by ECC step.
+        */
+       chip->tmp_dirty = true;
+       for (i = 0; i < chip->err_steps; i++) {
+               u32 bit_errors = chip->err_count;
+               unsigned int j = chip->err_step_bits + chip->ecc_bits;
+
+               while (bit_errors) {
+                       unsigned int u = rand();
+                       float quot = 1ULL << 32;
+
+                       do {
+                               quot *= j - bit_errors;
+                               quot /= j;
+                               j--;
+
+                               if (j < stop)
+                                       goto next;
+                       } while (u < quot);
+
+                       sand_nand_inject_error(chip, i, j);
+                       bit_errors--;
+               }
+next:
+               ;
+       }
+
+       return 0;
+}
+
+static void sand_nand_command(struct mtd_info *mtd, unsigned int command,
+                             int column, int page_addr)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sand_nand_chip *chip = to_sand_nand(nand);
+       enum sand_nand_state new_state = chip->state;
+
+       SAND_DEBUG(chip, "command=%02x column=%d page_addr=%d\n", command,
+                  column, page_addr);
+
+       if (!chip->selected)
+               return;
+
+       switch (chip->state) {
+       case STATE_READY:
+               if (command == NAND_CMD_RESET)
+                       goto reset;
+               break;
+       case STATE_PROG:
+               new_state = STATE_IDLE;
+               if (command != NAND_CMD_PAGEPROG ||
+                   test_and_set_bit(chip->page_addr, chip->programmed)) {
+                       chip->status |= NAND_STATUS_FAIL;
+                       break;
+               }
+
+               if (sand_nand_seek(chip)) {
+                       chip->status |= NAND_STATUS_FAIL;
+                       break;
+               }
+
+               if (os_write(chip->fd, chip->tmp, chip->chunksize) !=
+                   chip->chunksize) {
+                       SAND_DEBUG(chip, "could not write: %d\n", errno);
+                       chip->status |= NAND_STATUS_FAIL;
+                       break;
+               }
+
+               chip->fd_page_addr++;
+               break;
+       case STATE_ERASE:
+               new_state = STATE_IDLE;
+               if (command != NAND_CMD_ERASE2) {
+                       chip->status |= NAND_STATUS_FAIL;
+                       break;
+               }
+
+               if (chip->page_addr < 0 ||
+                   chip->page_addr >= chip->pages ||
+                   chip->page_addr % chip->pages_per_erase)
+                       chip->status |= NAND_STATUS_FAIL;
+               else
+                       bitmap_clear(chip->programmed, chip->page_addr,
+                                    chip->pages_per_erase);
+               break;
+       default:
+               chip->column = column;
+               chip->page_addr = page_addr;
+               switch (command) {
+               case NAND_CMD_READOOB:
+                       if (column >= 0)
+                               chip->column += chip->pagesize;
+                       fallthrough;
+               case NAND_CMD_READ0:
+                       new_state = STATE_IDLE;
+                       if (page_addr < 0 || page_addr >= chip->pages)
+                               break;
+
+                       if (chip->column < 0 || chip->column >= chip->chunksize)
+                               break;
+
+                       if (sand_nand_read(chip))
+                               break;
+
+                       chip->page_addr = page_addr;
+                       new_state = STATE_READ;
+                       break;
+               case NAND_CMD_ERASE1:
+                       new_state = STATE_ERASE;
+                       chip->status = ~NAND_STATUS_FAIL;
+                       break;
+               case NAND_CMD_STATUS:
+                       new_state = STATE_STATUS;
+                       chip->column = 0;
+                       break;
+               case NAND_CMD_SEQIN:
+                       new_state = STATE_PROG;
+                       chip->status = ~NAND_STATUS_FAIL;
+                       if (page_addr < 0 || page_addr >= chip->pages ||
+                           chip->column < 0 ||
+                           chip->column >= chip->chunksize) {
+                               chip->status |= NAND_STATUS_FAIL;
+                       } else if (chip->tmp_dirty) {
+                               memset(chip->tmp, 0xff, chip->chunksize);
+                               chip->tmp_dirty = false;
+                       }
+                       break;
+               case NAND_CMD_READID:
+                       if (chip->onfi[0] && column == 0x20)
+                               new_state = STATE_READ_ONFI;
+                       else
+                               new_state = STATE_READ_ID;
+                       chip->column = 0;
+                       break;
+               case NAND_CMD_PARAM:
+                       if (chip->onfi[0] && !column)
+                               new_state = STATE_PARAM_ONFI;
+                       else
+                               new_state = STATE_IDLE;
+                       break;
+               case NAND_CMD_RESET:
+reset:
+                       new_state = STATE_IDLE;
+                       chip->column = -1;
+                       chip->page_addr = -1;
+                       chip->status = ~NAND_STATUS_FAIL;
+                       break;
+               default:
+                       new_state = STATE_IDLE;
+                       SAND_DEBUG(chip, "Unsupported command %02x\n", command);
+               }
+       }
+
+       to_state(chip, new_state);
+}
+
+static void sand_nand_select_chip(struct mtd_info *mtd, int n)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sand_nand_chip *chip = to_sand_nand(nand);
+
+       chip->selected = !n;
+}
+
+static void sand_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sand_nand_chip *chip = to_sand_nand(nand);
+       unsigned int to_copy;
+       int src_len = 0;
+       const u8 *src = NULL;
+
+       if (!chip->selected)
+               goto copy;
+
+       switch (chip->state) {
+       case STATE_READ:
+               src = chip->tmp;
+               src_len = chip->chunksize;
+               break;
+       case STATE_READ_ID:
+               src = chip->id;
+               src_len = chip->id_len;
+               break;
+       case STATE_READ_ONFI:
+               src = "ONFI";
+               src_len = 4;
+               break;
+       case STATE_PARAM_ONFI:
+               src = chip->onfi;
+               src_len = sizeof(chip->onfi);
+               break;
+       case STATE_STATUS:
+               src = &chip->status;
+               src_len = 1;
+               break;
+       default:
+               break;
+       }
+
+copy:
+       if (chip->column >= 0)
+               to_copy = max(min(len, src_len - chip->column), 0);
+       else
+               to_copy = 0;
+       memcpy(buf, src + chip->column, to_copy);
+       memset(buf + to_copy, 0xff, len - to_copy);
+       chip->column += to_copy;
+
+       if (len == 1) {
+               SAND_DEBUG(chip, "read [ %02x ]\n", buf[0]);
+       } else if (src_len) {
+               SAND_DEBUG(chip, "read %d bytes\n", len);
+#ifdef VERBOSE_DEBUG
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
+#endif
+       }
+
+       if (src_len && chip->column == src_len)
+               to_state(chip, STATE_IDLE);
+}
+
+static u8 sand_nand_read_byte(struct mtd_info *mtd)
+{
+       u8 ret;
+
+       sand_nand_read_buf(mtd, &ret, 1);
+       return ret;
+}
+
+static u16 sand_nand_read_word(struct mtd_info *mtd)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sand_nand_chip *chip = to_sand_nand(nand);
+
+       SAND_DEBUG(chip, "16-bit access unsupported\n");
+       return sand_nand_read_byte(mtd) | 0xff00;
+}
+
+static void sand_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sand_nand_chip *chip = to_sand_nand(nand);
+
+       SAND_DEBUG(chip, "write %d bytes\n", len);
+#ifdef VERBOSE_DEBUG
+       print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
+#endif
+
+       if (chip->state != STATE_PROG || chip->status & NAND_STATUS_FAIL)
+               return;
+
+       chip->tmp_dirty = true;
+       len = min((unsigned int)len, chip->chunksize - chip->column);
+       memcpy(chip->tmp + chip->column, buf, len);
+       chip->column += len;
+}
+
+static struct nand_chip *nand_chip;
+
+int sand_nand_remove(struct udevice *dev)
+{
+       struct sand_nand_priv *priv = dev_get_priv(dev);
+       struct sand_nand_chip *chip;
+
+       list_for_each_entry(chip, &priv->chips, node) {
+               struct nand_chip *nand = &chip->nand;
+
+               if (nand_chip == nand)
+                       nand_chip = NULL;
+
+               nand_unregister(nand_to_mtd(nand));
+               free(chip->programmed);
+               os_close(chip->fd);
+               free(chip);
+       }
+
+       return 0;
+}
+
+static int sand_nand_probe(struct udevice *dev)
+{
+       struct sand_nand_priv *priv = dev_get_priv(dev);
+       struct sand_nand_chip *chip;
+       int ret, devnum = 0;
+       ofnode np;
+
+       INIT_LIST_HEAD(&priv->chips);
+
+       dev_for_each_subnode(np, dev) {
+               struct nand_chip *nand;
+               struct mtd_info *mtd;
+               u32 erasesize, oobsize, pagesize, pages;
+               u32 err_count, err_step_size;
+               off_t expected_size;
+               char filename[30];
+               fdt_addr_t cs;
+               const u8 *id, *onfi;
+               int id_len, onfi_len;
+
+               cs = ofnode_get_addr_size_index_notrans(np, 0, NULL);
+               if (cs == FDT_ADDR_T_NONE) {
+                       dev_dbg(dev, "Invalid cs for chip %s\n",
+                               ofnode_get_name(np));
+                       ret = -ENOENT;
+                       goto err;
+               }
+
+               id = ofnode_read_prop(np, "sandbox,id", &id_len);
+               if (!id) {
+                       dev_dbg(dev, "No sandbox,id property for chip %s\n",
+                               ofnode_get_name(np));
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               onfi = ofnode_read_prop(np, "sandbox,onfi", &onfi_len);
+               if (onfi && onfi_len != sizeof(struct nand_onfi_params)) {
+                       dev_dbg(dev, "Invalid length %d for onfi params\n",
+                               onfi_len);
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               ret = ofnode_read_u32(np, "sandbox,erasesize", &erasesize);
+               if (ret) {
+                       dev_dbg(dev, "No sandbox,erasesize property for chip %s",
+                               ofnode_get_name(np));
+                       goto err;
+               }
+
+               ret = ofnode_read_u32(np, "sandbox,oobsize", &oobsize);
+               if (ret) {
+                       dev_dbg(dev, "No sandbox,oobsize property for chip %s",
+                               ofnode_get_name(np));
+                       goto err;
+               }
+
+               ret = ofnode_read_u32(np, "sandbox,pagesize", &pagesize);
+               if (ret) {
+                       dev_dbg(dev, "No sandbox,pagesize property for chip %s",
+                               ofnode_get_name(np));
+                       goto err;
+               }
+
+               ret = ofnode_read_u32(np, "sandbox,pages", &pages);
+               if (ret) {
+                       dev_dbg(dev, "No sandbox,pages property for chip %s",
+                               ofnode_get_name(np));
+                       goto err;
+               }
+
+               ret = ofnode_read_u32(np, "sandbox,err-count", &err_count);
+               if (ret) {
+                       dev_dbg(dev,
+                               "No sandbox,err-count property for chip %s",
+                               ofnode_get_name(np));
+                       goto err;
+               }
+
+               ret = ofnode_read_u32(np, "sandbox,err-step-size",
+                                     &err_step_size);
+               if (ret) {
+                       dev_dbg(dev,
+                               "No sandbox,err-step-size property for chip %s",
+                               ofnode_get_name(np));
+                       goto err;
+               }
+
+               chip = calloc(sizeof(*chip), 1);
+               if (!chip) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               chip->cs = cs;
+               chip->id = id;
+               chip->id_len = id_len;
+               chip->chunksize = pagesize + oobsize;
+               chip->pagesize = pagesize;
+               chip->pages = pages;
+               chip->pages_per_erase = erasesize / pagesize;
+               memset(chip->tmp, 0xff, chip->chunksize);
+
+               chip->err_count = err_count;
+               chip->err_step_bits = err_step_size * 8;
+               chip->err_steps = pagesize / err_step_size;
+
+               expected_size = (off_t)pages * chip->chunksize;
+               snprintf(filename, sizeof(filename),
+                        "/tmp/u-boot.nand%d.XXXXXX", devnum);
+               chip->fd = os_mktemp(filename, expected_size);
+               if (chip->fd < 0) {
+                       dev_dbg(dev, "Could not create temp file %s\n",
+                               filename);
+                       ret = chip->fd;
+                       goto err_chip;
+               }
+
+               chip->programmed = calloc(sizeof(long),
+                                         BITS_TO_LONGS(pages));
+               if (!chip->programmed) {
+                       ret = -ENOMEM;
+                       goto err_fd;
+               }
+
+               if (onfi) {
+                       memcpy(chip->onfi, onfi, onfi_len);
+                       memcpy(chip->onfi + onfi_len, onfi, onfi_len);
+                       memcpy(chip->onfi + 2 * onfi_len, onfi, onfi_len);
+               }
+
+               nand = &chip->nand;
+               nand->options = spl_in_proper() ? 0 : NAND_SKIP_BBTSCAN;
+               nand->flash_node = np;
+               nand->dev_ready = sand_nand_dev_ready;
+               nand->cmdfunc = sand_nand_command;
+               nand->waitfunc = sand_nand_wait;
+               nand->select_chip = sand_nand_select_chip;
+               nand->read_byte = sand_nand_read_byte;
+               nand->read_word = sand_nand_read_word;
+               nand->read_buf = sand_nand_read_buf;
+               nand->write_buf = sand_nand_write_buf;
+               nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK;
+
+               mtd = nand_to_mtd(nand);
+               mtd->dev = dev;
+
+               ret = nand_scan(mtd, CONFIG_SYS_NAND_MAX_CHIPS);
+               if (ret) {
+                       dev_dbg(dev, "Could not scan chip %s: %d\n",
+                               ofnode_get_name(np), ret);
+                       goto err_prog;
+               }
+               chip->ecc_bits = nand->ecc.layout->eccbytes * 8 /
+                                chip->err_steps;
+
+               ret = nand_register(devnum, mtd);
+               if (ret) {
+                       dev_dbg(dev, "Could not register nand %d: %d\n", devnum,
+                               ret);
+                       goto err_prog;
+               }
+
+               if (!nand_chip)
+                       nand_chip = nand;
+
+               list_add_tail(&chip->node, &priv->chips);
+               devnum++;
+               continue;
+
+err_prog:
+               free(chip->programmed);
+err_fd:
+               os_close(chip->fd);
+err_chip:
+               free(chip);
+               goto err;
+       }
+
+       return 0;
+
+err:
+       sand_nand_remove(dev);
+       return ret;
+}
+
+static const struct udevice_id sand_nand_ids[] = {
+       { .compatible = "sandbox,nand" },
+       { }
+};
+
+U_BOOT_DRIVER(sand_nand) = {
+       .name           = "sand-nand",
+       .id             = UCLASS_MTD,
+       .of_match       = sand_nand_ids,
+       .probe          = sand_nand_probe,
+       .remove         = sand_nand_remove,
+       .priv_auto      = sizeof(struct sand_nand_priv),
+};
+
+void board_nand_init(void)
+{
+       struct udevice *dev;
+       int err;
+
+       err = uclass_get_device_by_driver(UCLASS_MTD, DM_DRIVER_REF(sand_nand),
+                                         &dev);
+       if (err && err != -ENODEV)
+               log_info("Failed to get sandbox NAND: %d\n", err);
+}
+
+#if IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_SPL_NAND_INIT)
+void nand_deselect(void)
+{
+       nand_chip->select_chip(nand_to_mtd(nand_chip), -1);
+}
+
+static int nand_is_bad_block(int block)
+{
+       struct mtd_info *mtd = nand_to_mtd(nand_chip);
+
+       return mtd_block_isbad(mtd, block << mtd->erasesize_shift);
+}
+
+static int nand_read_page(int block, int page, uchar *dst)
+{
+       struct mtd_info *mtd = nand_to_mtd(nand_chip);
+       loff_t ofs = ((loff_t)block << mtd->erasesize_shift) +
+                    ((loff_t)page << mtd->writesize_shift);
+       size_t len = mtd->writesize;
+
+       return nand_read(mtd, ofs, &len, dst);
+}
+
+#include "nand_spl_loaders.c"
+#endif /* CONFIG_SPL_NAND_INIT */
index 6de0b0a..c9b8c78 100644 (file)
@@ -524,9 +524,10 @@ static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
        return 0;
 }
 
+static struct nfc_config conf;
+
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
 {
-       static struct nfc_config conf = { };
        int ret;
 
        ret = nand_detect_config(&conf, offs, dest);
@@ -536,6 +537,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
        return nand_read_buffer(&conf, offs, size, dest);
 }
 
+unsigned int nand_page_size(void)
+{
+       return conf.page_size;
+}
+
 void nand_deselect(void)
 {
        struct sunxi_ccm_reg *const ccm =
index 04791df..ecacabe 100644 (file)
@@ -44,14 +44,12 @@ void onenand_init(void)
                        puts("Flex-");
                puts("OneNAND: ");
 
-#ifdef CONFIG_MTD
                /*
                 * Add MTD device so that we can reference it later
                 * via the mtdcore infrastructure (e.g. ubi).
                 */
                onenand_mtd.name = dev_name;
                add_mtd_device(&onenand_mtd);
-#endif
        }
        print_size(onenand_chip.chipsize, "\n");
 }
index 09f5269..7a66c7a 100644 (file)
@@ -552,8 +552,20 @@ unsigned mtd_mmap_capabilities(struct mtd_info *mtd);
 
 #ifdef __UBOOT__
 /* drivers/mtd/mtdcore.h */
+#if CONFIG_IS_ENABLED(MTD)
 int add_mtd_device(struct mtd_info *mtd);
 int del_mtd_device(struct mtd_info *mtd);
+#else
+static inline int add_mtd_device(struct mtd_info *mtd)
+{
+       return -ENOSYS;
+}
+
+static inline int del_mtd_device(struct mtd_info *mtd)
+{
+       return -ENOSYS;
+}
+#endif
 
 #ifdef CONFIG_MTD_PARTITIONS
 int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
index 52cd1c4..f4aecaa 100644 (file)
@@ -163,7 +163,7 @@ struct cfi_pri_hdr {
 #if defined(CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
 /* map to cfi_flash_num_flash_banks only when supported */
 #if IS_ENABLED(CONFIG_FLASH_CFI_DRIVER) && \
-    (!IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_SPL_MTD_SUPPORT))
+    (!IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_SPL_MTD))
 #define CFI_FLASH_BANKS                (cfi_flash_num_flash_banks)
 /* board code can update this variable before CFI detection */
 extern int cfi_flash_num_flash_banks;
index 70c1286..220ffa2 100644 (file)
@@ -11,7 +11,9 @@
 #include <config.h>
 
 extern void nand_init(void);
+void nand_reinit(void);
 unsigned long nand_size(void);
+unsigned int nand_page_size(void);
 
 #include <linux/compat.h>
 #include <linux/mtd/mtd.h>
@@ -21,6 +23,7 @@ int nand_mtd_to_devnum(struct mtd_info *mtd);
 #if CONFIG_IS_ENABLED(SYS_NAND_SELF_INIT)
 void board_nand_init(void);
 int nand_register(int devnum, struct mtd_info *mtd);
+void nand_unregister(struct mtd_info *mtd);
 #else
 struct nand_chip;
 
index fc8a1b1..877404a 100644 (file)
@@ -108,6 +108,19 @@ int os_unlink(const char *pathname);
  */
 int os_persistent_file(char *buf, int maxsize, const char *fname);
 
+/**
+ * os_mktemp() - Create a temporary file
+ * @fname: The template to use for the file name. This must end with 6 Xs. It
+ *         will be modified to the opened filename on success.
+ * @size: The size of the file
+ *
+ * Create a temporary file using @fname as a template, unlink it, and truncate
+ * it to @size.
+ *
+ * Return: A file descriptor, or negative errno on error
+ */
+int os_mktemp(char *fname, off_t size);
+
 /**
  * os_exit() - access to the OS exit() system call
  *
index 5937156..d688629 100644 (file)
@@ -41,4 +41,8 @@
 #define SPL_PAYLOAD_ARGS_ADDR  0
 #endif
 
+/* Number of pages per block */
+#define SYS_NAND_BLOCK_PAGES \
+       (CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE)
+
 #endif
index cb82d83..a3ce7b3 100644 (file)
@@ -73,6 +73,7 @@ obj-$(CONFIG_CMD_MUX) += mux-cmd.o
 obj-$(CONFIG_MULTIPLEXER) += mux-emul.o
 obj-$(CONFIG_MUX_MMIO) += mux-mmio.o
 obj-y += fdtdec.o
+obj-$(CONFIG_MTD_RAW_NAND) += nand.o
 obj-$(CONFIG_UT_DM) += nop.o
 obj-y += ofnode.o
 obj-y += ofread.o
diff --git a/test/dm/nand.c b/test/dm/nand.c
new file mode 100644 (file)
index 0000000..0b992fd
--- /dev/null
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
+ */
+
+#include <nand.h>
+#include <part.h>
+#include <rand.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+
+static int dm_test_nand(struct unit_test_state *uts, int dev, bool end)
+{
+       nand_erase_options_t opts = { };
+       struct mtd_info *mtd;
+       size_t length;
+       loff_t size;
+       char *buf;
+       int *gold;
+       u8 oob[NAND_MAX_OOBSIZE];
+       int i;
+       loff_t off = 0;
+       mtd_oob_ops_t ops = { };
+
+       /* Seed RNG for bit errors */
+       srand((off >> 32) ^ off ^ ~dev);
+
+       mtd = get_nand_dev_by_index(dev);
+       ut_assertnonnull(mtd);
+       size = mtd->erasesize * 4;
+       length = size;
+
+       buf = malloc(size);
+       ut_assertnonnull(buf);
+       gold = malloc(size);
+       ut_assertnonnull(gold);
+
+       /* Mark a block as bad */
+       ut_assertok(mtd_block_markbad(mtd, off + mtd->erasesize));
+
+       /* Erase some stuff */
+       if (end)
+               off = mtd->size - size - mtd->erasesize;
+       opts.offset = off;
+       opts.length = size;
+       opts.spread = 1;
+       opts.lim = U32_MAX;
+       ut_assertok(nand_erase_opts(mtd, &opts));
+
+       /* Make sure everything is erased */
+       memset(gold, 0xff, size);
+       ut_assertok(nand_read_skip_bad(mtd, off, &length, NULL, U64_MAX, buf));
+       ut_asserteq(size, length);
+       ut_asserteq_mem(gold, buf, size);
+
+       /* ...but our bad block marker is still there */
+       ops.oobbuf = oob;
+       ops.ooblen = mtd->oobsize;
+       ut_assertok(mtd_read_oob(mtd, mtd->erasesize, &ops));
+       ut_asserteq(0, oob[mtd_to_nand(mtd)->badblockpos]);
+
+       /* Generate some data and write it */
+       for (i = 0; i < size / sizeof(int); i++)
+               gold[i] = rand();
+       ut_assertok(nand_write_skip_bad(mtd, off, &length, NULL, U64_MAX,
+                                       (void *)gold, 0));
+       ut_asserteq(size, length);
+
+       /* Verify */
+       ut_assertok(nand_read_skip_bad(mtd, off, &length, NULL, U64_MAX, buf));
+       ut_asserteq(size, length);
+       ut_asserteq_mem(gold, buf, size);
+
+       /* Erase some blocks */
+       memset(((char *)gold) + mtd->erasesize, 0xff, mtd->erasesize * 2);
+       opts.offset = off + mtd->erasesize;
+       opts.length = mtd->erasesize * 2;
+       ut_assertok(nand_erase_opts(mtd, &opts));
+
+       /* Verify */
+       ut_assertok(nand_read_skip_bad(mtd, off, &length, NULL, U64_MAX, buf));
+       ut_asserteq(size, length);
+       ut_asserteq_mem(gold, buf, size);
+
+       return 0;
+}
+
+#define DM_NAND_TEST(dev) \
+static int dm_test_nand##dev##_start(struct unit_test_state *uts) \
+{ \
+       return dm_test_nand(uts, dev, false); \
+} \
+DM_TEST(dm_test_nand##dev##_start, UT_TESTF_SCAN_FDT); \
+static int dm_test_nand##dev##_end(struct unit_test_state *uts) \
+{ \
+       return dm_test_nand(uts, dev, true); \
+} \
+DM_TEST(dm_test_nand##dev##_end, UT_TESTF_SCAN_FDT)
+
+DM_NAND_TEST(0);
+DM_NAND_TEST(1);
index 8f9e6ae..6f0bb81 100644 (file)
@@ -23,6 +23,15 @@ config SPL_UT_LOAD_FS
        help
          Test filesystems and the various load methods which use them.
 
+config SPL_UT_LOAD_NAND
+       bool "Test loading from NAND flash"
+       depends on SANDBOX && SPL_OF_REAL
+       depends on SPL_NAND_SUPPORT
+       depends on SPL_MTD
+       default y
+       help
+         Test the NAND flash load method.
+
 config SPL_UT_LOAD_NET
        bool "Test loading over TFTP"
        depends on SANDBOX && SPL_OF_REAL
index b302101..11ed257 100644 (file)
@@ -4,6 +4,7 @@
 
 obj-y += spl_load.o
 obj-$(CONFIG_SPL_UT_LOAD_FS) += spl_load_fs.o
+obj-$(CONFIG_SPL_UT_LOAD_NAND) += spl_load_nand.o
 obj-$(CONFIG_SPL_UT_LOAD_NET) += spl_load_net.o
 obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_load_nor.o
 obj-$(CONFIG_SPL_UT_LOAD_OS) += spl_load_os.o
diff --git a/test/image/spl_load_nand.c b/test/image/spl_load_nand.c
new file mode 100644 (file)
index 0000000..30179de
--- /dev/null
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
+ */
+
+#include <nand.h>
+#include <spl.h>
+#include <test/spl.h>
+#include <test/ut.h>
+
+uint32_t spl_nand_get_uboot_raw_page(void);
+
+static int spl_test_nand_write_image(struct unit_test_state *uts, void *img,
+                                    size_t img_size)
+{
+       uint32_t off = spl_nand_get_uboot_raw_page();
+       struct mtd_info *mtd;
+       struct erase_info erase = { };
+       size_t length;
+
+       nand_reinit();
+       mtd = get_nand_dev_by_index(0);
+       ut_assertnonnull(mtd);
+
+       /* Mark the first block as bad to test that it gets skipped */
+       ut_assertok(mtd_block_markbad(mtd, off & ~mtd->erasesize_mask));
+       off += mtd->erasesize;
+
+       erase.mtd = mtd;
+       erase.len = img_size + (off & mtd->erasesize_mask);
+       erase.len += mtd->erasesize_mask;
+       erase.len &= ~mtd->erasesize_mask;
+       erase.addr = off & ~mtd->erasesize_mask;
+       erase.scrub = 1;
+       ut_assertok(mtd_erase(mtd, &erase));
+
+       ut_assertok(mtd_write(mtd, off, img_size, &length, img));
+
+       return 0;
+}
+
+static int spl_test_nand(struct unit_test_state *uts, const char *test_name,
+                        enum spl_test_image type)
+{
+       return do_spl_test_load(uts, test_name, type,
+                               SPL_LOAD_IMAGE_GET(1, BOOT_DEVICE_NAND,
+                                                  spl_nand_load_image),
+                               spl_test_nand_write_image);
+}
+SPL_IMG_TEST(spl_test_nand, LEGACY, DM_FLAGS);
+SPL_IMG_TEST(spl_test_nand, LEGACY_LZMA, DM_FLAGS);
+SPL_IMG_TEST(spl_test_nand, IMX8, DM_FLAGS);
+SPL_IMG_TEST(spl_test_nand, FIT_INTERNAL, DM_FLAGS);
+SPL_IMG_TEST(spl_test_nand, FIT_EXTERNAL, DM_FLAGS);