-NAND Interface:
-
- #define NAND_WAIT_READY(nand)
- Wait until the NAND flash is ready. Typically this would be a
- loop waiting for the READY/BUSY line from the flash to indicate it
- it is ready.
-
- #define WRITE_NAND_COMMAND(d, adr)
- Write the command byte `d' to the flash at `adr' with the
- CLE (command latch enable) line true. If your board uses writes to
- different addresses to control CLE and ALE, you can modify `adr'
- to be the appropriate address here. If your board uses I/O registers
- to control them, it is probably better to let NAND_CTL_SETCLE()
- and company do it.
-
- #define WRITE_NAND_ADDRESS(d, adr)
- Write the address byte `d' to the flash at `adr' with the
- ALE (address latch enable) line true. If your board uses writes to
- different addresses to control CLE and ALE, you can modify `adr'
- to be the appropriate address here. If your board uses I/O registers
- to control them, it is probably better to let NAND_CTL_SETALE()
- and company do it.
-
- #define WRITE_NAND(d, adr)
- Write the data byte `d' to the flash at `adr' with the
- ALE and CLE lines false. If your board uses writes to
- different addresses to control CLE and ALE, you can modify `adr'
- to be the appropriate address here. If your board uses I/O registers
- to control them, it is probably better to let NAND_CTL_CLRALE()
- and company do it.
-
- #define READ_NAND(adr)
- Read a data byte from the flash at `adr' with the
- ALE and CLE lines false. If your board uses reads from
- different addresses to control CLE and ALE, you can modify `adr'
- to be the appropriate address here. If your board uses I/O registers
- to control them, it is probably better to let NAND_CTL_CLRALE()
- and company do it.
-
- #define NAND_DISABLE_CE(nand)
- Set CE (Chip Enable) low to enable the NAND flash.
-
- #define NAND_ENABLE_CE(nand)
- Set CE (Chip Enable) high to disable the NAND flash.
-
- #define NAND_CTL_CLRALE(nandptr)
- Set ALE (address latch enable) low. If ALE control is handled by
- WRITE_NAND_ADDRESS() this can be empty.
-
- #define NAND_CTL_SETALE(nandptr)
- Set ALE (address latch enable) high. If ALE control is handled by
- WRITE_NAND_ADDRESS() this can be empty.
-
- #define NAND_CTL_CLRCLE(nandptr)
- Set CLE (command latch enable) low. If CLE control is handled by
- WRITE_NAND_ADDRESS() this can be empty.
-
- #define NAND_CTL_SETCLE(nandptr)
- Set CLE (command latch enable) high. If CLE control is handled by
- WRITE_NAND_ADDRESS() this can be empty.
-
-More Definitions:
-
- These definitions are needed in the board configuration for now, but
- may really belong in a header file.
- TODO: Figure which ones are truly configuration settings and rename
- them to CFG_NAND_... and move the rest somewhere appropriate.
-
- #define SECTORSIZE 512
- #define ADDR_COLUMN 1
- #define ADDR_PAGE 2
- #define ADDR_COLUMN_PAGE 3
- #define NAND_ChipID_UNKNOWN 0x00
- #define NAND_MAX_FLOORS 1
- #define NAND_MAX_CHIPS 1
-
+ 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.