diff options
Diffstat (limited to 'drivers/mtd/nand/fsl_elbc_nand.c')
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 86 |
1 files changed, 42 insertions, 44 deletions
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ddd37d2554ed..ae30fb6eed97 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -237,12 +237,15 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) | |||
237 | 237 | ||
238 | ctrl->use_mdr = 0; | 238 | ctrl->use_mdr = 0; |
239 | 239 | ||
240 | dev_vdbg(ctrl->dev, | 240 | if (ctrl->status != LTESR_CC) { |
241 | "fsl_elbc_run_command: stat=%08x mdr=%08x fmr=%08x\n", | 241 | dev_info(ctrl->dev, |
242 | ctrl->status, ctrl->mdr, in_be32(&lbc->fmr)); | 242 | "command failed: fir %x fcr %x status %x mdr %x\n", |
243 | in_be32(&lbc->fir), in_be32(&lbc->fcr), | ||
244 | ctrl->status, ctrl->mdr); | ||
245 | return -EIO; | ||
246 | } | ||
243 | 247 | ||
244 | /* returns 0 on success otherwise non-zero) */ | 248 | return 0; |
245 | return ctrl->status == LTESR_CC ? 0 : -EIO; | ||
246 | } | 249 | } |
247 | 250 | ||
248 | static void fsl_elbc_do_read(struct nand_chip *chip, int oob) | 251 | static void fsl_elbc_do_read(struct nand_chip *chip, int oob) |
@@ -253,17 +256,17 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob) | |||
253 | 256 | ||
254 | if (priv->page_size) { | 257 | if (priv->page_size) { |
255 | out_be32(&lbc->fir, | 258 | out_be32(&lbc->fir, |
256 | (FIR_OP_CW0 << FIR_OP0_SHIFT) | | 259 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
257 | (FIR_OP_CA << FIR_OP1_SHIFT) | | 260 | (FIR_OP_CA << FIR_OP1_SHIFT) | |
258 | (FIR_OP_PA << FIR_OP2_SHIFT) | | 261 | (FIR_OP_PA << FIR_OP2_SHIFT) | |
259 | (FIR_OP_CW1 << FIR_OP3_SHIFT) | | 262 | (FIR_OP_CM1 << FIR_OP3_SHIFT) | |
260 | (FIR_OP_RBW << FIR_OP4_SHIFT)); | 263 | (FIR_OP_RBW << FIR_OP4_SHIFT)); |
261 | 264 | ||
262 | out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | | 265 | out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | |
263 | (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); | 266 | (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); |
264 | } else { | 267 | } else { |
265 | out_be32(&lbc->fir, | 268 | out_be32(&lbc->fir, |
266 | (FIR_OP_CW0 << FIR_OP0_SHIFT) | | 269 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
267 | (FIR_OP_CA << FIR_OP1_SHIFT) | | 270 | (FIR_OP_CA << FIR_OP1_SHIFT) | |
268 | (FIR_OP_PA << FIR_OP2_SHIFT) | | 271 | (FIR_OP_PA << FIR_OP2_SHIFT) | |
269 | (FIR_OP_RBW << FIR_OP3_SHIFT)); | 272 | (FIR_OP_RBW << FIR_OP3_SHIFT)); |
@@ -332,7 +335,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, | |||
332 | case NAND_CMD_READID: | 335 | case NAND_CMD_READID: |
333 | dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n"); | 336 | dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n"); |
334 | 337 | ||
335 | out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | | 338 | out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
336 | (FIR_OP_UA << FIR_OP1_SHIFT) | | 339 | (FIR_OP_UA << FIR_OP1_SHIFT) | |
337 | (FIR_OP_RBW << FIR_OP2_SHIFT)); | 340 | (FIR_OP_RBW << FIR_OP2_SHIFT)); |
338 | out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT); | 341 | out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT); |
@@ -359,16 +362,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"); | 362 | dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n"); |
360 | 363 | ||
361 | out_be32(&lbc->fir, | 364 | out_be32(&lbc->fir, |
362 | (FIR_OP_CW0 << FIR_OP0_SHIFT) | | 365 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
363 | (FIR_OP_PA << FIR_OP1_SHIFT) | | 366 | (FIR_OP_PA << FIR_OP1_SHIFT) | |
364 | (FIR_OP_CM1 << FIR_OP2_SHIFT)); | 367 | (FIR_OP_CM2 << FIR_OP2_SHIFT) | |
368 | (FIR_OP_CW1 << FIR_OP3_SHIFT) | | ||
369 | (FIR_OP_RS << FIR_OP4_SHIFT)); | ||
365 | 370 | ||
366 | out_be32(&lbc->fcr, | 371 | out_be32(&lbc->fcr, |
367 | (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | | 372 | (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | |
368 | (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT)); | 373 | (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | |
374 | (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT)); | ||
369 | 375 | ||
370 | out_be32(&lbc->fbcr, 0); | 376 | out_be32(&lbc->fbcr, 0); |
371 | ctrl->read_bytes = 0; | 377 | ctrl->read_bytes = 0; |
378 | ctrl->use_mdr = 1; | ||
372 | 379 | ||
373 | fsl_elbc_run_command(mtd); | 380 | fsl_elbc_run_command(mtd); |
374 | return; | 381 | return; |
@@ -383,40 +390,41 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, | |||
383 | 390 | ||
384 | ctrl->column = column; | 391 | ctrl->column = column; |
385 | ctrl->oob = 0; | 392 | ctrl->oob = 0; |
393 | ctrl->use_mdr = 1; | ||
386 | 394 | ||
387 | if (priv->page_size) { | 395 | fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | |
388 | fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) | | 396 | (NAND_CMD_SEQIN << FCR_CMD2_SHIFT) | |
389 | (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT); | 397 | (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT); |
390 | 398 | ||
399 | if (priv->page_size) { | ||
391 | out_be32(&lbc->fir, | 400 | out_be32(&lbc->fir, |
392 | (FIR_OP_CW0 << FIR_OP0_SHIFT) | | 401 | (FIR_OP_CM2 << FIR_OP0_SHIFT) | |
393 | (FIR_OP_CA << FIR_OP1_SHIFT) | | 402 | (FIR_OP_CA << FIR_OP1_SHIFT) | |
394 | (FIR_OP_PA << FIR_OP2_SHIFT) | | 403 | (FIR_OP_PA << FIR_OP2_SHIFT) | |
395 | (FIR_OP_WB << FIR_OP3_SHIFT) | | 404 | (FIR_OP_WB << FIR_OP3_SHIFT) | |
396 | (FIR_OP_CW1 << FIR_OP4_SHIFT)); | 405 | (FIR_OP_CM3 << FIR_OP4_SHIFT) | |
406 | (FIR_OP_CW1 << FIR_OP5_SHIFT) | | ||
407 | (FIR_OP_RS << FIR_OP6_SHIFT)); | ||
397 | } else { | 408 | } else { |
398 | fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) | | ||
399 | (NAND_CMD_SEQIN << FCR_CMD2_SHIFT); | ||
400 | |||
401 | out_be32(&lbc->fir, | 409 | out_be32(&lbc->fir, |
402 | (FIR_OP_CW0 << FIR_OP0_SHIFT) | | 410 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
403 | (FIR_OP_CM2 << FIR_OP1_SHIFT) | | 411 | (FIR_OP_CM2 << FIR_OP1_SHIFT) | |
404 | (FIR_OP_CA << FIR_OP2_SHIFT) | | 412 | (FIR_OP_CA << FIR_OP2_SHIFT) | |
405 | (FIR_OP_PA << FIR_OP3_SHIFT) | | 413 | (FIR_OP_PA << FIR_OP3_SHIFT) | |
406 | (FIR_OP_WB << FIR_OP4_SHIFT) | | 414 | (FIR_OP_WB << FIR_OP4_SHIFT) | |
407 | (FIR_OP_CW1 << FIR_OP5_SHIFT)); | 415 | (FIR_OP_CM3 << FIR_OP5_SHIFT) | |
416 | (FIR_OP_CW1 << FIR_OP6_SHIFT) | | ||
417 | (FIR_OP_RS << FIR_OP7_SHIFT)); | ||
408 | 418 | ||
409 | if (column >= mtd->writesize) { | 419 | if (column >= mtd->writesize) { |
410 | /* OOB area --> READOOB */ | 420 | /* OOB area --> READOOB */ |
411 | column -= mtd->writesize; | 421 | column -= mtd->writesize; |
412 | fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; | 422 | fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; |
413 | ctrl->oob = 1; | 423 | ctrl->oob = 1; |
414 | } else if (column < 256) { | 424 | } else { |
425 | WARN_ON(column != 0); | ||
415 | /* First 256 bytes --> READ0 */ | 426 | /* First 256 bytes --> READ0 */ |
416 | fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; | 427 | fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; |
417 | } else { | ||
418 | /* Second 256 bytes --> READ1 */ | ||
419 | fcr |= NAND_CMD_READ1 << FCR_CMD0_SHIFT; | ||
420 | } | 428 | } |
421 | } | 429 | } |
422 | 430 | ||
@@ -628,22 +636,6 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
628 | { | 636 | { |
629 | struct fsl_elbc_mtd *priv = chip->priv; | 637 | struct fsl_elbc_mtd *priv = chip->priv; |
630 | struct fsl_elbc_ctrl *ctrl = priv->ctrl; | 638 | 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 | 639 | ||
648 | if (ctrl->status != LTESR_CC) | 640 | if (ctrl->status != LTESR_CC) |
649 | return NAND_STATUS_FAIL; | 641 | return NAND_STATUS_FAIL; |
@@ -651,8 +643,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
651 | /* The chip always seems to report that it is | 643 | /* The chip always seems to report that it is |
652 | * write-protected, even when it is not. | 644 | * write-protected, even when it is not. |
653 | */ | 645 | */ |
654 | setbits8(ctrl->addr, NAND_STATUS_WP); | 646 | return (ctrl->mdr & 0xff) | NAND_STATUS_WP; |
655 | return fsl_elbc_read_byte(mtd); | ||
656 | } | 647 | } |
657 | 648 | ||
658 | static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | 649 | static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) |
@@ -946,6 +937,13 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl) | |||
946 | { | 937 | { |
947 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 938 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
948 | 939 | ||
940 | /* | ||
941 | * NAND transactions can tie up the bus for a long time, so set the | ||
942 | * bus timeout to max by clearing LBCR[BMT] (highest base counter | ||
943 | * value) and setting LBCR[BMTPS] to the highest prescaler value. | ||
944 | */ | ||
945 | clrsetbits_be32(&lbc->lbcr, LBCR_BMT, 15); | ||
946 | |||
949 | /* clear event registers */ | 947 | /* clear event registers */ |
950 | setbits32(&lbc->ltesr, LTESR_NAND_MASK); | 948 | setbits32(&lbc->ltesr, LTESR_NAND_MASK); |
951 | out_be32(&lbc->lteatr, 0); | 949 | out_be32(&lbc->lteatr, 0); |