diff options
author | Tom Rini <trini@konsulko.com> | 2015-03-31 17:17:06 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-03-31 17:17:06 -0400 |
commit | 482cbd553daf3d9cd21e564702bac84a6bd43f2f (patch) | |
tree | ba0c09e8301e7fae94072408e4d6f4254b2d238f /drivers | |
parent | 9da7e3daf31d7c0c8478a57544bfdd6245e53ff3 (diff) | |
parent | 55765b1842e7dcf22efa8d973c7d1b7498dd99fa (diff) | |
download | u-boot-imx-482cbd553daf3d9cd21e564702bac84a6bd43f2f.zip u-boot-imx-482cbd553daf3d9cd21e564702bac84a6bd43f2f.tar.gz u-boot-imx-482cbd553daf3d9cd21e564702bac84a6bd43f2f.tar.bz2 |
Merge git://git.denx.de/u-boot-nand-flash
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dfu/dfu_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/davinci_nand.c | 12 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 38 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 38 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_upm.c | 18 | ||||
-rw-r--r-- | drivers/mtd/nand/mpc5121_nfc.c | 26 | ||||
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 33 | ||||
-rw-r--r-- | drivers/mtd/nand/mxs_nand.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 65 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_util.c | 156 | ||||
-rw-r--r-- | drivers/mtd/nand/ndfc.c | 18 | ||||
-rw-r--r-- | drivers/mtd/nand/vf610_nfc.c | 28 |
12 files changed, 120 insertions, 318 deletions
diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c index f9ee189..a975492 100644 --- a/drivers/dfu/dfu_nand.c +++ b/drivers/dfu/dfu_nand.c @@ -64,7 +64,7 @@ static int nand_block_op(enum dfu_op op, struct dfu_entity *dfu, return ret; /* then write */ ret = nand_write_skip_bad(nand, start, &count, &actual, - lim, buf, 0); + lim, buf, WITH_WR_VERIFY); } if (ret != 0) { diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 41689b5..a397074 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -405,18 +405,6 @@ static int nand_davinci_write_page(struct mtd_info *mtd, struct nand_chip *chip, goto err; } -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE - /* Send command to read back the data */ - chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); - - if (chip->verify_buf(mtd, buf, mtd->writesize)) { - ret = -EIO; - goto err; - } - - /* Make sure the next page prog is preceded by a status read */ - chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); -#endif err: /* restore ECC layout */ if (page < CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE) { diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 3372b64..e85832d 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -561,41 +561,6 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) len, avail); } -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -/* - * Verify buffer against the FCM Controller Data Buffer - */ -static int fsl_elbc_verify_buf(struct mtd_info *mtd, - const u_char *buf, int len) -{ - struct nand_chip *chip = mtd->priv; - struct fsl_elbc_mtd *priv = chip->priv; - struct fsl_elbc_ctrl *ctrl = priv->ctrl; - int i; - - if (len < 0) { - printf("write_buf of %d bytes", len); - return -EINVAL; - } - - if ((unsigned int)len > ctrl->read_bytes - ctrl->index) { - printf("verify_buf beyond end of buffer " - "(%d requested, %u available)\n", - len, ctrl->read_bytes - ctrl->index); - - ctrl->index = ctrl->read_bytes; - return -EINVAL; - } - - for (i = 0; i < len; i++) - if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i]) - break; - - ctrl->index += len; - return i == len && ctrl->status == LTESR_CC ? 0 : -EIO; -} -#endif - /* This function is called after Program and Erase Operations to * check for success or failure. */ @@ -727,9 +692,6 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) nand->read_byte = fsl_elbc_read_byte; nand->write_buf = fsl_elbc_write_buf; nand->read_buf = fsl_elbc_read_buf; -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - nand->verify_buf = fsl_elbc_verify_buf; -#endif nand->select_chip = fsl_elbc_select_chip; nand->cmdfunc = fsl_elbc_cmdfunc; nand->waitfunc = fsl_elbc_wait; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index b283eae..7903eeb 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -683,41 +683,6 @@ static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) __func__, len, avail); } -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -/* - * Verify buffer against the IFC Controller Data Buffer - */ -static int fsl_ifc_verify_buf(struct mtd_info *mtd, - const u_char *buf, int len) -{ - struct nand_chip *chip = mtd->priv; - struct fsl_ifc_mtd *priv = chip->priv; - struct fsl_ifc_ctrl *ctrl = priv->ctrl; - int i; - - if (len < 0) { - printf("%s of %d bytes", __func__, len); - return -EINVAL; - } - - if ((unsigned int)len > ctrl->read_bytes - ctrl->index) { - printf("%s beyond end of buffer " - "(%d requested, %u available)\n", - __func__, len, ctrl->read_bytes - ctrl->index); - - ctrl->index = ctrl->read_bytes; - return -EINVAL; - } - - for (i = 0; i < len; i++) - if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i]) - break; - - ctrl->index += len; - return i == len && ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO; -} -#endif - /* This function is called after Program and Erase Operations to * check for success or failure. */ @@ -940,9 +905,6 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr) nand->write_buf = fsl_ifc_write_buf; nand->read_buf = fsl_ifc_read_buf; -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - nand->verify_buf = fsl_ifc_verify_buf; -#endif nand->select_chip = fsl_ifc_select_chip; nand->cmdfunc = fsl_ifc_cmdfunc; nand->waitfunc = fsl_ifc_wait; diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 65ce98a..5426c32 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -153,21 +153,6 @@ static void upm_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) buf[i] = in_8(chip->IO_ADDR_R); } -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -static int upm_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) -{ - int i; - struct nand_chip *chip = mtd->priv; - - for (i = 0; i < len; i++) { - if (buf[i] != in_8(chip->IO_ADDR_R)) - return -EFAULT; - } - - return 0; -} -#endif - static int nand_dev_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; @@ -193,9 +178,6 @@ int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun) chip->read_byte = upm_nand_read_byte; chip->read_buf = upm_nand_read_buf; chip->write_buf = upm_nand_write_buf; -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - chip->verify_buf = upm_nand_verify_buf; -#endif if (fun->dev_ready) chip->dev_ready = nand_dev_ready; diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 7233bfc..e621c36 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -459,29 +459,6 @@ static void mpc5121_nfc_write_buf(struct mtd_info *mtd, mpc5121_nfc_buf_copy(mtd, (u_char *) buf, len, 1); } -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -/* Compare buffer with NAND flash */ -static int mpc5121_nfc_verify_buf(struct mtd_info *mtd, - const u_char * buf, int len) -{ - u_char tmp[256]; - uint bsize; - - while (len) { - bsize = min(len, 256); - mpc5121_nfc_read_buf(mtd, tmp, bsize); - - if (memcmp(buf, tmp, bsize)) - return 1; - - buf += bsize; - len -= bsize; - } - - return 0; -} -#endif - /* Read byte from NFC buffers */ static u8 mpc5121_nfc_read_byte(struct mtd_info *mtd) { @@ -609,9 +586,6 @@ int board_nand_init(struct nand_chip *chip) chip->read_word = mpc5121_nfc_read_word; chip->read_buf = mpc5121_nfc_read_buf; chip->write_buf = mpc5121_nfc_write_buf; -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - chip->verify_buf = mpc5121_nfc_verify_buf; -#endif chip->select_chip = mpc5121_nfc_select_chip; chip->bbt_options = NAND_BBT_USE_FLASH; chip->ecc.mode = NAND_ECC_SOFT; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 2e5b5b9..f12b07e 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -949,34 +949,6 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) host->col_addr = col; } -#ifdef __UBOOT__ -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -/* - * Used by the upper layer to verify the data in NAND Flash - * with the data in the buf. - */ -static int mxc_nand_verify_buf(struct mtd_info *mtd, - const u_char *buf, int len) -{ - u_char tmp[256]; - uint bsize; - - while (len) { - bsize = min(len, 256); - mxc_nand_read_buf(mtd, tmp, bsize); - - if (memcmp(buf, tmp, bsize)) - return 1; - - buf += bsize; - len -= bsize; - } - - return 0; -} -#endif -#endif - /* * This function is used by upper layer for select and * deselect of the NAND chip @@ -1207,11 +1179,6 @@ int board_nand_init(struct nand_chip *this) this->read_word = mxc_nand_read_word; this->write_buf = mxc_nand_write_buf; this->read_buf = mxc_nand_read_buf; -#ifdef __UBOOT__ -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - this->verify_buf = mxc_nand_verify_buf; -#endif -#endif host->regs = (struct mxc_nand_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; #ifdef MXC_NFC_V3_2 diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 7a064ab..2d2b938 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -453,7 +453,7 @@ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length) d->cmd.data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_DEC_SEM | - MXS_DMA_DESC_WAIT4END | (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_WAIT4END | (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET); d->cmd.address = 0; @@ -510,7 +510,7 @@ static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, d->cmd.data = MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END | - (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET) | + (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET) | (length << MXS_DMA_DESC_BYTES_OFFSET); d->cmd.address = (dma_addr_t)nand_info->data_buf; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6db6566..c0e381a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -361,51 +361,6 @@ void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ioread8_rep(chip->IO_ADDR_R, buf, len); } -#ifdef __UBOOT__ -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -/** - * nand_verify_buf - [DEFAULT] Verify chip data against buffer - * @mtd: MTD device structure - * @buf: buffer containing the data to compare - * @len: number of bytes to compare - * - * Default verify function for 8bit buswidth. - */ -static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) -{ - int i; - struct nand_chip *chip = mtd->priv; - - for (i = 0; i < len; i++) - if (buf[i] != readb(chip->IO_ADDR_R)) - return -EFAULT; - return 0; -} - -/** - * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer - * @mtd: MTD device structure - * @buf: buffer containing the data to compare - * @len: number of bytes to compare - * - * Default verify function for 16bit buswidth. - */ -static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) -{ - int i; - struct nand_chip *chip = mtd->priv; - u16 *p = (u16 *) buf; - len >>= 1; - - for (i = 0; i < len; i++) - if (p[i] != readw(chip->IO_ADDR_R)) - return -EFAULT; - - return 0; -} -#endif -#endif - /** * nand_write_buf16 - [DEFAULT] write buffer to chip * @mtd: MTD device structure @@ -2435,20 +2390,6 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, status = chip->waitfunc(mtd, chip); } - -#ifdef __UBOOT__ -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - /* Send command to read back the data */ - chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); - - if (chip->verify_buf(mtd, buf, mtd->writesize)) - return -EIO; - - /* Make sure the next page prog is preceded by a status read */ - chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); -#endif -#endif - return 0; } @@ -3139,12 +3080,6 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; if (!chip->scan_bbt) chip->scan_bbt = nand_default_bbt; -#ifdef __UBOOT__ -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - if (!chip->verify_buf) - chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; -#endif -#endif if (!chip->controller) { chip->controller = &chip->hwcontrol; diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index afdd160..12dd26a 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -464,6 +464,87 @@ static size_t drop_ffs(const nand_info_t *nand, const u_char *buf, #endif /** + * nand_verify_page_oob: + * + * Verify a page of NAND flash, including the OOB. + * Reads page of NAND and verifies the contents and OOB against the + * values in ops. + * + * @param nand NAND device + * @param ops MTD operations, including data to verify + * @param ofs offset in flash + * @return 0 in case of success + */ +int nand_verify_page_oob(nand_info_t *nand, struct mtd_oob_ops *ops, loff_t ofs) +{ + int rval; + struct mtd_oob_ops vops; + size_t verlen = nand->writesize + nand->oobsize; + + memcpy(&vops, ops, sizeof(vops)); + + vops.datbuf = malloc(verlen); + + if (!vops.datbuf) + return -ENOMEM; + + vops.oobbuf = vops.datbuf + nand->writesize; + + rval = mtd_read_oob(nand, ofs, &vops); + if (!rval) + rval = memcmp(ops->datbuf, vops.datbuf, vops.len); + if (!rval) + rval = memcmp(ops->oobbuf, vops.oobbuf, vops.ooblen); + + free(vops.datbuf); + + return rval ? -EIO : 0; +} + +/** + * nand_verify: + * + * Verify a region of NAND flash. + * Reads NAND in page-sized chunks and verifies the contents against + * the contents of a buffer. The offset into the NAND must be + * page-aligned, and the function doesn't handle skipping bad blocks. + * + * @param nand NAND device + * @param ofs offset in flash + * @param len buffer length + * @param buf buffer to read from + * @return 0 in case of success + */ +int nand_verify(nand_info_t *nand, loff_t ofs, size_t len, u_char *buf) +{ + int rval = 0; + size_t verofs; + size_t verlen = nand->writesize; + uint8_t *verbuf = malloc(verlen); + + if (!verbuf) + return -ENOMEM; + + /* Read the NAND back in page-size groups to limit malloc size */ + for (verofs = ofs; verofs < ofs + len; + verofs += verlen, buf += verlen) { + verlen = min(nand->writesize, (uint32_t)(ofs + len - verofs)); + rval = nand_read(nand, verofs, &verlen, verbuf); + if (!rval || (rval == -EUCLEAN)) + rval = memcmp(buf, verbuf, verlen); + + if (rval) + break; + } + + free(verbuf); + + return rval ? -EIO : 0; +} + + + +/** * nand_write_skip_bad: * * Write image to NAND flash. @@ -499,24 +580,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, if (actual) *actual = 0; -#ifdef CONFIG_CMD_NAND_YAFFS - if (flags & WITH_YAFFS_OOB) { - if (flags & ~WITH_YAFFS_OOB) - return -EINVAL; - - int pages; - pages = nand->erasesize / nand->writesize; - blocksize = (pages * nand->oobsize) + nand->erasesize; - if (*length % (nand->writesize + nand->oobsize)) { - printf("Attempt to write incomplete page" - " in yaffs mode\n"); - return -EINVAL; - } - } else -#endif - { - blocksize = nand->erasesize; - } + blocksize = nand->erasesize; /* * nand_write() handles unaligned, partial page writes. @@ -554,6 +618,10 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, if (!need_skip && !(flags & WITH_DROP_FFS)) { rval = nand_write(nand, offset, length, buffer); + + if ((flags & WITH_WR_VERIFY) && !rval) + rval = nand_verify(nand, offset, *length, buffer); + if (rval == 0) return 0; @@ -581,48 +649,22 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, else write_size = blocksize - block_offset; -#ifdef CONFIG_CMD_NAND_YAFFS - if (flags & WITH_YAFFS_OOB) { - int page, pages; - size_t pagesize = nand->writesize; - size_t pagesize_oob = pagesize + nand->oobsize; - struct mtd_oob_ops ops; - - ops.len = pagesize; - ops.ooblen = nand->oobsize; - ops.mode = MTD_OPS_AUTO_OOB; - ops.ooboffs = 0; - - pages = write_size / pagesize_oob; - for (page = 0; page < pages; page++) { - WATCHDOG_RESET(); - - ops.datbuf = p_buffer; - ops.oobbuf = ops.datbuf + pagesize; - - rval = mtd_write_oob(nand, offset, &ops); - if (rval != 0) - break; - - offset += pagesize; - p_buffer += pagesize_oob; - } - } - else -#endif - { - truncated_write_size = write_size; + truncated_write_size = write_size; #ifdef CONFIG_CMD_NAND_TRIMFFS - if (flags & WITH_DROP_FFS) - truncated_write_size = drop_ffs(nand, p_buffer, - &write_size); + if (flags & WITH_DROP_FFS) + truncated_write_size = drop_ffs(nand, p_buffer, + &write_size); #endif - rval = nand_write(nand, offset, &truncated_write_size, - p_buffer); - offset += write_size; - p_buffer += write_size; - } + rval = nand_write(nand, offset, &truncated_write_size, + p_buffer); + + if ((flags & WITH_WR_VERIFY) && !rval) + rval = nand_verify(nand, offset, + truncated_write_size, p_buffer); + + offset += write_size; + p_buffer += write_size; if (rval != 0) { printf("NAND write to offset %llx failed %d\n", diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 2659595..8a68cb0 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -118,21 +118,6 @@ static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len out_be32((u32 *)(base + NDFC_DATA), *p++); } -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) -static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) -{ - struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; - uint32_t *p = (uint32_t *) buf; - - for (; len > 0; len -= 4) - if (*p++ != in_be32((u32 *)(base + NDFC_DATA))) - return -1; - - return 0; -} -#endif - /* * Read a byte from the NDFC. */ @@ -207,9 +192,6 @@ int board_nand_init(struct nand_chip *nand) #endif nand->write_buf = ndfc_write_buf; -#if defined(CONFIG_MTD_NAND_VERIFY_WRITE) - nand->verify_buf = ndfc_verify_buf; -#endif nand->read_byte = ndfc_read_byte; chip++; diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 928d58b..d98dd28 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -146,6 +146,7 @@ struct vf610_nfc { void __iomem *regs; uint column; int spareonly; + int page_sz; int page; /* Status and ID are in alternate locations. */ int alt_buf; @@ -329,6 +330,11 @@ static void vf610_nfc_addr_cycle(struct mtd_info *mtd, int column, int page) ROW_ADDR_SHIFT, page); } +static inline void vf610_nfc_transfer_size(void __iomem *regbase, int size) +{ + __raw_writel(size, regbase + NFC_SECTOR_SIZE); +} + /* Send command to NAND chip */ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command, int column, int page) @@ -342,12 +348,14 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command, switch (command) { case NAND_CMD_PAGEPROG: nfc->page = -1; + vf610_nfc_transfer_size(nfc->regs, nfc->page_sz); vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN, command, PROGRAM_PAGE_CMD_CODE); vf610_nfc_addr_cycle(mtd, column, page); break; case NAND_CMD_RESET: + vf610_nfc_transfer_size(nfc->regs, 0); vf610_nfc_send_command(nfc->regs, command, RESET_CMD_CODE); break; /* @@ -363,14 +371,15 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command, if (nfc->page == page) return; nfc->page = page; + vf610_nfc_transfer_size(nfc->regs, nfc->page_sz); vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0, NAND_CMD_READSTART, READ_PAGE_CMD_CODE); vf610_nfc_addr_cycle(mtd, column, page); break; case NAND_CMD_ERASE1: - if (nfc->page == page) - nfc->page = -1; + nfc->page = -1; + vf610_nfc_transfer_size(nfc->regs, 0); vf610_nfc_send_commands(nfc->regs, command, NAND_CMD_ERASE2, ERASE_CMD_CODE); vf610_nfc_addr_cycle(mtd, column, page); @@ -378,11 +387,13 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_READID: nfc->alt_buf = ALT_BUF_ID; + vf610_nfc_transfer_size(nfc->regs, 0); vf610_nfc_send_command(nfc->regs, command, READ_ID_CMD_CODE); break; case NAND_CMD_STATUS: nfc->alt_buf = ALT_BUF_STAT; + vf610_nfc_transfer_size(nfc->regs, 0); vf610_nfc_send_command(nfc->regs, command, STATUS_READ_CMD_CODE); break; @@ -580,7 +591,6 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr) struct nand_chip *chip; struct vf610_nfc *nfc; int err = 0; - int page_sz; struct vf610_nfc_config cfg = { .hardware_ecc = 1, #ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT @@ -634,9 +644,8 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr) chip->bbt_td = &bbt_main_descr; chip->bbt_md = &bbt_mirror_descr; - page_sz = PAGE_2K + OOB_64; - page_sz += cfg.width == 16 ? 1 : 0; - vf610_nfc_write(mtd, NFC_SECTOR_SIZE, page_sz); + nfc->page_sz = PAGE_2K + OOB_64; + nfc->page_sz += cfg.width == 16 ? 1 : 0; /* Set configuration register. */ vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT); @@ -665,16 +674,15 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr) chip->ecc.mode = NAND_ECC_SOFT; /* default */ - page_sz = mtd->writesize + mtd->oobsize; + nfc->page_sz = mtd->writesize + mtd->oobsize; /* Single buffer only, max 256 OOB minus ECC status */ - if (page_sz > PAGE_2K + 256 - 8) { + if (nfc->page_sz > PAGE_2K + 256 - 8) { dev_err(nfc->dev, "Unsupported flash size\n"); err = -ENXIO; goto error; } - page_sz += cfg.width == 16 ? 1 : 0; - vf610_nfc_write(mtd, NFC_SECTOR_SIZE, page_sz); + nfc->page_sz += cfg.width == 16 ? 1 : 0; if (cfg.hardware_ecc) { if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) { |