aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2009-11-13 15:13:01 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-11-30 04:53:49 -0500
commit476459a6cf46d20ec73d9b211f3894ced5f9871e (patch)
tree38825d12755f3ff540b15a8f42ebeb6bab6d10f1 /drivers/mtd/nand
parentb3a70f0bc32d1b70584bcaa6019fa4260b0da92e (diff)
mtd: eLBC NAND: use recommended command sequences
Currently, the program and erase sequences do not wait for completion, instead relying on a subsequent waitfunc() callback. However, this causes the chipselect to be deasserted while the NAND chip is still asserting the busy pin, which can corrupt activity on other chipselects. This patch switches to using the sequences recommended by the manual, in which a wait is performed within the initial command sequence. We can now re-use the status byte from the initial command sequence, rather than having to do another status read in the waitfunc. Since we're already touching the command sequences, it also cleans up some cruft in SEQIN that isn't needed since we cannot program partial pages outside of OOB. Signed-off-by: Scott Wood <scottwood@freescale.com> Reported-by: Suchit Lepcha <suchit.lepcha@freescale.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 58db27855126..5b51ed3cf71d 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -253,17 +253,17 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
253 253
254 if (priv->page_size) { 254 if (priv->page_size) {
255 out_be32(&lbc->fir, 255 out_be32(&lbc->fir,
256 (FIR_OP_CW0 << FIR_OP0_SHIFT) | 256 (FIR_OP_CM0 << FIR_OP0_SHIFT) |
257 (FIR_OP_CA << FIR_OP1_SHIFT) | 257 (FIR_OP_CA << FIR_OP1_SHIFT) |
258 (FIR_OP_PA << FIR_OP2_SHIFT) | 258 (FIR_OP_PA << FIR_OP2_SHIFT) |
259 (FIR_OP_CW1 << FIR_OP3_SHIFT) | 259 (FIR_OP_CM1 << FIR_OP3_SHIFT) |
260 (FIR_OP_RBW << FIR_OP4_SHIFT)); 260 (FIR_OP_RBW << FIR_OP4_SHIFT));
261 261
262 out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | 262 out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
263 (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); 263 (NAND_CMD_READSTART << FCR_CMD1_SHIFT));
264 } else { 264 } else {
265 out_be32(&lbc->fir, 265 out_be32(&lbc->fir,
266 (FIR_OP_CW0 << FIR_OP0_SHIFT) | 266 (FIR_OP_CM0 << FIR_OP0_SHIFT) |
267 (FIR_OP_CA << FIR_OP1_SHIFT) | 267 (FIR_OP_CA << FIR_OP1_SHIFT) |
268 (FIR_OP_PA << FIR_OP2_SHIFT) | 268 (FIR_OP_PA << FIR_OP2_SHIFT) |
269 (FIR_OP_RBW << FIR_OP3_SHIFT)); 269 (FIR_OP_RBW << FIR_OP3_SHIFT));
@@ -332,7 +332,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
332 case NAND_CMD_READID: 332 case NAND_CMD_READID:
333 dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n"); 333 dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
334 334
335 out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | 335 out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) |
336 (FIR_OP_UA << FIR_OP1_SHIFT) | 336 (FIR_OP_UA << FIR_OP1_SHIFT) |
337 (FIR_OP_RBW << FIR_OP2_SHIFT)); 337 (FIR_OP_RBW << FIR_OP2_SHIFT));
338 out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT); 338 out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
@@ -359,16 +359,20 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
359 dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n"); 359 dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n");
360 360
361 out_be32(&lbc->fir, 361 out_be32(&lbc->fir,
362 (FIR_OP_CW0 << FIR_OP0_SHIFT) | 362 (FIR_OP_CM0 << FIR_OP0_SHIFT) |
363 (FIR_OP_PA << FIR_OP1_SHIFT) | 363 (FIR_OP_PA << FIR_OP1_SHIFT) |
364 (FIR_OP_CM1 << FIR_OP2_SHIFT)); 364 (FIR_OP_CM2 << FIR_OP2_SHIFT) |
365 (FIR_OP_CW1 << FIR_OP3_SHIFT) |
366 (FIR_OP_RS << FIR_OP4_SHIFT));
365 367
366 out_be32(&lbc->fcr, 368 out_be32(&lbc->fcr,
367 (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | 369 (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) |
368 (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT)); 370 (NAND_CMD_STATUS << FCR_CMD1_SHIFT) |
371 (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT));
369 372
370 out_be32(&lbc->fbcr, 0); 373 out_be32(&lbc->fbcr, 0);
371 ctrl->read_bytes = 0; 374 ctrl->read_bytes = 0;
375 ctrl->use_mdr = 1;
372 376
373 fsl_elbc_run_command(mtd); 377 fsl_elbc_run_command(mtd);
374 return; 378 return;
@@ -383,40 +387,41 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
383 387
384 ctrl->column = column; 388 ctrl->column = column;
385 ctrl->oob = 0; 389 ctrl->oob = 0;
390 ctrl->use_mdr = 1;
386 391
387 if (priv->page_size) { 392 fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) |
388 fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) | 393 (NAND_CMD_SEQIN << FCR_CMD2_SHIFT) |
389 (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT); 394 (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
390 395
396 if (priv->page_size) {
391 out_be32(&lbc->fir, 397 out_be32(&lbc->fir,
392 (FIR_OP_CW0 << FIR_OP0_SHIFT) | 398 (FIR_OP_CM2 << FIR_OP0_SHIFT) |
393 (FIR_OP_CA << FIR_OP1_SHIFT) | 399 (FIR_OP_CA << FIR_OP1_SHIFT) |
394 (FIR_OP_PA << FIR_OP2_SHIFT) | 400 (FIR_OP_PA << FIR_OP2_SHIFT) |
395 (FIR_OP_WB << FIR_OP3_SHIFT) | 401 (FIR_OP_WB << FIR_OP3_SHIFT) |
396 (FIR_OP_CW1 << FIR_OP4_SHIFT)); 402 (FIR_OP_CM3 << FIR_OP4_SHIFT) |
403 (FIR_OP_CW1 << FIR_OP5_SHIFT) |
404 (FIR_OP_RS << FIR_OP6_SHIFT));
397 } else { 405 } else {
398 fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) |
399 (NAND_CMD_SEQIN << FCR_CMD2_SHIFT);
400
401 out_be32(&lbc->fir, 406 out_be32(&lbc->fir,
402 (FIR_OP_CW0 << FIR_OP0_SHIFT) | 407 (FIR_OP_CM0 << FIR_OP0_SHIFT) |
403 (FIR_OP_CM2 << FIR_OP1_SHIFT) | 408 (FIR_OP_CM2 << FIR_OP1_SHIFT) |
404 (FIR_OP_CA << FIR_OP2_SHIFT) | 409 (FIR_OP_CA << FIR_OP2_SHIFT) |
405 (FIR_OP_PA << FIR_OP3_SHIFT) | 410 (FIR_OP_PA << FIR_OP3_SHIFT) |
406 (FIR_OP_WB << FIR_OP4_SHIFT) | 411 (FIR_OP_WB << FIR_OP4_SHIFT) |
407 (FIR_OP_CW1 << FIR_OP5_SHIFT)); 412 (FIR_OP_CM3 << FIR_OP5_SHIFT) |
413 (FIR_OP_CW1 << FIR_OP6_SHIFT) |
414 (FIR_OP_RS << FIR_OP7_SHIFT));
408 415
409 if (column >= mtd->writesize) { 416 if (column >= mtd->writesize) {
410 /* OOB area --> READOOB */ 417 /* OOB area --> READOOB */
411 column -= mtd->writesize; 418 column -= mtd->writesize;
412 fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; 419 fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
413 ctrl->oob = 1; 420 ctrl->oob = 1;
414 } else if (column < 256) { 421 } else {
422 WARN_ON(column != 0);
415 /* First 256 bytes --> READ0 */ 423 /* First 256 bytes --> READ0 */
416 fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; 424 fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
417 } else {
418 /* Second 256 bytes --> READ1 */
419 fcr |= NAND_CMD_READ1 << FCR_CMD0_SHIFT;
420 } 425 }
421 } 426 }
422 427
@@ -628,22 +633,6 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)
628{ 633{
629 struct fsl_elbc_mtd *priv = chip->priv; 634 struct fsl_elbc_mtd *priv = chip->priv;
630 struct fsl_elbc_ctrl *ctrl = priv->ctrl; 635 struct fsl_elbc_ctrl *ctrl = priv->ctrl;
631 struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
632
633 if (ctrl->status != LTESR_CC)
634 return NAND_STATUS_FAIL;
635
636 /* Use READ_STATUS command, but wait for the device to be ready */
637 ctrl->use_mdr = 0;
638 out_be32(&lbc->fir,
639 (FIR_OP_CW0 << FIR_OP0_SHIFT) |
640 (FIR_OP_RBW << FIR_OP1_SHIFT));
641 out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT);
642 out_be32(&lbc->fbcr, 1);
643 set_addr(mtd, 0, 0, 0);
644 ctrl->read_bytes = 1;
645
646 fsl_elbc_run_command(mtd);
647 636
648 if (ctrl->status != LTESR_CC) 637 if (ctrl->status != LTESR_CC)
649 return NAND_STATUS_FAIL; 638 return NAND_STATUS_FAIL;
@@ -651,8 +640,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)
651 /* The chip always seems to report that it is 640 /* The chip always seems to report that it is
652 * write-protected, even when it is not. 641 * write-protected, even when it is not.
653 */ 642 */
654 setbits8(ctrl->addr, NAND_STATUS_WP); 643 return (ctrl->mdr & 0xff) | NAND_STATUS_WP;
655 return fsl_elbc_read_byte(mtd);
656} 644}
657 645
658static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) 646static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)