summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/mxc_nand.c461
-rw-r--r--drivers/mtd/nand/nand_base.c8
-rw-r--r--include/asm-arm/arch-mx35/mxc_nand.h1
-rw-r--r--include/asm-arm/arch-mx51/mx51.h8
-rw-r--r--include/asm-arm/arch-mx51/mxc_nand.h396
-rw-r--r--include/configs/mx51_3stack.h14
-rw-r--r--include/linux/mtd/nand.h4
7 files changed, 548 insertions, 344 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 7e224b7..953131d 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -15,7 +15,7 @@
#include <malloc.h>
#include <asm/io.h>
#include <asm/errno.h>
-#include <nand.h>
+#include <linux/mtd/nand.h>
#include <asm-arm/arch/mxc_nand.h>
struct nand_info {
@@ -143,6 +143,96 @@ static void wait_op_done(int max_retries)
MTDDEBUG(MTD_DEBUG_LEVEL0, "wait: INT not set\n");
}
+/*!
+ * This function sends an address (or partial address) to the
+ * NAND device. The address is used to select the source/destination for
+ * a NAND command.
+ *
+ * @param addr address to be written to NFC.
+ * @param useirq True if IRQ should be used rather than polling
+ */
+static void send_addr(u16 addr)
+{
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(0x%x)\n", addr);
+
+ /* fill address */
+ raw_write((addr << NFC_FLASH_ADDR_SHIFT), REG_NFC_FLASH_ADDR);
+
+ /* clear status */
+ ACK_OPS;
+
+ /* send out address */
+ raw_write(NFC_ADDR, REG_NFC_OPS);
+
+ /* Wait for operation to complete */
+ wait_op_done(TROP_US_DELAY);
+}
+
+static void mxc_do_addr_cycle_auto(struct mtd_info *mtd, int column,
+ int page_addr)
+{
+#ifdef CONFIG_MXC_NFC_SP_AUTO
+ if (page_addr != -1 && column != -1) {
+ u32 mask = 0xFFFF;
+ /* the column address */
+ raw_write(column & mask, NFC_FLASH_ADDR0);
+ raw_write((raw_read(NFC_FLASH_ADDR0) |
+ ((page_addr & mask) << 16)), NFC_FLASH_ADDR0);
+ /* the row address */
+ raw_write(((raw_read(NFC_FLASH_ADDR8) & (mask << 16)) |
+ ((page_addr & (mask << 16)) >> 16)),
+ NFC_FLASH_ADDR8);
+ } else if (page_addr != -1) {
+ raw_write(page_addr, NFC_FLASH_ADDR0);
+ }
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3,
+ "AutoMode:the ADDR REGS value is (0x%x, 0x%x)\n",
+ raw_read(NFC_FLASH_ADDR0), raw_read(NFC_FLASH_ADDR8));
+#endif
+}
+
+static void mxc_do_addr_cycle_atomic(struct mtd_info *mtd, int column,
+ int page_addr)
+{
+ struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
+
+ u32 page_mask = info->page_mask;
+
+ if (column != -1) {
+ send_addr(column & 0xFF);
+ if (IS_2K_PAGE_NAND) {
+ /* another col addr cycle for 2k page */
+ send_addr((column >> 8) & 0xF);
+ } else if (IS_4K_PAGE_NAND) {
+ /* another col addr cycle for 4k page */
+ send_addr((column >> 8) & 0x1F);
+ }
+ }
+ if (page_addr != -1) {
+ do {
+ send_addr(page_addr & 0xff);
+ page_mask >>= 8;
+ page_addr >>= 8;
+ } while (page_mask != 0);
+ }
+}
+
+/*
+ * Function to perform the address cycles.
+ */
+static void mxc_nand_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
+{
+ struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
+
+ if (info->auto_mode)
+ mxc_do_addr_cycle_auto(mtd, column, page_addr);
+ else
+ mxc_do_addr_cycle_atomic(mtd, column, page_addr);
+}
+
static void send_cmd_atomic(struct mtd_info *mtd, u16 cmd)
{
/* fill command */
@@ -158,37 +248,42 @@ static void send_cmd_atomic(struct mtd_info *mtd, u16 cmd)
wait_op_done(TROP_US_DELAY);
}
-static void send_cmd_auto(struct mtd_info *mtd, u16 cmd)
+/*
+ * Function to record the ECC corrected/uncorrected errors resulted
+ * after a page read. This NFC detects and corrects upto to 4 symbols
+ * of 9-bits each.
+ */
+static int mxc_nand_ecc_status(struct mtd_info *mtd)
{
-#ifdef CONFIG_MXC_NFC_SP_AUTO
- switch (cmd) {
- case NAND_CMD_READ0:
- case NAND_CMD_READOOB:
- raw_write(NAND_CMD_READ0, REG_NFC_FLASH_CMD);
- break;
- case NAND_CMD_SEQIN:
- case NAND_CMD_ERASE1:
- raw_write(cmd, REG_NFC_FLASH_CMD);
- break;
- case NAND_CMD_PAGEPROG:
- case NAND_CMD_ERASE2:
- case NAND_CMD_READSTART:
- raw_write(raw_read(REG_NFC_FLASH_CMD) | cmd << NFC_CMD_1_SHIFT,
- REG_NFC_FLASH_CMD);
- send_cmd_interleave(mtd, cmd);
- break;
- case NAND_CMD_READID:
- send_atomic_cmd(cmd);
- send_addr(0);
- break;
- case NAND_CMD_RESET:
- send_cmd_interleave(mtd, cmd);
- case NAND_CMD_STATUS:
- break;
- default:
- break;
- }
-#endif
+ u32 ecc_stat, err;
+ int no_subpages = 1;
+ int ret = 0;
+ u8 ecc_bit_mask, err_limit;
+ struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
+
+ ecc_bit_mask = (IS_4BIT_ECC ? 0x7 : 0xf);
+ err_limit = (IS_4BIT_ECC ? 0x4 : 0x8);
+
+ no_subpages = mtd->writesize >> 9;
+
+ no_subpages /= info->num_of_intlv;
+
+ ecc_stat = GET_NFC_ECC_STATUS();
+ do {
+ err = ecc_stat & ecc_bit_mask;
+ if (err > err_limit) {
+ printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
+ return -1;
+ } else {
+ ret += err;
+ }
+ ecc_stat >>= 4;
+ } while (--no_subpages);
+
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "%d Symbol Correctable RS-ECC Error\n", ret);
+
+ return ret;
}
/*!
@@ -199,14 +294,15 @@ static void send_cmd_auto(struct mtd_info *mtd, u16 cmd)
static void send_cmd_interleave(struct mtd_info *mtd, u16 cmd)
{
#ifdef CONFIG_MXC_NFC_SP_AUTO
- u32 i;
- u32 j = num_of_intlv;
+
struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
u32 addr_low = raw_read(NFC_FLASH_ADDR0);
u32 addr_high = raw_read(NFC_FLASH_ADDR8);
u32 page_addr = addr_low >> 16 | addr_high << 16;
- u8 *dbuf = mtd->info.data_buf;
- u8 *obuf = mtd->info.oob_buf;
+ u32 i, j = info->num_of_intlv;
+ u8 *dbuf = info->data_buf;
+ u8 *obuf = info->oob_buf;
u32 dlen = mtd->writesize / j;
u32 olen = mtd->oobsize / j;
@@ -218,9 +314,9 @@ static void send_cmd_interleave(struct mtd_info *mtd, u16 cmd)
else
page_addr *= this->numchips;
- for (i = 0; i < j; i++) {
- if (cmd == NAND_CMD_PAGEPROG) {
-
+ switch (cmd) {
+ case NAND_CMD_PAGEPROG:
+ for (i = 0; i < j; i++) {
/* reset addr cycle */
if (j > 1)
mxc_nand_addr_cycle(mtd, 0, page_addr++);
@@ -238,14 +334,16 @@ static void send_cmd_interleave(struct mtd_info *mtd, u16 cmd)
raw_write(NFC_AUTO_PROG, REG_NFC_OPS);
/* wait auto_prog_done bit set */
- if (i < j - 1) {
- while (!
- (raw_read(REG_NFC_OPS_STAT) & 1 << 30))
- ;
- } else {
- wait_op_done(TROP_US_DELAY);
- }
- } else if (cmd == NAND_CMD_READSTART) {
+ while (!(raw_read(REG_NFC_OPS_STAT) & NFC_OP_DONE))
+ ;
+ }
+
+ wait_op_done(TROP_US_DELAY);
+ while (!(raw_read(REG_NFC_OPS_STAT) & NFC_RB));
+
+ break;
+ case NAND_CMD_READSTART:
+ for (i = 0; i < j; i++) {
/* reset addr cycle */
if (j > 1)
mxc_nand_addr_cycle(mtd, 0, page_addr++);
@@ -265,18 +363,62 @@ static void send_cmd_interleave(struct mtd_info *mtd, u16 cmd)
/* update the value */
dbuf += dlen;
obuf += olen;
- } else if (cmd == NAND_CMD_ERASE2) {
+ }
+ break;
+ case NAND_CMD_ERASE2:
+ for (i = 0; i < j; i++) {
if (!i) {
page_addr = addr_low;
page_addr *= (j > 1 ? j : this->numchips);
}
mxc_nand_addr_cycle(mtd, -1, page_addr++);
+ raw_write(0, REG_NFC_OPS_STAT);
raw_write(NFC_AUTO_ERASE, REG_NFC_OPS);
wait_op_done(TROP_US_DELAY);
- } else if (cmd == NAND_CMD_RESET) {
- NFC_SET_NFC_ACTIVE_CS(i);
- send_atomic_cmd(cmd);
}
+ break;
+ case NAND_CMD_RESET:
+ for (i = 0; i < j; i++) {
+ if (j > 1)
+ NFC_SET_NFC_ACTIVE_CS(i);
+ send_cmd_atomic(mtd, cmd);
+ }
+ break;
+ default:
+ break;
+ }
+#endif
+}
+
+static void send_cmd_auto(struct mtd_info *mtd, u16 cmd)
+{
+#ifdef CONFIG_MXC_NFC_SP_AUTO
+ switch (cmd) {
+ case NAND_CMD_READ0:
+ case NAND_CMD_READOOB:
+ raw_write(NAND_CMD_READ0, REG_NFC_FLASH_CMD);
+ break;
+ case NAND_CMD_SEQIN:
+ case NAND_CMD_ERASE1:
+ raw_write(cmd, REG_NFC_FLASH_CMD);
+ break;
+ case NAND_CMD_PAGEPROG:
+ case NAND_CMD_ERASE2:
+ case NAND_CMD_READSTART:
+ raw_write(raw_read(REG_NFC_FLASH_CMD) | cmd << NFC_CMD_1_SHIFT,
+ REG_NFC_FLASH_CMD);
+ send_cmd_interleave(mtd, cmd);
+ break;
+ case NAND_CMD_READID:
+ send_cmd_atomic(mtd, cmd);
+ send_addr(0);
+ break;
+ case NAND_CMD_RESET:
+ send_cmd_interleave(mtd, cmd);
+ case NAND_CMD_STATUS:
+ break;
+ default:
+ break;
}
#endif
}
@@ -299,32 +441,7 @@ static void send_cmd(struct mtd_info *mtd, u16 cmd)
else
send_cmd_atomic(mtd, cmd);
- MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(0x%x, %d)\n", cmd);
-}
-
-/*!
- * This function sends an address (or partial address) to the
- * NAND device. The address is used to select the source/destination for
- * a NAND command.
- *
- * @param addr address to be written to NFC.
- * @param useirq True if IRQ should be used rather than polling
- */
-static void send_addr(u16 addr)
-{
- MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(0x%x %d)\n", addr);
-
- /* fill address */
- raw_write((addr << NFC_FLASH_ADDR_SHIFT), REG_NFC_FLASH_ADDR);
-
- /* clear status */
- ACK_OPS;
-
- /* send out address */
- raw_write(NFC_ADDR, REG_NFC_OPS);
-
- /* Wait for operation to complete */
- wait_op_done(TROP_US_DELAY);
+ MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(0x%x)\n", cmd);
}
/*!
@@ -420,7 +537,8 @@ static u16 mxc_do_status_auto(struct mtd_info *mtd)
/* set ative cs */
NFC_SET_NFC_ACTIVE_CS(i);
- raw_write(NFC_AUTO_STATE, REG_NFC_OPS);
+ /* clear status */
+ ACK_OPS;
/* FIXME, NFC Auto erase may have
* problem, have to pollingit until
@@ -428,6 +546,12 @@ static u16 mxc_do_status_auto(struct mtd_info *mtd)
* it may get error
*/
do {
+ raw_write(NFC_AUTO_STATE, REG_NFC_OPS);
+ #ifdef CONFIG_MX51
+ /* mx51to2 NFC need wait the op done */
+ if (is_soc_rev(CHIP_REV_2_0) == 0)
+ wait_op_done(TROP_US_DELAY);
+ #endif
status = (raw_read(NFC_CONFIG1) & mask) >> 16;
} while ((status & NAND_STATUS_READY) == 0);
@@ -491,44 +615,6 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
}
/*
- * Function to record the ECC corrected/uncorrected errors resulted
- * after a page read. This NFC detects and corrects upto to 4 symbols
- * of 9-bits each.
- */
-static int mxc_nand_ecc_status(struct mtd_info *mtd)
-{
- u32 ecc_stat, err;
- int no_subpages = 1;
- int ret = 0;
- u8 ecc_bit_mask, err_limit;
- struct nand_chip *this = mtd->priv;
- struct nand_info *info = this->priv;
-
- ecc_bit_mask = (IS_4BIT_ECC ? 0x7 : 0xf);
- err_limit = (IS_4BIT_ECC ? 0x4 : 0x8);
-
- no_subpages = mtd->writesize >> 9;
-
- no_subpages /= info->num_of_intlv;
-
- ecc_stat = GET_NFC_ECC_STATUS();
- do {
- err = ecc_stat & ecc_bit_mask;
- if (err > err_limit) {
- printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
- return -1;
- } else {
- ret += err;
- }
- ecc_stat >>= 4;
- } while (--no_subpages);
-
- MTDDEBUG(MTD_DEBUG_LEVEL3, "%d Symbol Correctable RS-ECC Error\n", ret);
-
- return ret;
-}
-
-/*
* Function to correct the detected errors. This NFC corrects all the errors
* detected. So this function just return 0.
*/
@@ -645,25 +731,6 @@ static u16 mxc_nand_read_word(struct mtd_info *mtd)
}
/*!
- * This function reads byte from the NAND Flash
- *
- * @param mtd MTD structure for the NAND Flash
- *
- * @return data read from the NAND Flash
- */
-static u_char mxc_nand_read_byte16(struct mtd_info *mtd)
-{
- struct nand_chip *this = mtd->priv;
- struct nand_info *info = this->priv;
-
- /* Check for status request */
- if (info->status_req)
- return mxc_nand_get_status(mtd) & 0xFF;
-
- return mxc_nand_read_word(mtd) & 0xFF;
-}
-
-/*!
* This function writes data of length \b len from buffer \b buf to the NAND
* internal RAM buffer's MAIN area 0.
*
@@ -751,72 +818,6 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
}
}
-static void mxc_do_addr_cycle_auto(struct mtd_info *mtd, int column,
- int page_addr)
-{
-#ifdef CONFIG_MXC_NFC_SP_AUTO
- if (page_addr != -1 && column != -1) {
- u32 mask = 0xFFFF;
- /* the column address */
- raw_write(column & mask, NFC_FLASH_ADDR0);
- raw_write((raw_read(NFC_FLASH_ADDR0) |
- ((page_addr & mask) << 16)), NFC_FLASH_ADDR0);
- /* the row address */
- raw_write(((raw_read(NFC_FLASH_ADDR8) & (mask << 16)) |
- ((page_addr & (mask << 16)) >> 16)),
- NFC_FLASH_ADDR8);
- } else if (page_addr != -1) {
- raw_write(page_addr, NFC_FLASH_ADDR0);
- }
-
- MTDDEBUG(MTD_DEBUG_LEVEL3,
- "AutoMode:the ADDR REGS value is (0x%x, 0x%x)\n",
- raw_read(NFC_FLASH_ADDR0), raw_read(NFC_FLASH_ADDR8));
-#endif
-}
-
-static void mxc_do_addr_cycle_atomic(struct mtd_info *mtd, int column,
- int page_addr)
-{
- struct nand_chip *this = mtd->priv;
- struct nand_info *info = this->priv;
-
- u32 page_mask = info->page_mask;
-
- if (column != -1) {
- send_addr(column & 0xFF);
- if (IS_2K_PAGE_NAND) {
- /* another col addr cycle for 2k page */
- send_addr((column >> 8) & 0xF);
- } else if (IS_4K_PAGE_NAND) {
- /* another col addr cycle for 4k page */
- send_addr((column >> 8) & 0x1F);
- }
- }
- if (page_addr != -1) {
- do {
- send_addr(page_addr & 0xff);
- page_mask >>= 8;
- page_addr >>= 8;
- } while (page_mask != 0);
- }
-}
-
-
-/*
- * Function to perform the address cycles.
- */
-static void mxc_nand_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
-{
- struct nand_chip *this = mtd->priv;
- struct nand_info *info = this->priv;
-
- if (info->auto_mode)
- mxc_do_addr_cycle_auto(mtd, column, page_addr);
- else
- mxc_do_addr_cycle_atomic(mtd, column, page_addr);
-}
-
/*!
* This function is used by the upper layer to write command to NAND Flash for
* different operations to be carried out on NAND Flash
@@ -933,6 +934,50 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
}
}
+static int mxc_nand_read_oob(struct mtd_info *mtd,
+ struct nand_chip *chip, int page, int sndcmd)
+{
+ struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
+
+ if (sndcmd) {
+
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+ sndcmd = 0;
+ }
+
+ memcpy(chip->oob_poi, info->oob_buf, mtd->oobsize);
+
+ return sndcmd;
+}
+
+static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf)
+{
+ struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
+
+#ifndef CONFIG_MXC_NFC_SP_AUTO
+ mxc_nand_ecc_status(mtd);
+#endif
+
+ memcpy(buf, info->data_buf, mtd->writesize);
+ memcpy(chip->oob_poi, info->oob_buf, mtd->oobsize);
+
+ return 0;
+}
+
+static void mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ struct nand_chip *this = mtd->priv;
+ struct nand_info *info = this->priv;
+
+ memcpy(info->data_buf, buf, mtd->writesize);
+ memcpy(info->oob_buf, chip->oob_poi, mtd->oobsize);
+
+}
+
/* Define some generic bad / good block scan pattern which are used
* while scanning a device for factory marked good / bad blocks. */
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -1014,7 +1059,7 @@ static int mxc_nand_scan_bbt(struct mtd_info *mtd)
this->bbt_erase_shift =
this->phys_erase_shift = ffs(mtd->erasesize) - 1;
this->chip_shift = ffs(this->chipsize) - 1;
- /*this->oob_poi = this->buffers->databuf + mtd->writesize;*/
+ this->oob_poi = this->buffers->databuf + mtd->writesize;
}
/* propagate ecc.layout to mtd_info */
@@ -1055,6 +1100,9 @@ static void mxc_nfc_init(void)
/* Unlock Block Command for given address range */
raw_write(NFC_SET_WPC(NFC_WPC_UNLOCK), REG_NFC_WPC);
+
+ /* Enable hw ecc */
+ raw_write((raw_read(REG_NFC_ECC_EN) | NFC_ECC_EN), REG_NFC_ECC_EN);
}
static int mxc_alloc_buf(struct nand_info *info)
@@ -1080,12 +1128,6 @@ static int mxc_alloc_buf(struct nand_info *info)
return err;
}
-static void mxc_free_buf(struct nand_info *info)
-{
- kfree(info->data_buf);
- kfree(info->oob_buf);
-}
-
/*!
* This function is called during the driver binding process.
*
@@ -1132,13 +1174,16 @@ int board_nand_init(struct nand_chip *nand)
this->read_buf = mxc_nand_read_buf;
this->verify_buf = mxc_nand_verify_buf;
this->scan_bbt = mxc_nand_scan_bbt;
+ this->ecc.read_page = mxc_nand_read_page;
+ this->ecc.write_page = mxc_nand_write_page;
+ this->ecc.read_oob = mxc_nand_read_oob;
this->ecc.calculate = mxc_nand_calculate_ecc;
this->ecc.correct = mxc_nand_correct_data;
this->ecc.hwctl = mxc_nand_enable_hwecc;
+ this->ecc.layout = &nand_hw_eccoob_512;
this->ecc.mode = NAND_ECC_HW;
this->ecc.bytes = 9;
this->ecc.size = 512;
return 0;
-
}
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 29c0d2d..0478740 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2529,7 +2529,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
mtd->writesize = 1024 << (extid & 0x3);
extid >>= 2;
/* Calc oobsize */
- mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
+ mtd->oobsize = (*maf_id == 0x2c && dev_id == 0xd5) ?
+ 218 : (8 << (extid & 0x01)) * (mtd->writesize >> 9);
extid >>= 2;
/* Calc blocksize. Blocksize is multiples of 64KiB */
mtd->erasesize = (64 * 1024) << (extid & 0x03);
@@ -2866,10 +2867,9 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->ecclayout = chip->ecc.layout;
/* Check, if we should skip the bad block table scan */
- if (chip->options & NAND_SKIP_BBTSCAN)
- chip->options |= NAND_BBT_SCANNED;
+ chip->options |= NAND_BBT_SCANNED;
- return 0;
+ return chip->scan_bbt(mtd);
}
/* module_text_address() isn't exported, and it's mostly a pointless
diff --git a/include/asm-arm/arch-mx35/mxc_nand.h b/include/asm-arm/arch-mx35/mxc_nand.h
index bc04c09..047b232 100644
--- a/include/asm-arm/arch-mx35/mxc_nand.h
+++ b/include/asm-arm/arch-mx35/mxc_nand.h
@@ -33,7 +33,6 @@
#define NAND_PAGESIZE_2KB 2048
#define NAND_PAGESIZE_4KB 4096
-#define NAND_MAX_PAGESIZE 4096
/*
* Addresses for NFC registers
diff --git a/include/asm-arm/arch-mx51/mx51.h b/include/asm-arm/arch-mx51/mx51.h
index d9d8ef7..566251b 100644
--- a/include/asm-arm/arch-mx51/mx51.h
+++ b/include/asm-arm/arch-mx51/mx51.h
@@ -406,14 +406,6 @@ MXC_IPG_PERCLK,
MXC_UART_CLK,
};
-/*!
- * NFMS bit in RCSR register for pagesize of nandflash
- */
-#define NFMS (*((volatile u32 *)(CCM_BASE_ADDR+0x18)))
-#define NFMS_BIT 8
-#define NFMS_NF_DWIDTH 14
-#define NFMS_NF_PG_SZ 8
-
extern unsigned int mxc_get_clock(enum mxc_clock clk);
extern unsigned int get_board_rev(void);
extern int is_soc_rev(int rev);
diff --git a/include/asm-arm/arch-mx51/mxc_nand.h b/include/asm-arm/arch-mx51/mxc_nand.h
index aad93d1..539d0fd 100644
--- a/include/asm-arm/arch-mx51/mxc_nand.h
+++ b/include/asm-arm/arch-mx51/mxc_nand.h
@@ -12,7 +12,7 @@
*/
/*!
- * @file mxc_nd2.h
+ * @file mxc_nand.h
*
* @brief This file contains the NAND Flash Controller register information.
*
@@ -25,99 +25,100 @@
#include <asm/arch/mx51.h>
-#define IS_2K_PAGE_NAND ((mtd->oobblock / info->num_of_intlv) \
+#define IS_2K_PAGE_NAND ((mtd->writesize / info->num_of_intlv) \
== NAND_PAGESIZE_2KB)
-#define IS_4K_PAGE_NAND ((mtd->oobblock / info->num_of_intlv) \
+#define IS_4K_PAGE_NAND ((mtd->writesize / info->num_of_intlv) \
== NAND_PAGESIZE_4KB)
-#define IS_LARGE_PAGE_NAND ((mtd->oobblock / info->num_of_intlv) > 512)
+#define IS_LARGE_PAGE_NAND ((mtd->writesize / info->num_of_intlv) > 512)
+
+#define GET_NAND_OOB_SIZE (mtd->oobsize / info->num_of_intlv)
#define NAND_PAGESIZE_2KB 2048
#define NAND_PAGESIZE_4KB 4096
-#define NAND_MAX_PAGESIZE 4096
-/*
- * Addresses for NFC registers
- */
-#define NFC_REG_BASE (NFC_BASE_ADDR + 0x1000)
-#define NFC_BUF_ADDR (NFC_REG_BASE + 0xE04)
-#define NFC_FLASH_ADDR (NFC_REG_BASE + 0xE06)
-#define NFC_FLASH_CMD (NFC_REG_BASE + 0xE08)
-#define NFC_CONFIG (NFC_REG_BASE + 0xE0A)
-#define NFC_ECC_STATUS_RESULT (NFC_REG_BASE + 0xE0C)
-#define NFC_SPAS (NFC_REG_BASE + 0xE10)
-#define NFC_WRPROT (NFC_REG_BASE + 0xE12)
-#define NFC_UNLOCKSTART_BLKADDR (NFC_REG_BASE + 0xE20)
-#define NFC_UNLOCKEND_BLKADDR (NFC_REG_BASE + 0xE22)
-#define NFC_CONFIG1 (NFC_REG_BASE + 0xE1A)
-#define NFC_CONFIG2 (NFC_REG_BASE + 0xE1C)
+#define NFC_AXI_BASE_ADDR NFC_BASE_ADDR_AXI
+#define NFC_IP_BASE_ADDR NFC_BASE_ADDR
+#define MXC_INT_NANDFC MXC_INT_NFC
+#define CONFIG_MXC_NFC_SP_AUTO
+#define NFC_FLASH_CMD (NFC_AXI_BASE_ADDR + 0x1E00)
+#define NFC_FLASH_ADDR0 (NFC_AXI_BASE_ADDR + 0x1E04)
+#define NFC_FLASH_ADDR8 (NFC_AXI_BASE_ADDR + 0x1E24)
+#define NFC_CONFIG1 (NFC_AXI_BASE_ADDR + 0x1E34)
+#define NFC_ECC_STATUS_RESULT (NFC_AXI_BASE_ADDR + 0x1E38)
+#define NFC_ECC_STATUS_SUM (NFC_AXI_BASE_ADDR + 0x1E3C)
+#define LAUNCH_NFC (NFC_AXI_BASE_ADDR + 0x1E40)
+#define NFC_WRPROT (NFC_IP_BASE_ADDR + 0x00)
+#define NFC_WRPROT_UNLOCK_BLK_ADD0 (NFC_IP_BASE_ADDR + 0x04)
+#define NFC_CONFIG2 (NFC_IP_BASE_ADDR + 0x24)
+#define NFC_CONFIG3 (NFC_IP_BASE_ADDR + 0x28)
+#define NFC_IPC (NFC_IP_BASE_ADDR + 0x2C)
/*!
* Addresses for NFC RAM BUFFER Main area 0
*/
-#define MAIN_AREA0 (u16 *)(NFC_BASE_ADDR + 0x000)
-#define MAIN_AREA1 (u16 *)(NFC_BASE_ADDR + 0x200)
+#define MAIN_AREA0 ((u16 *)(NFC_AXI_BASE_ADDR + 0x000))
+#define MAIN_AREA1 ((u16 *)(NFC_AXI_BASE_ADDR + 0x200))
/*!
* Addresses for NFC SPARE BUFFER Spare area 0
*/
-#define SPARE_AREA0 (u16 *)(NFC_BASE_ADDR + 0x1000)
+#define SPARE_AREA0 ((u16 *)(NFC_AXI_BASE_ADDR + 0x1000))
#define SPARE_LEN 64
#define SPARE_COUNT 8
-#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT)
+#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT)
+#define NFC_SPAS_WIDTH 8
+#define NFC_SPAS_SHIFT 16
-#define SPAS_SHIFT (0)
-#define SPAS_MASK (0xFF00)
-#define IS_4BIT_ECC \
- ((raw_read(REG_NFC_ECC_MODE) & NFC_ECC_MODE_4) >> 0)
+#define IS_4BIT_ECC \
+( \
+ is_soc_rev(CHIP_REV_2_0) == 0 ? \
+ !((raw_read(NFC_CONFIG2) & NFC_ECC_MODE_4) >> 6) : \
+ ((raw_read(NFC_CONFIG2) & NFC_ECC_MODE_4) >> 6) \
+)
#define NFC_SET_SPAS(v) \
- raw_write(((raw_read(REG_NFC_SPAS) & SPAS_MASK) | \
- ((v<<SPAS_SHIFT))), \
- REG_NFC_SPAS)
+ raw_write((((raw_read(NFC_CONFIG2) & \
+ NFC_FIELD_RESET(NFC_SPAS_WIDTH, NFC_SPAS_SHIFT)) | ((v) << 16))), \
+ NFC_CONFIG2)
-#define NFC_SET_ECC_MODE(v) \
+#define NFC_SET_ECC_MODE(v) \
do { \
- if ((v) == NFC_SPAS_218) { \
- raw_write((raw_read(REG_NFC_ECC_MODE) & \
- NFC_ECC_MODE_8), \
- REG_NFC_ECC_MODE); \
+ if (is_soc_rev(CHIP_REV_2_0) == 0) { \
+ if ((v) == NFC_SPAS_218 || (v) == NFC_SPAS_112) \
+ raw_write(((raw_read(NFC_CONFIG2) & \
+ NFC_ECC_MODE_MASK) | \
+ NFC_ECC_MODE_4), NFC_CONFIG2); \
+ else \
+ raw_write(((raw_read(NFC_CONFIG2) & \
+ NFC_ECC_MODE_MASK) & \
+ NFC_ECC_MODE_8), NFC_CONFIG2); \
} else { \
- raw_write((raw_read(REG_NFC_ECC_MODE) | \
- NFC_ECC_MODE_4), \
- REG_NFC_ECC_MODE); \
- } \
-} while (0)
-
-#define GET_ECC_STATUS() \
- __raw_readl(REG_NFC_ECC_STATUS_RESULT);
-
-#define NFC_SET_NFMS(v) \
-do { \
- (NFMS |= (v)); \
- if (((v) & (1 << NFMS_NF_PG_SZ))) { \
- if (IS_2K_PAGE_NAND) { \
- NFC_SET_SPAS(NFC_SPAS_64); \
- } else if (IS_4K_PAGE_NAND) { \
- NFC_SET_SPAS(NFC_SPAS_128); \
- } else { \
- NFC_SET_SPAS(NFC_SPAS_16); \
- } \
- NFC_SET_ECC_MODE(NFC_SPAS_128); \
+ if ((v) == NFC_SPAS_218 || (v) == NFC_SPAS_112) \
+ raw_write(((raw_read(NFC_CONFIG2) & \
+ NFC_ECC_MODE_MASK) & \
+ NFC_ECC_MODE_8), NFC_CONFIG2); \
+ else \
+ raw_write(((raw_read(NFC_CONFIG2) & \
+ NFC_ECC_MODE_MASK) | \
+ NFC_ECC_MODE_4), NFC_CONFIG2); \
} \
} while (0)
+#define WRITE_NFC_IP_REG(val, reg) \
+ do { \
+ raw_write(NFC_IPC_CREQ, NFC_IPC); \
+ while (!((raw_read(NFC_IPC) & NFC_IPC_ACK)>>1)) \
+ ; \
+ raw_write(val, reg); \
+ raw_write(0, NFC_IPC); \
+ } while (0)
-#define WRITE_NFC_IP_REG(val, reg) \
- raw_write((raw_read(REG_NFC_OPS_STAT) & ~NFC_OPS_STAT), \
- REG_NFC_OPS_STAT)
-
-#define GET_NFC_ECC_STATUS() \
- raw_read(REG_NFC_ECC_STATUS_RESULT);
+#define GET_NFC_ECC_STATUS() raw_read(REG_NFC_ECC_STATUS_RESULT);
/*!
- * Set INT to 0, Set 1 to specific operation bit, rest to 0 in LAUNCH_NFC
- * Register for Specific operation
+ * Set 1 to specific operation bit, rest to 0 in LAUNCH_NFC Register for
+ * Specific operation
*/
#define NFC_CMD 0x1
#define NFC_ADDR 0x2
@@ -125,74 +126,241 @@ do { \
#define NFC_OUTPUT 0x8
#define NFC_ID 0x10
#define NFC_STATUS 0x20
+#define NFC_AUTO_PROG 0x40
+#define NFC_AUTO_READ 0x80
+#define NFC_AUTO_ERASE 0x200
+#define NFC_COPY_BACK_0 0x400
+#define NFC_COPY_BACK_1 0x800
+#define NFC_AUTO_STATE 0x1000
+
+/* Bit Definitions for NFC_IPC*/
+#define NFC_OPS_STAT (1 << 31)
+#define NFC_OP_DONE (1 << 30)
+#define NFC_RB (1 << 28)
+#define NFC_PS_WIDTH 2
+#define NFC_PS_SHIFT 0
+#define NFC_PS_512 0
+#define NFC_PS_2K 1
+#define NFC_PS_4K 2
+
+
+#define NFC_ONE_CYCLE (1 << 2)
+#define NFC_INT_MSK (1 << 15)
+#define NFC_AUTO_PROG_DONE_MSK (1 << 14)
+#define NFC_NUM_ADDR_PHASE1_WIDTH 2
+#define NFC_NUM_ADDR_PHASE1_SHIFT 12
+#define NFC_NUM_ADDR_PHASE0_WIDTH 1
+#define NFC_NUM_ADDR_PHASE0_SHIFT 5
+#define NFC_ONE_LESS_PHASE1 0
+#define NFC_TWO_LESS_PHASE1 1
+#define NFC_FLASH_ADDR_SHIFT 0
+#define NFC_UNLOCK_END_ADDR_SHIFT 16
+
+/* Bit definition for NFC_CONFIGRATION_1 */
+#define NFC_SP_EN (1 << 0)
+#define NFC_CE (1 << 1)
+#define NFC_RST (1 << 2)
+#define NFC_ECC_EN (1 << 3)
-/* Bit Definitions */
-#define NFC_OPS_STAT (1 << 15)
-#define NFC_SP_EN (1 << 2)
-#define NFC_ECC_EN (1 << 3)
-#define NFC_INT_MSK (1 << 4)
-#define NFC_BIG (1 << 5)
-#define NFC_RST (1 << 6)
-#define NFC_CE (1 << 7)
-#define NFC_ONE_CYCLE (1 << 8)
-#define NFC_BLS_LOCKED 0
-#define NFC_BLS_LOCKED_DEFAULT 1
-#define NFC_BLS_UNLCOKED 2
+#define NFC_FIELD_RESET(width, shift) (~(((1 << (width)) - 1) << (shift)))
+
+#define NFC_RBA_SHIFT 4
+#define NFC_RBA_WIDTH 3
+
+#define NFC_ITERATION_SHIFT 8
+#define NFC_ITERATION_WIDTH 4
+#define NFC_ACTIVE_CS_SHIFT 12
+#define NFC_ACTIVE_CS_WIDTH 3
+/* bit definition for CONFIGRATION3 */
+#define NFC_NO_SDMA (1 << 20)
+#define NFC_FMP_SHIFT 16
+#define NFC_FMP_WIDTH 4
+#define NFC_RBB_MODE (1 << 15)
+#define NFC_NUM_OF_DEVICES_SHIFT 12
+#define NFC_NUM_OF_DEVICES_WIDTH 4
+#define NFC_DMA_MODE_SHIFT 11
+#define NFC_DMA_MODE_WIDTH 1
+#define NFC_SBB_SHIFT 8
+#define NFC_SBB_WIDTH 3
+#define NFC_BIG (1 << 7)
+#define NFC_SB2R_SHIFT 4
+#define NFC_SB2R_WIDTH 3
+#define NFC_FW_SHIFT 3
+#define NFC_FW_WIDTH 1
+#define NFC_TOO (1 << 2)
+#define NFC_ADD_OP_SHIFT 0
+#define NFC_ADD_OP_WIDTH 2
+#define NFC_FW_8 1
+#define NFC_FW_16 0
+#define NFC_ST_CMD_SHITF 24
+#define NFC_ST_CMD_WIDTH 8
+
+#define NFC_PPB_32 (0 << 7)
+#define NFC_PPB_64 (1 << 7)
+#define NFC_PPB_128 (2 << 7)
+#define NFC_PPB_256 (3 << 7)
+#define NFC_PPB_RESET (~(3 << 7))
+
+#define NFC_BLS_LOCKED (0 << 16)
+#define NFC_BLS_LOCKED_DEFAULT (1 << 16)
+#define NFC_BLS_UNLCOKED (2 << 16)
+#define NFC_BLS_RESET (~(3 << 16))
#define NFC_WPC_LOCK_TIGHT 1
#define NFC_WPC_LOCK (1 << 1)
#define NFC_WPC_UNLOCK (1 << 2)
-#define NFC_FLASH_ADDR_SHIFT 0
-#define NFC_UNLOCK_END_ADDR_SHIFT 0
-
-#define NFC_ECC_MODE_4 (1<<0)
-#define NFC_ECC_MODE_8 (~(1<<0))
-#define NFC_SPAS_16 8
-#define NFC_SPAS_64 32
-#define NFC_SPAS_128 64
-#define NFC_SPAS_218 109
-
-/* NFC Register Mapping */
-#define REG_NFC_OPS_STAT NFC_CONFIG2
-#define REG_NFC_INTRRUPT NFC_CONFIG1
-#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR
+#define NFC_WPC_RESET (~(7))
+#define NFC_ECC_MODE_4 (1 << 6)
+#define NFC_ECC_MODE_8 (~(1 << 6))
+#define NFC_ECC_MODE_MASK (~(1 << 6))
+#define NFC_SPAS_16 8
+#define NFC_SPAS_64 32
+#define NFC_SPAS_128 64
+#define NFC_SPAS_112 56
+#define NFC_SPAS_218 109
+#define NFC_IPC_CREQ (1 << 0)
+#define NFC_IPC_ACK (1 << 1)
+
+#define REG_NFC_OPS_STAT NFC_IPC
+#define REG_NFC_INTRRUPT NFC_CONFIG2
+#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR0
#define REG_NFC_FLASH_CMD NFC_FLASH_CMD
-#define REG_NFC_OPS NFC_CONFIG2
-#define REG_NFC_SET_RBA NFC_BUF_ADDR
-#define REG_NFC_ECC_EN NFC_CONFIG1
-#define REG_NFC_ECC_STATUS_RESULT NFC_ECC_STATUS_RESULT
+#define REG_NFC_OPS LAUNCH_NFC
+#define REG_NFC_SET_RBA NFC_CONFIG1
+#define REG_NFC_RB NFC_IPC
+#define REG_NFC_ECC_EN NFC_CONFIG2
+#define REG_NFC_ECC_STATUS_RESULT NFC_ECC_STATUS_RESULT
#define REG_NFC_CE NFC_CONFIG1
+#define REG_NFC_RST NFC_CONFIG1
+#define REG_NFC_PPB NFC_CONFIG2
#define REG_NFC_SP_EN NFC_CONFIG1
-#define REG_NFC_BLS NFC_CONFIG
+#define REG_NFC_BLS NFC_WRPROT
+#define REG_UNLOCK_BLK_ADD0 NFC_WRPROT_UNLOCK_BLK_ADD0
+#define REG_UNLOCK_BLK_ADD1 NFC_WRPROT_UNLOCK_BLK_ADD1
+#define REG_UNLOCK_BLK_ADD2 NFC_WRPROT_UNLOCK_BLK_ADD2
+#define REG_UNLOCK_BLK_ADD3 NFC_WRPROT_UNLOCK_BLK_ADD3
#define REG_NFC_WPC NFC_WRPROT
-#define REG_START_BLKADDR NFC_UNLOCKSTART_BLKADDR
-#define REG_END_BLKADDR NFC_UNLOCKEND_BLKADDR
-#define REG_NFC_RST NFC_CONFIG1
-#define REG_NFC_ECC_MODE NFC_CONFIG1
-#define REG_NFC_SPAS NFC_SPAS
+#define REG_NFC_ONE_CYCLE NFC_CONFIG2
+
+/* NFC V3 Specific MACRO functions definitions */
+#define raw_write(v, a) __raw_writel(v, a)
+#define raw_read(a) __raw_readl(a)
+
+/* Explcit ack ops status (if any), before issue of any command */
+#define ACK_OPS \
+ raw_write((raw_read(REG_NFC_OPS_STAT) & ~NFC_OPS_STAT), \
+ REG_NFC_OPS_STAT);
+
+/* Set RBA buffer id*/
+#define NFC_SET_RBA(val) \
+ raw_write((raw_read(REG_NFC_SET_RBA) & \
+ (NFC_FIELD_RESET(NFC_RBA_WIDTH, NFC_RBA_SHIFT))) | \
+ ((val) << NFC_RBA_SHIFT), REG_NFC_SET_RBA);
+
+#define NFC_SET_PS(val) \
+ raw_write((raw_read(NFC_CONFIG2) & \
+ (NFC_FIELD_RESET(NFC_PS_WIDTH, NFC_PS_SHIFT))) | \
+ ((val) << NFC_PS_SHIFT), NFC_CONFIG2);
+
+#define UNLOCK_ADDR(start_addr, end_addr) \
+{ \
+ int i = 0; \
+ for (; i < NAND_MAX_CHIPS; i++) \
+ raw_write(start_addr | \
+ (end_addr << NFC_UNLOCK_END_ADDR_SHIFT), \
+ REG_UNLOCK_BLK_ADD0 + (i << 2)); \
+}
+#define NFC_SET_NFC_ACTIVE_CS(val) \
+ raw_write((raw_read(NFC_CONFIG1) & \
+ (NFC_FIELD_RESET(NFC_ACTIVE_CS_WIDTH, NFC_ACTIVE_CS_SHIFT))) | \
+ ((val) << NFC_ACTIVE_CS_SHIFT), NFC_CONFIG1);
-/* NFC V1/V2 Specific MACRO functions definitions */
+#define NFC_GET_MAXCHIP_SP() 8
-#define raw_write(v, a) __raw_writew(v, a)
-#define raw_read(a) __raw_readw(a)
+#define NFC_SET_BLS(val) ((raw_read(REG_NFC_BLS) & NFC_BLS_RESET) | val)
+#define NFC_SET_WPC(val) ((raw_read(REG_NFC_WPC) & NFC_WPC_RESET) | val)
+#define CHECK_NFC_RB (raw_read(REG_NFC_RB) & NFC_RB)
-#define NFC_SET_BLS(val) val
+#define NFC_SET_NFC_NUM_ADDR_PHASE1(val) \
+ raw_write((raw_read(NFC_CONFIG2) & \
+ (NFC_FIELD_RESET(NFC_NUM_ADDR_PHASE1_WIDTH, \
+ NFC_NUM_ADDR_PHASE1_SHIFT))) | \
+ ((val) << NFC_NUM_ADDR_PHASE1_SHIFT), NFC_CONFIG2);
-#define UNLOCK_ADDR(start_addr, end_addr) \
+#define NFC_SET_NFC_NUM_ADDR_PHASE0(val) \
+ raw_write((raw_read(NFC_CONFIG2) & \
+ (NFC_FIELD_RESET(NFC_NUM_ADDR_PHASE0_WIDTH, \
+ NFC_NUM_ADDR_PHASE0_SHIFT))) | \
+ ((val) << NFC_NUM_ADDR_PHASE0_SHIFT), NFC_CONFIG2);
+
+#define NFC_SET_NFC_ITERATION(val) \
+ raw_write((raw_read(NFC_CONFIG1) & \
+ (NFC_FIELD_RESET(NFC_ITERATION_WIDTH, NFC_ITERATION_SHIFT))) | \
+ ((val) << NFC_ITERATION_SHIFT), NFC_CONFIG1);
+
+#define NFC_SET_FW(val) \
+ raw_write((raw_read(NFC_CONFIG3) & \
+ (NFC_FIELD_RESET(NFC_FW_WIDTH, NFC_FW_SHIFT))) | \
+ ((val) << NFC_FW_SHIFT), NFC_CONFIG3);
+
+#define NFC_SET_NUM_OF_DEVICE(val) \
+ raw_write((raw_read(NFC_CONFIG3) & \
+ (NFC_FIELD_RESET(NFC_NUM_OF_DEVICES_WIDTH, \
+ NFC_NUM_OF_DEVICES_SHIFT))) | \
+ ((val) << NFC_NUM_OF_DEVICES_SHIFT), NFC_CONFIG3);
+
+#define NFC_SET_ADD_OP_MODE(val) \
+ raw_write((raw_read(NFC_CONFIG3) & \
+ (NFC_FIELD_RESET(NFC_ADD_OP_WIDTH, NFC_ADD_OP_SHIFT))) | \
+ ((val) << NFC_ADD_OP_SHIFT), NFC_CONFIG3);
+
+#define NFC_SET_ADD_CS_MODE(val) \
{ \
- raw_write(start_addr, REG_START_BLKADDR); \
- raw_write(end_addr, REG_END_BLKADDR); \
+ NFC_SET_ADD_OP_MODE(val); \
+ NFC_SET_NUM_OF_DEVICE(this->numchips - 1); \
}
-#define NFC_SET_NFC_ACTIVE_CS(val)
-#define NFC_SET_WPC(val) val
+#define NFC_SET_ST_CMD(val) \
+ raw_write((raw_read(NFC_CONFIG2) & \
+ (NFC_FIELD_RESET(NFC_ST_CMD_WIDTH, \
+ NFC_ST_CMD_SHITF))) | \
+ ((val) << NFC_ST_CMD_SHITF), NFC_CONFIG2);
-/* NULL Definitions */
-#define ACK_OPS
-#define NFC_SET_RBA(val) raw_write(val, REG_NFC_SET_RBA);
+#define NFMS_NF_DWIDTH 0
+#define NFMS_NF_PG_SZ 1
+#define NFC_CMD_1_SHIFT 8
+
+#define NUM_OF_ADDR_CYCLE ((ffs(~(info->page_mask)) - 1) >> 3)
+
+/*should set the fw,ps,spas,ppb*/
+#define NFC_SET_NFMS(v) \
+do { \
+ NFC_SET_FW(NFC_FW_8); \
+ if (((v) & (1 << NFMS_NF_DWIDTH))) \
+ NFC_SET_FW(NFC_FW_16); \
+ if (((v) & (1 << NFMS_NF_PG_SZ))) { \
+ if (IS_2K_PAGE_NAND) { \
+ NFC_SET_PS(NFC_PS_2K); \
+ NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE); \
+ NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_TWO_LESS_PHASE1); \
+ } else if (IS_4K_PAGE_NAND) { \
+ NFC_SET_PS(NFC_PS_4K); \
+ NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE); \
+ NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_TWO_LESS_PHASE1); \
+ } else { \
+ NFC_SET_PS(NFC_PS_512); \
+ NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE - 1); \
+ NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_ONE_LESS_PHASE1); \
+ } \
+ NFC_SET_ADD_CS_MODE(1); \
+ NFC_SET_SPAS(GET_NAND_OOB_SIZE >> 1); \
+ NFC_SET_ECC_MODE(GET_NAND_OOB_SIZE >> 1); \
+ NFC_SET_ST_CMD(0x70); \
+ raw_write(raw_read(NFC_CONFIG3) | 1 << 20, NFC_CONFIG3); \
+ } \
+} while (0)
#define READ_PAGE() send_read_page(0)
#define PROG_PAGE() send_prog_page(0)
-#define CHECK_NFC_RB 1
#endif /* __MXC_NAND_H__ */
diff --git a/include/configs/mx51_3stack.h b/include/configs/mx51_3stack.h
index ae91982..7446c39 100644
--- a/include/configs/mx51_3stack.h
+++ b/include/configs/mx51_3stack.h
@@ -58,7 +58,7 @@
/*
* Size of malloc() pool
*/
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 512 * 1024)
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
/* size in bytes reserved for initial data */
#define CONFIG_SYS_GBL_DATA_SIZE 128
@@ -83,7 +83,8 @@
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
/* Enable below configure when supporting nand */
-/* #define CONFIG_CMD_NAND */
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_ENV
#undef CONFIG_CMD_IMLS
#define CONFIG_BOOTDELAY 3
@@ -172,16 +173,15 @@
/*-----------------------------------------------------------------------
* NAND FLASH driver setup
*/
-#define NAND_MAX_CHIPS 1
+#define NAND_MAX_CHIPS 8
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x40000000
/* Monitor at beginning of flash */
-#define CONFIG_ENV_IS_NOWHERE 1
-#define CONFIG_ENV_SECT_SIZE (128 * 1024)
+#define CONFIG_ENV_IS_IN_NAND 1
+#define CONFIG_ENV_SECT_SIZE (1024 * 1024)
#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
-/* #define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_ENV_SECT_SIZE) */
-#define CONFIG_ENV_OFFSET 0x40000
+#define CONFIG_ENV_OFFSET 0x100000
/*
* JFFS2 partitions
*/
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 3e0044b..7d5196a 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -50,8 +50,8 @@ extern void nand_wait_ready(struct mtd_info *mtd);
* is supported now. If you add a chip with bigger oobsize/page
* adjust this accordingly.
*/
-#define NAND_MAX_OOBSIZE 218
-#define NAND_MAX_PAGESIZE 4096
+#define NAND_MAX_OOBSIZE (218 * CONFIG_SYS_NAND_MAX_CHIPS)
+#define NAND_MAX_PAGESIZE (4096 * CONFIG_SYS_NAND_MAX_CHIPS)
/*
* Constants for hardware specific CLE/ALE/NCE function