[U-Boot] [PATCH v2] NAND: Add 16bit NAND support for the NDFC

From dc3cda4054bc94c2ae3c1d104b5162681a16e7ac Mon Sep 17 00:00:00 2001
From: Alex Waterman awaterman@dawning.com Date: Thu, 19 May 2011 15:08:36 -0400 Subject: [PATCH v2] NAND: Add 16bit NAND support for the NDFC
This patch adds support for 16 bit NAND devices attached to the NDFC on ppc4xx processors. Two config entries were added:
CONFIG_SYS_NDFC_16 - Setting this tells the NDFC that a 16 bit device is attached. CONFIG_SYS_NDFC_EBC0_CFG - This is for the External Bus Controller configuration register.
Also, a new ndfc_read_byte() function was added which does not first convert the data to little endian.
The NAND SPL was also modified to do 16bit bad block testing when a 16 bit chip is being used.
Signed-off-by: Alex Waterman awaterman@dawning.com Cc: Scott Wood scottwood@freescale.com Cc: Stefan Roese sr@denx.de --- README | 8 ++++++++ drivers/mtd/nand/ndfc.c | 33 +++++++++++++++++++++++++++++---- nand_spl/nand_boot.c | 12 +++++++++--- 3 files changed, 46 insertions(+), 7 deletions(-)
Changes for v2: - Changes dynamic checking of chip options field to a compile time check.
diff --git a/README b/README index 6f3748d..3ede798 100644 --- a/README +++ b/README @@ -2912,6 +2912,14 @@ Low Level (hardware related) configuration options: - CONFIG_SYS_SRIOn_MEM_SIZE: Size of SRIO port 'n' memory region
+- CONFIG_SYS_NDFC_16 + Defined to tell the NDFC that the NAND chip is using a + 16 bit bus. + +- CONFIG_SYS_NDFC_EBC0_CFG + Sets the EBC0_CFG register for the NDFC. If not defined + a default value will be used. + - CONFIG_SPD_EEPROM Get DDR timing information from an I2C EEPROM. Common with pluggable memory modules such as SODIMMs diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 0729e0c..6ebbb5e 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -37,6 +37,13 @@ #include <asm/io.h> #include <asm/ppc4xx.h>
+#ifndef CONFIG_SYS_NAND_BCR +#define CONFIG_SYS_NAND_BCR 0x80002222 +#endif +#ifndef CONFIG_SYS_NDFC_EBC0_CFG +#define CONFIG_SYS_NDFC_EBC0_CFG 0xb8400000 +#endif + /* * We need to store the info, which chip-select (CS) is used for the * chip number. For example on Sequoia NAND chip #0 uses @@ -140,12 +147,25 @@ static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len
return 0; } -#endif /* #ifndef CONFIG_NAND_SPL */
-#ifndef CONFIG_SYS_NAND_BCR -#define CONFIG_SYS_NAND_BCR 0x80002222 +/* + * Read a byte from the NDFC. + */ +static uint8_t ndfc_read_byte(struct mtd_info *mtd) +{ + + struct nand_chip *chip = mtd->priv; + +#ifdef CONFIG_SYS_NDFC_16BIT + return (uint8_t) readw(chip->IO_ADDR_R); +#else + return readb(chip->IO_ADDR_R); #endif
+} + +#endif /* #ifndef CONFIG_NAND_SPL */ + void board_nand_select_device(struct nand_chip *nand, int chip) { /* @@ -198,16 +218,21 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.bytes = 3; nand->select_chip = ndfc_select_chip;
+#ifdef CONFIG_SYS_NDFC_16BIT + nand->options |= NAND_BUSWIDTH_16; +#endif + #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; nand->verify_buf = ndfc_verify_buf; + nand->read_byte = ndfc_read_byte;
chip++; #else /* * Setup EBC (CS0 only right now) */ - mtebc(EBC0_CFG, 0xb8400000); + mtebc(EBC0_CFG, CONFIG_SYS_NDFC_EBC0_CFG);
mtebc(PB0CR, CONFIG_SYS_EBC_PB0CR); mtebc(PB0AP, CONFIG_SYS_EBC_PB0AP); diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c index 9545a9a..725356f 100644 --- a/nand_spl/nand_boot.c +++ b/nand_spl/nand_boot.c @@ -80,9 +80,10 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8 cmd = NAND_CMD_READ0; }
+#ifdef CONFIG_SYS_NDFC_16BIT /* Shift the offset from byte addressing to word addressing. */ - if (this->options & NAND_BUSWIDTH_16) - offs >>= 1; + offs >>= 1; +#endif
/* Begin command latch cycle */ hwctrl(mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE); @@ -122,10 +123,15 @@ static int nand_is_bad_block(struct mtd_info *mtd, int block) nand_command(mtd, block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS, NAND_CMD_READOOB);
/* - * Read one byte + * Read one byte (or two if it's a 16 bit chip). */ +#ifdef CONFIG_SYS_NDFC_16BIT + if (readw(this->IO_ADDR_R) != 0xffff) + return 1; +#else if (readb(this->IO_ADDR_R) != 0xff) return 1; +#endif
return 0; }

On Fri, May 27, 2011 at 10:00:07AM -0400, Alex Waterman wrote:
diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c index 9545a9a..725356f 100644 --- a/nand_spl/nand_boot.c +++ b/nand_spl/nand_boot.c @@ -80,9 +80,10 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8 cmd = NAND_CMD_READ0; }
+#ifdef CONFIG_SYS_NDFC_16BIT /* Shift the offset from byte addressing to word addressing. */
- if (this->options & NAND_BUSWIDTH_16)
offs >>= 1;
- offs >>= 1;
+#endif
This is not an NDFC-specific file.
-Scott

+#ifdef CONFIG_SYS_NDFC_16BIT /* Shift the offset from byte addressing to word addressing. */
- if (this->options & NAND_BUSWIDTH_16)
offs >>= 1;
- offs >>= 1;
+#endif
This is not an NDFC-specific file.
Oh, yeah, I see. This should not have been swapped to a preprocessor condition. Could we make a general define for 16 bit NAND not just limited to the NDFC? Or would you rather just have the extra if condition despite the extra code space it takes up?
Regards, Alex

On Tue, 7 Jun 2011 08:33:25 -0400 Alex Waterman awaterman@dawning.com wrote:
+#ifdef CONFIG_SYS_NDFC_16BIT /* Shift the offset from byte addressing to word addressing. */
- if (this->options & NAND_BUSWIDTH_16)
offs >>= 1;
- offs >>= 1;
+#endif
This is not an NDFC-specific file.
Oh, yeah, I see. This should not have been swapped to a preprocessor condition. Could we make a general define for 16 bit NAND not just limited to the NDFC? Or would you rather just have the extra if condition despite the extra code space it takes up?
I'm fine with either way. If you make it compile-time, make sure you update all boards that use SPL with 16-bit, and document that it's limited to SPL (unless you really want to update all the boards using 16-bit, SPL or not, and update the main NAND code to take advantage of this, and there's enough advantage to be gained to make it worthwhile).
-Scott
participants (2)
-
Alex Waterman
-
Scott Wood