|  | NAND FLASH commands and notes | 
|  |  | 
|  | See NOTE below!!! | 
|  |  | 
|  | # (C) Copyright 2003 | 
|  | # Dave Ellis, SIXNET, dge@sixnetio.com | 
|  | # | 
|  | # 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 | 
|  |  | 
|  | Commands: | 
|  |  | 
|  | nand bad | 
|  | Print a list of all of the bad blocks in the current device. | 
|  |  | 
|  | nand device | 
|  | Print information about the current NAND device. | 
|  |  | 
|  | nand device num | 
|  | Make device `num' the current device and print information about it. | 
|  |  | 
|  | nand erase off|partition size | 
|  | nand erase clean [off|partition size] | 
|  | Erase `size' bytes starting at offset `off'. Alternatively partition | 
|  | name can be specified, in this case size will be eventually limited | 
|  | to not exceed partition size (this behaviour applies also to read | 
|  | and write commands). Only complete erase blocks can be erased. | 
|  |  | 
|  | If `erase' is specified without an offset or size, the entire flash | 
|  | is erased. If `erase' is specified with partition but without an | 
|  | size, the entire partition is erased. | 
|  |  | 
|  | If `clean' is specified, a JFFS2-style clean marker is written to | 
|  | each block after it is erased. | 
|  |  | 
|  | This command will not erase blocks that are marked bad. There is | 
|  | a debug option in cmd_nand.c to allow bad blocks to be erased. | 
|  | Please read the warning there before using it, as blocks marked | 
|  | bad by the manufacturer must _NEVER_ be erased. | 
|  |  | 
|  | nand info | 
|  | Print information about all of the NAND devices found. | 
|  |  | 
|  | nand read addr ofs|partition size | 
|  | Read `size' bytes from `ofs' in NAND flash to `addr'.  Blocks that | 
|  | are marked bad are skipped.  If a page cannot be read because an | 
|  | uncorrectable data error is found, the command stops with an error. | 
|  |  | 
|  | nand read.oob addr ofs|partition size | 
|  | Read `size' bytes from the out-of-band data area corresponding to | 
|  | `ofs' in NAND flash to `addr'. This is limited to the 16 bytes of | 
|  | data for one 512-byte page or 2 256-byte pages. There is no check | 
|  | for bad blocks or ECC errors. | 
|  |  | 
|  | nand write addr ofs|partition size | 
|  | Write `size' bytes from `addr' to `ofs' in NAND flash.  Blocks that | 
|  | are marked bad are skipped.  If a page cannot be read because an | 
|  | uncorrectable data error is found, the command stops with an error. | 
|  |  | 
|  | As JFFS2 skips blocks similarly, this allows writing a JFFS2 image, | 
|  | as long as the image is short enough to fit even after skipping the | 
|  | bad blocks.  Compact images, such as those produced by mkfs.jffs2 | 
|  | should work well, but loading an image copied from another flash is | 
|  | going to be trouble if there are any bad blocks. | 
|  |  | 
|  | nand write.trimffs addr ofs|partition size | 
|  | Enabled by the CONFIG_CMD_NAND_TRIMFFS macro. This command will write to | 
|  | the NAND flash in a manner identical to the 'nand write' command | 
|  | described above -- with the additional check that all pages at the end | 
|  | of eraseblocks which contain only 0xff data will not be written to the | 
|  | NAND flash. This behaviour is required when flashing UBI images | 
|  | containing UBIFS volumes as per the UBI FAQ[1]. | 
|  |  | 
|  | [1] http://www.linux-mtd.infradead.org/doc/ubi.html#L_flasher_algo | 
|  |  | 
|  | nand write.oob addr ofs|partition size | 
|  | Write `size' bytes from `addr' to the out-of-band data area | 
|  | corresponding to `ofs' in NAND flash. This is limited to the 16 bytes | 
|  | 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 [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_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_MTD_NAND_ECC_YAFFS would be another useful choice for | 
|  | someone to implement. | 
|  |  | 
|  | CONFIG_SYS_MAX_NAND_DEVICE | 
|  | The maximum number of NAND devices you want to support. | 
|  |  | 
|  | 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. | 
|  |  | 
|  | NOTE: | 
|  | ===== | 
|  |  | 
|  | The current NAND implementation is based on what is in recent | 
|  | Linux kernels.  The old legacy implementation has been removed. | 
|  |  | 
|  | If you have board code which used CONFIG_NAND_LEGACY, you'll need | 
|  | to convert to the current NAND interface for it to continue to work. | 
|  |  | 
|  | The Disk On Chip driver is currently broken and has been for some time. | 
|  | There is a driver in drivers/mtd/nand, taken from Linux, that works with | 
|  | the current NAND system but has not yet been adapted to the u-boot | 
|  | environment. | 
|  |  | 
|  | Additional improvements to the NAND subsystem by Guido Classen, 10-10-2006 | 
|  |  | 
|  | JFFS2 related commands: | 
|  |  | 
|  | implement "nand erase clean" and old "nand erase" | 
|  | using both the new code which is able to skip bad blocks | 
|  | "nand erase clean" additionally writes JFFS2-cleanmarkers in the oob. | 
|  |  | 
|  | Miscellaneous and testing commands: | 
|  | "markbad [offset]" | 
|  | create an artificial bad block (for testing bad block handling) | 
|  |  | 
|  | "scrub [offset length]" | 
|  | like "erase" but don't skip bad block. Instead erase them. | 
|  | 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 lock" | 
|  | set NAND chip to lock state (all pages locked) | 
|  |  | 
|  | "nand lock tight" | 
|  | set NAND chip to lock tight state (software can't change locking anymore) | 
|  |  | 
|  | "nand lock status" | 
|  | displays current locking status of all pages | 
|  |  | 
|  | "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. |