From 156800905a17f3ce1638f89fb0f7b4bf55a1fa02 Mon Sep 17 00:00:00 2001 From: Stefan Bigler Date: Mon, 18 Jul 2011 15:25:11 +0200 Subject: nand: increase chip_delay in mv kirkwood nand driver The new SAMSUNG NAND Flash K9F1G08U0D require a bigger chip_delay. The Data Transfer from Cell to Register is >= 35us. Other Vendors and older chips normally use >= 25us. To have enough margin 40us is selected. Signed-off-by: Stefan Bigler Signed-off-by: Holger Brunck cc: Prafulla Wadaskar cc: Stefan Roese Signed-off-by: Scott Wood --- drivers/mtd/nand/kirkwood_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/nand') diff --git a/drivers/mtd/nand/kirkwood_nand.c b/drivers/mtd/nand/kirkwood_nand.c index 376378ed3f..bdab5aa795 100644 --- a/drivers/mtd/nand/kirkwood_nand.c +++ b/drivers/mtd/nand/kirkwood_nand.c @@ -76,7 +76,7 @@ int board_nand_init(struct nand_chip *nand) nand->options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING; nand->ecc.mode = NAND_ECC_SOFT; nand->cmd_ctrl = kw_nand_hwcontrol; - nand->chip_delay = 30; + nand->chip_delay = 40; nand->select_chip = kw_nand_select_chip; return 0; } -- cgit v1.2.1 From 780f30b642177793a984cf0a3c428994a0564f88 Mon Sep 17 00:00:00 2001 From: Helmut Raiger Date: Wed, 6 Jul 2011 09:40:28 +0200 Subject: mxc_nand: fixed some typos (cosmetic) Signed-off-by: Helmut Raiger Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers/mtd/nand') diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 2a8dd7e239..78e07cc7f7 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -350,7 +350,7 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr) } /* - * This function requests the NANDFC to initate the transfer + * This function requests the NANDFC to initiate the transfer * of data currently in the NANDFC RAM buffer to the NAND device. */ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, @@ -394,7 +394,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, } /* - * Requests NANDFC to initated the transfer of data from the + * Requests NANDFC to initiate the transfer of data from the * NAND device into in the NANDFC ram buffer. */ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, @@ -637,7 +637,7 @@ static int mxc_nand_read_page_syndrome(struct mtd_info *mtd, MTDDEBUG(MTD_DEBUG_LEVEL1, "Reading page %u to buf %p oob %p\n", host->page_addr, buf, oob); - /* first read out the data area and the available portion of OOB */ + /* first read the data area and the available portion of OOB */ for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) { int stat; @@ -1179,7 +1179,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, /* * before sending SEQIN command for partial write, * we need read one page out. FSL NFC does not support - * partial write. It alway send out 512+ecc+512+ecc ... + * partial write. It always sends out 512+ecc+512+ecc * for large page nand flash. But for small page nand * flash, it does support SPARE ONLY operation. */ @@ -1209,7 +1209,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_prog_page(host, 0, host->spare_only); if (host->pagesize_2k && !is_mxc_nfc_11()) { - /* data in 4 areas datas */ + /* data in 4 areas */ send_prog_page(host, 1, host->spare_only); send_prog_page(host, 2, host->spare_only); send_prog_page(host, 3, host->spare_only); @@ -1225,10 +1225,9 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, if (column != -1) { /* * MXC NANDFC can only perform full page+spare or - * spare-only read/write. When the upper layers - * layers perform a read/write buf operation, - * we will used the saved column adress to index into - * the full page. + * spare-only read/write. When the upper layers perform + * a read/write buffer operation, we will use the saved + * column address to index into the full page. */ send_addr(host, 0); if (host->pagesize_2k) @@ -1377,7 +1376,7 @@ int board_nand_init(struct nand_chip *this) /* Unlock Block Command for given address range */ writew(0x4, &host->regs->nfc_wrprot); - /* NAND bus width determines access funtions used by upper layer */ + /* NAND bus width determines access functions used by upper layer */ if (is_16bit_nand()) this->options |= NAND_BUSWIDTH_16; -- cgit v1.2.1 From b4b1e769b8f6e80219da576d45a10c9e0ca5446b Mon Sep 17 00:00:00 2001 From: Helmut Raiger Date: Wed, 6 Jul 2011 19:04:41 +0200 Subject: mxc_nand: fix a problem writing more than 32MB When writing 0x4000 to the unlockend_blkaddr register, large writes to a 2k page NAND sometimes fail. The current kernel driver writes 0xFFFF to this register for V2 of the nand controller. However on an i.MX31 this also fixes writes larger than 32MB. The datasheet is very unspecific, but (0x4000=16384)*2000 roughly fits the limits we're encountering with NAND writes. This problem might be NAND chip specific. Signed-off-by: Helmut Raiger Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/mtd/nand') diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 78e07cc7f7..35e89a0f4d 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1371,7 +1371,18 @@ int board_nand_init(struct nand_chip *this) /* Blocks to be unlocked */ writew(0x0, &host->regs->nfc_unlockstart_blkaddr); - writew(0x4000, &host->regs->nfc_unlockend_blkaddr); + /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the + * unlockend_blkaddr, but the magic 0x4000 does not always work + * when writing more than some 32 megabytes (on 2k page nands) + * However 0xFFFF doesn't seem to have this kind + * of limitation (tried it back and forth several times). + * The linux kernel driver sets this to 0xFFFF for the v2 controller + * only, but probably this was not tested there for v1. + * The very same limitation seems to apply to this kernel driver. + * This might be NAND chip specific and the i.MX31 datasheet is + * extremely vague about the semantics of this register. + */ + writew(0xFFFF, &host->regs->nfc_unlockend_blkaddr); /* Unlock Block Command for given address range */ writew(0x4, &host->regs->nfc_wrprot); -- cgit v1.2.1 From 6d41419f0b010db03c01dec59875144457aa11d2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 12 Sep 2011 06:04:06 +0200 Subject: NAND: Really ignore bad blocks when scrubbing Signed-off-by: Marek Vasut Cc: Scott Wood Cc: Stefano Babic Cc: Wolfgang Denk Cc: Detlev Zundel [scottwood@freescale.com: use chip instead of redundant priv_nand] Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 2 +- drivers/mtd/nand/nand_util.c | 29 ++++++++--------------------- 2 files changed, 9 insertions(+), 22 deletions(-) (limited to 'drivers/mtd/nand') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index e7dfcb1568..6aac6a2bf4 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2224,7 +2224,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, /* * heck if we have a bad block, we do not erase bad blocks ! */ - if (nand_block_checkbad(mtd, ((loff_t) page) << + if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) << chip->page_shift, 0, allowbbt)) { printk(KERN_WARNING "nand_erase: attempt to erase a " "bad block at page 0x%08x\n", page); diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 81bf366159..60c778e637 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -57,12 +57,6 @@ typedef struct mtd_info mtd_info_t; #define cpu_to_je16(x) (x) #define cpu_to_je32(x) (x) -/*****************************************************************************/ -static int nand_block_bad_scrub(struct mtd_info *mtd, loff_t ofs, int getchip) -{ - return 0; -} - /** * nand_erase_opts: - erase NAND flash with support for various options * (jffs2 formating) @@ -82,7 +76,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) int bbtest = 1; int result; int percent_complete = -1; - int (*nand_block_bad_old)(struct mtd_info *, loff_t, int) = NULL; const char *mtd_device = meminfo->name; struct mtd_oob_ops oob_opts; struct nand_chip *chip = meminfo->priv; @@ -110,17 +103,15 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) * and disable bad block table while erasing. */ if (opts->scrub) { - struct nand_chip *priv_nand = meminfo->priv; - - nand_block_bad_old = priv_nand->block_bad; - priv_nand->block_bad = nand_block_bad_scrub; - /* we don't need the bad block table anymore... + erase.scrub = opts->scrub; + /* + * We don't need the bad block table anymore... * after scrub, there are no bad blocks left! */ - if (priv_nand->bbt) { - kfree(priv_nand->bbt); + if (chip->bbt) { + kfree(chip->bbt); } - priv_nand->bbt = NULL; + chip->bbt = NULL; } for (erased_length = 0; @@ -204,12 +195,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) if (!opts->quiet) printf("\n"); - if (nand_block_bad_old) { - struct nand_chip *priv_nand = meminfo->priv; - - priv_nand->block_bad = nand_block_bad_old; - priv_nand->scan_bbt(meminfo); - } + if (opts->scrub) + chip->scan_bbt(meminfo); return 0; } -- cgit v1.2.1 From 17d261df18acfab96dcb5e0e078d2fe81a7d70ad Mon Sep 17 00:00:00 2001 From: mhench Date: Mon, 11 Jul 2011 12:29:43 +0000 Subject: mtd: eLBC NAND: remove elbc_fcm_ctrl->oob_poi The eLBC NAND driver currently follows up each program/write operation with a read-back of the page, in order to [ostensibly] fill in ECC data for the caller. However, the page address used for this read is always -1, so the read will never work correctly. Remove this useless (and potentially problematic) block of code. v2: fix broken mailer Signed-off-by: mhench Signed-off-by: Scott Wood --- drivers/mtd/nand/fsl_elbc_nand.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'drivers/mtd/nand') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index acdb43112a..4d1e527db1 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -85,7 +85,6 @@ struct fsl_elbc_ctrl { unsigned int mdr; /* UPM/FCM Data Register value */ unsigned int use_mdr; /* Non zero if the MDR is to be set */ unsigned int oob; /* Non zero if operating on OOB data */ - uint8_t *oob_poi; /* Place to write ECC after read back */ }; /* These map to the positions used by the FCM hardware ECC generator */ @@ -436,7 +435,6 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ case NAND_CMD_PAGEPROG: { - int full_page; vdbg("fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG " "writing %d bytes.\n", ctrl->index); @@ -445,34 +443,13 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, * write so the HW generates the ECC. */ if (ctrl->oob || ctrl->column != 0 || - ctrl->index != mtd->writesize + mtd->oobsize) { + ctrl->index != mtd->writesize + mtd->oobsize) out_be32(&lbc->fbcr, ctrl->index); - full_page = 0; - } else { + else out_be32(&lbc->fbcr, 0); - full_page = 1; - } fsl_elbc_run_command(mtd); - /* Read back the page in order to fill in the ECC for the - * caller. Is this really needed? - */ - if (full_page && ctrl->oob_poi) { - out_be32(&lbc->fbcr, 3); - set_addr(mtd, 6, page_addr, 1); - - ctrl->read_bytes = mtd->writesize + 9; - - fsl_elbc_do_read(chip, 1); - fsl_elbc_run_command(mtd); - - memcpy_fromio(ctrl->oob_poi + 6, - &ctrl->addr[ctrl->index], 3); - ctrl->index += 3; - } - - ctrl->oob_poi = NULL; return; } @@ -680,13 +657,8 @@ static void fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf) { - struct fsl_elbc_mtd *priv = chip->priv; - struct fsl_elbc_ctrl *ctrl = priv->ctrl; - fsl_elbc_write_buf(mtd, buf, mtd->writesize); fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); - - ctrl->oob_poi = chip->oob_poi; } static struct fsl_elbc_ctrl *elbc_ctrl; -- cgit v1.2.1 From 24dd863f8b4cd4125a427943665ccf782d8aa940 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 4 Oct 2011 00:56:07 +0200 Subject: PPC: Fix fsl_upm.c by renaming nand handling functions This avoids colision with nand subsystem's functions. Signed-off-by: Marek Vasut Cc: Scott Wood Signed-off-by: Scott Wood --- drivers/mtd/nand/fsl_upm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/mtd/nand') diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index c33e2786b2..31c174bd3b 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -124,14 +124,14 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) fun_wait(fun); } -static u8 nand_read_byte(struct mtd_info *mtd) +static u8 upm_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; return in_8(chip->IO_ADDR_R); } -static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +static void upm_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) { int i; struct nand_chip *chip = mtd->priv; @@ -147,7 +147,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) fun_wait(fun); } -static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +static void upm_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { int i; struct nand_chip *chip = mtd->priv; @@ -156,7 +156,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) buf[i] = in_8(chip->IO_ADDR_R); } -static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) +static int upm_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) { int i; struct nand_chip *chip = mtd->priv; @@ -191,10 +191,10 @@ int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun) #if CONFIG_SYS_NAND_MAX_CHIPS > 1 chip->select_chip = fun_select_chip; #endif - chip->read_byte = nand_read_byte; - chip->read_buf = nand_read_buf; - chip->write_buf = nand_write_buf; - chip->verify_buf = nand_verify_buf; + chip->read_byte = upm_nand_read_byte; + chip->read_buf = upm_nand_read_buf; + chip->write_buf = upm_nand_write_buf; + chip->verify_buf = upm_nand_verify_buf; if (fun->dev_ready) chip->dev_ready = nand_dev_ready; -- cgit v1.2.1