aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBastian Hecht <hechtb@googlemail.com>2012-05-14 08:14:43 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-07-06 13:17:03 -0400
commitef4ce0bcb3c91375d2bdefd7a0e2fead95c97620 (patch)
tree2be3ac4eb032f79b1abb91424e3257487102e170
parentaa32d1f0601ac2f5f69520175b8d2cea42caa025 (diff)
mtd: sh_flctl: Fix hardware ECC behaviour
The flctl uses 10 bytes ECC data for every 512 bytes sector. This patch makes the controller write all 40 bytes instead of 10 bytes only. Signed-off-by: Bastian Hecht <hechtb@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--drivers/mtd/nand/sh_flctl.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index b3666be0ccfc..8633b5b98a13 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -427,30 +427,20 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
427static void execmd_read_oob(struct mtd_info *mtd, int page_addr) 427static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
428{ 428{
429 struct sh_flctl *flctl = mtd_to_flctl(mtd); 429 struct sh_flctl *flctl = mtd_to_flctl(mtd);
430 int page_sectors = flctl->page_size ? 4 : 1;
431 int i;
430 432
431 set_cmd_regs(mtd, NAND_CMD_READ0, 433 set_cmd_regs(mtd, NAND_CMD_READ0,
432 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); 434 (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
433 435
434 empty_fifo(flctl); 436 empty_fifo(flctl);
435 if (flctl->page_size) {
436 int i;
437 /* In case that the page size is 2k */
438 for (i = 0; i < 16 * 3; i++)
439 flctl->done_buff[i] = 0xFF;
440
441 set_addr(mtd, 3 * 528 + 512, page_addr);
442 writel(16, FLDTCNTR(flctl));
443 437
444 start_translation(flctl); 438 for (i = 0; i < page_sectors; i++) {
445 read_fiforeg(flctl, 16, 16 * 3); 439 set_addr(mtd, (512 + 16) * i + 512 , page_addr);
446 wait_completion(flctl);
447 } else {
448 /* In case that the page size is 512b */
449 set_addr(mtd, 512, page_addr);
450 writel(16, FLDTCNTR(flctl)); 440 writel(16, FLDTCNTR(flctl));
451 441
452 start_translation(flctl); 442 start_translation(flctl);
453 read_fiforeg(flctl, 16, 0); 443 read_fiforeg(flctl, 16, 16 * i);
454 wait_completion(flctl); 444 wait_completion(flctl);
455 } 445 }
456} 446}
@@ -495,18 +485,12 @@ static void execmd_write_oob(struct mtd_info *mtd)
495 int page_addr = flctl->seqin_page_addr; 485 int page_addr = flctl->seqin_page_addr;
496 int sector, page_sectors; 486 int sector, page_sectors;
497 487
498 if (flctl->page_size) { 488 page_sectors = flctl->page_size ? 4 : 1;
499 sector = 3;
500 page_sectors = 4;
501 } else {
502 sector = 0;
503 page_sectors = 1;
504 }
505 489
506 set_cmd_regs(mtd, NAND_CMD_PAGEPROG, 490 set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
507 (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); 491 (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
508 492
509 for (; sector < page_sectors; sector++) { 493 for (sector = 0; sector < page_sectors; sector++) {
510 empty_fifo(flctl); 494 empty_fifo(flctl);
511 set_addr(mtd, sector * 528 + 512, page_addr); 495 set_addr(mtd, sector * 528 + 512, page_addr);
512 writel(16, FLDTCNTR(flctl)); /* set read size */ 496 writel(16, FLDTCNTR(flctl)); /* set read size */