# (C) Copyright 2003
#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
+# SPDX-License-Identifier: GPL-2.0+
Commands:
of data for one 512-byte page or 2 256-byte pages. There is no check
for bad blocks.
- nand read.raw addr ofs|partition
- Read page from `ofs' in NAND flash to `addr'. This reads the raw page,
- so ECC is avoided and the OOB area is read as well.
-
- nand write.raw addr ofs|partition
- Write page from `addr' to `ofs' in NAND flash. This writes the raw page,
- so ECC is avoided and the OOB area is written as well, making the whole
- page written as-is.
+ nand read.raw addr ofs|partition [count]
+ nand write.raw addr ofs|partition [count]
+ Read or write one or more pages at "ofs" in NAND flash, from or to
+ "addr" in memory. This is a raw access, so ECC is avoided and the
+ OOB area is transferred as well. If count is absent, it is assumed
+ to be one page. As with .yaffs2 accesses, the data is formatted as
+ a packed sequence of "data, oob, data, oob, ..." -- no alignment of
+ individual pages is maintained.
Configuration Options:
+ CONFIG_SYS_NAND_U_BOOT_OFFS
+ NAND Offset from where SPL will read u-boot image. This is the starting
+ address of u-boot MTD partition in NAND.
+
CONFIG_CMD_NAND
Enables NAND support and commmands.
+ CONFIG_CMD_NAND_TORTURE
+ Enables the torture command (see description of this command below).
+
CONFIG_MTD_NAND_ECC_JFFS2
Define this if you want the Error Correction Code information in
the out-of-band data to be formatted to match the JFFS2 file system.
CONFIG_SYS_MAX_NAND_DEVICE
The maximum number of NAND devices you want to support.
+ CONFIG_SYS_NAND_MAX_ECCPOS
+ If specified, overrides the maximum number of ECC bytes
+ supported. Useful for reducing image size, especially with SPL.
+ This must be at least 48 if nand_base.c is used.
+
+ CONFIG_SYS_NAND_MAX_OOBFREE
+ If specified, overrides the maximum number of free OOB regions
+ supported. Useful for reducing image size, especially with SPL.
+ This must be at least 2 if nand_base.c is used.
+
CONFIG_SYS_NAND_MAX_CHIPS
The maximum number of NAND chips per device to be supported.
+ CONFIG_SYS_NAND_SELF_INIT
+ Traditionally, glue code in drivers/mtd/nand/nand.c has driven
+ the initialization process -- it provides the mtd and nand
+ structs, calls a board init function for a specific device,
+ calls nand_scan(), and registers with mtd.
+
+ This arrangement does not provide drivers with the flexibility to
+ run code between nand_scan_ident() and nand_scan_tail(), or other
+ deviations from the "normal" flow.
+
+ If a board defines CONFIG_SYS_NAND_SELF_INIT, drivers/mtd/nand/nand.c
+ will make one call to board_nand_init(), with no arguments. That
+ function is responsible for calling a driver init function for
+ each NAND device on the board, that performs all initialization
+ tasks except setting mtd->name, and registering with the rest of
+ U-Boot. Those last tasks are accomplished by calling nand_register()
+ on the new mtd device.
+
+ Example of new init to be added to the end of an existing driver
+ init:
+
+ /*
+ * devnum is the device number to be used in nand commands
+ * and in mtd->name. Must be less than
+ * CONFIG_SYS_NAND_MAX_DEVICE.
+ */
+ mtd = &nand_info[devnum];
+
+ /* chip is struct nand_chip, and is now provided by the driver. */
+ mtd->priv = &chip;
+
+ /*
+ * Fill in appropriate values if this driver uses these fields,
+ * or uses the standard read_byte/write_buf/etc. functions from
+ * nand_base.c that use these fields.
+ */
+ chip.IO_ADDR_R = ...;
+ chip.IO_ADDR_W = ...;
+
+ if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_CHIPS, NULL))
+ error out
+
+ /*
+ * Insert here any code you wish to run after the chip has been
+ * identified, but before any other I/O is done.
+ */
+
+ if (nand_scan_tail(mtd))
+ error out
+
+ if (nand_register(devnum))
+ error out
+
+ In addition to providing more flexibility to the driver, it reduces
+ the difference between a U-Boot driver and its Linux counterpart.
+ nand_init() is now reduced to calling board_nand_init() once, and
+ printing a size summary. This should also make it easier to
+ transition to delayed NAND initialization.
+
+ Please convert your driver even if you don't need the extra
+ flexibility, so that one day we can eliminate the old mechanism.
+
+
+ CONFIG_SYS_NAND_ONFI_DETECTION
+ Enables detection of ONFI compliant devices during probe.
+ And fetching device parameters flashed on device, by parsing
+ ONFI parameter page.
+
+ CONFIG_BCH
+ Enables software based BCH ECC algorithm present in lib/bch.c
+ This is used by SoC platforms which do not have built-in ELM
+ hardware engine required for BCH ECC correction.
+
+ CONFIG_SYS_NAND_BUSWIDTH_16BIT
+ Indicates that NAND device has 16-bit wide data-bus. In absence of this
+ config, bus-width of NAND device is assumed to be either 8-bit and later
+ determined by reading ONFI params.
+ Above config is useful when NAND device's bus-width information cannot
+ be determined from on-chip ONFI params, like in following scenarios:
+ - SPL boot does not support reading of ONFI parameters. This is done to
+ keep SPL code foot-print small.
+ - In current U-Boot flow using nand_init(), driver initialization
+ happens in board_nand_init() which is called before any device probe
+ (nand_scan_ident + nand_scan_tail), thus device's ONFI parameters are
+ not available while configuring controller. So a static CONFIG_NAND_xx
+ is needed to know the device's bus-width in advance.
+ Some drivers using above config are:
+ drivers/mtd/nand/mxc_nand.c
+ drivers/mtd/nand/ndfc.c
+ drivers/mtd/nand/omap_gpmc.c
+
+
+Platform specific options
+=========================
+ CONFIG_NAND_OMAP_GPMC
+ Enables omap_gpmc.c driver for OMAPx and AMxxxx platforms.
+ GPMC controller is used for parallel NAND flash devices, and can
+ do ECC calculation (not ECC error detection) for HAM1, BCH4, BCH8
+ and BCH16 ECC algorithms.
+
+ CONFIG_NAND_OMAP_ELM
+ Enables omap_elm.c driver for OMAPx and AMxxxx platforms.
+ ELM controller is used for ECC error detection (not ECC calculation)
+ of BCH4, BCH8 and BCH16 ECC algorithms.
+ Some legacy platforms like OMAP3xx do not have in-built ELM h/w engine,
+ thus such SoC platforms need to depend on software library for ECC error
+ detection. However ECC calculation on such plaforms would still be
+ done by GPMC controller.
+
+ CONFIG_SPL_NAND_AM33XX_BCH
+ Enables SPL-NAND driver (am335x_spl_bch.c) which supports ELM based
+ hardware ECC correction. This is useful for platforms which have ELM
+ hardware engine and use NAND boot mode.
+ Some legacy platforms like OMAP3xx do not have in-built ELM h/w engine,
+ so those platforms should use CONFIG_SPL_NAND_SIMPLE for enabling
+ SPL-NAND driver with software ECC correction support.
+
+ CONFIG_NAND_OMAP_ECCSCHEME
+ On OMAP platforms, this CONFIG specifies NAND ECC scheme.
+ It can take following values:
+ OMAP_ECC_HAM1_CODE_SW
+ 1-bit Hamming code using software lib.
+ (for legacy devices only)
+ OMAP_ECC_HAM1_CODE_HW
+ 1-bit Hamming code using GPMC hardware.
+ (for legacy devices only)
+ OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
+ 4-bit BCH code (unsupported)
+ OMAP_ECC_BCH4_CODE_HW
+ 4-bit BCH code (unsupported)
+ OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
+ 8-bit BCH code with
+ - ecc calculation using GPMC hardware engine,
+ - error detection using software library.
+ - requires CONFIG_BCH to enable software BCH library
+ (For legacy device which do not have ELM h/w engine)
+ OMAP_ECC_BCH8_CODE_HW
+ 8-bit BCH code with
+ - ecc calculation using GPMC hardware engine,
+ - error detection using ELM hardware engine.
+ OMAP_ECC_BCH16_CODE_HW
+ 16-bit BCH code with
+ - ecc calculation using GPMC hardware engine,
+ - error detection using ELM hardware engine.
+
+ How to select ECC scheme on OMAP and AMxx platforms ?
+ -----------------------------------------------------
+ Though higher ECC schemes have more capability to detect and correct
+ bit-flips, but still selection of ECC scheme is dependent on following
+ - hardware engines present in SoC.
+ Some legacy OMAP SoC do not have ELM h/w engine thus such
+ SoC cannot support BCHx_HW ECC schemes.
+ - size of OOB/Spare region
+ With higher ECC schemes, more OOB/Spare area is required to
+ store ECC. So choice of ECC scheme is limited by NAND oobsize.
+
+ In general following expression can help:
+ NAND_OOBSIZE >= 2 + (NAND_PAGESIZE / 512) * ECC_BYTES
+ where
+ NAND_OOBSIZE = number of bytes available in
+ OOB/spare area per NAND page.
+ NAND_PAGESIZE = bytes in main-area of NAND page.
+ ECC_BYTES = number of ECC bytes generated to
+ protect 512 bytes of data, which is:
+ 3 for HAM1_xx ecc schemes
+ 7 for BCH4_xx ecc schemes
+ 14 for BCH8_xx ecc schemes
+ 26 for BCH16_xx ecc schemes
+
+ example to check for BCH16 on 2K page NAND
+ NAND_PAGESIZE = 2048
+ NAND_OOBSIZE = 64
+ 2 + (2048 / 512) * 26 = 106 > NAND_OOBSIZE
+ Thus BCH16 cannot be supported on 2K page NAND.
+
+ However, for 4K pagesize NAND
+ NAND_PAGESIZE = 4096
+ NAND_OOBSIZE = 64
+ ECC_BYTES = 26
+ 2 + (4096 / 512) * 26 = 210 < NAND_OOBSIZE
+ Thus BCH16 can be supported on 4K page NAND.
+
+
+ CONFIG_NAND_OMAP_GPMC_PREFETCH
+ On OMAP platforms that use the GPMC controller
+ (CONFIG_NAND_OMAP_GPMC_PREFETCH), this options enables the code that
+ uses the prefetch mode to speed up read operations.
+
NOTE:
=====
DANGEROUS!!! Factory set bad blocks will be lost. Use only
to remove artificial bad blocks created with the "markbad" command.
+ "torture offset"
+ Torture block to determine if it is still reliable.
+ Enabled by the CONFIG_CMD_NAND_TORTURE configuration option.
+ This command returns 0 if the block is still reliable, else 1.
+ If the block is detected as unreliable, it is up to the user to decide to
+ mark this block as bad.
+ The analyzed block is put through 3 erase / write cycles (or less if the block
+ is detected as unreliable earlier).
+ This command can be used in scripts, e.g. together with the markbad command to
+ automate retries and handling of possibly newly detected bad blocks if the
+ nand write command fails.
+ It can also be used manually by users having seen some NAND errors in logs to
+ search the root cause of these errors.
+ The underlying nand_torture() function is also useful for code willing to
+ automate actions following a nand->write() error. This would e.g. be required
+ in order to program or update safely firmware to NAND, especially for the UBI
+ part of such firmware.
+
NAND locking command (for chips with active LOCKPRE pin)
"nand unlock [offset] [size]"
unlock consecutive area (can be called multiple times for different areas)
+ "nand unlock.allexcept [offset] [size]"
+ unlock all except specified consecutive area
I have tested the code with board containing 128MiB NAND large page chips
and 32MiB small page chips.