aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVipin Kumar <vipin.kumar@st.com>2012-10-09 06:44:50 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-11-15 08:37:48 -0500
commita4742d515071b8b7889a6b608da48d36c1dfcc71 (patch)
treebe7a07d746e8e1f2715421a5be9d18eafb15b70e
parent928aa2aeb7269292ca1e3d0e5e2e5d08af13da3d (diff)
mtd: fsmc_nand: use relaxed variants of io accessors
Use relaxed variants of readl/writel accessors. readl/writel io accessors use explicit dsb instruction which causes stalls in the processor core resulting several cycles of delay for each access Use relaxed variants where ever possible. This also results in an improved read/write performance. Signed-off-by: Vipin Kumar <vipin.kumar@st.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
-rw-r--r--drivers/mtd/nand/fsmc_nand.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 82c0371f71e8..6b592235f847 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
383 pc |= FSMC_ENABLE; 383 pc |= FSMC_ENABLE;
384 else 384 else
385 pc &= ~FSMC_ENABLE; 385 pc &= ~FSMC_ENABLE;
386 writel(pc, FSMC_NAND_REG(regs, bank, PC)); 386 writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC));
387 } 387 }
388 388
389 mb(); 389 mb();
390 390
391 if (cmd != NAND_CMD_NONE) 391 if (cmd != NAND_CMD_NONE)
392 writeb(cmd, this->IO_ADDR_W); 392 writeb_relaxed(cmd, this->IO_ADDR_W);
393} 393}
394 394
395/* 395/*
@@ -426,14 +426,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
426 tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; 426 tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
427 427
428 if (busw) 428 if (busw)
429 writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC)); 429 writel_relaxed(value | FSMC_DEVWID_16,
430 FSMC_NAND_REG(regs, bank, PC));
430 else 431 else
431 writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC)); 432 writel_relaxed(value | FSMC_DEVWID_8,
433 FSMC_NAND_REG(regs, bank, PC));
432 434
433 writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, 435 writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
434 FSMC_NAND_REG(regs, bank, PC)); 436 FSMC_NAND_REG(regs, bank, PC));
435 writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM)); 437 writel_relaxed(thiz | thold | twait | tset,
436 writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB)); 438 FSMC_NAND_REG(regs, bank, COMM));
439 writel_relaxed(thiz | thold | twait | tset,
440 FSMC_NAND_REG(regs, bank, ATTRIB));
437} 441}
438 442
439/* 443/*
@@ -446,11 +450,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
446 void __iomem *regs = host->regs_va; 450 void __iomem *regs = host->regs_va;
447 uint32_t bank = host->bank; 451 uint32_t bank = host->bank;
448 452
449 writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, 453 writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
450 FSMC_NAND_REG(regs, bank, PC)); 454 FSMC_NAND_REG(regs, bank, PC));
451 writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, 455 writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
452 FSMC_NAND_REG(regs, bank, PC)); 456 FSMC_NAND_REG(regs, bank, PC));
453 writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, 457 writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
454 FSMC_NAND_REG(regs, bank, PC)); 458 FSMC_NAND_REG(regs, bank, PC));
455} 459}
456 460
@@ -470,7 +474,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
470 unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; 474 unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
471 475
472 do { 476 do {
473 if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) 477 if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
474 break; 478 break;
475 else 479 else
476 cond_resched(); 480 cond_resched();
@@ -481,25 +485,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
481 return -ETIMEDOUT; 485 return -ETIMEDOUT;
482 } 486 }
483 487
484 ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); 488 ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
485 ecc[0] = (uint8_t) (ecc_tmp >> 0); 489 ecc[0] = (uint8_t) (ecc_tmp >> 0);
486 ecc[1] = (uint8_t) (ecc_tmp >> 8); 490 ecc[1] = (uint8_t) (ecc_tmp >> 8);
487 ecc[2] = (uint8_t) (ecc_tmp >> 16); 491 ecc[2] = (uint8_t) (ecc_tmp >> 16);
488 ecc[3] = (uint8_t) (ecc_tmp >> 24); 492 ecc[3] = (uint8_t) (ecc_tmp >> 24);
489 493
490 ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2)); 494 ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
491 ecc[4] = (uint8_t) (ecc_tmp >> 0); 495 ecc[4] = (uint8_t) (ecc_tmp >> 0);
492 ecc[5] = (uint8_t) (ecc_tmp >> 8); 496 ecc[5] = (uint8_t) (ecc_tmp >> 8);
493 ecc[6] = (uint8_t) (ecc_tmp >> 16); 497 ecc[6] = (uint8_t) (ecc_tmp >> 16);
494 ecc[7] = (uint8_t) (ecc_tmp >> 24); 498 ecc[7] = (uint8_t) (ecc_tmp >> 24);
495 499
496 ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3)); 500 ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
497 ecc[8] = (uint8_t) (ecc_tmp >> 0); 501 ecc[8] = (uint8_t) (ecc_tmp >> 0);
498 ecc[9] = (uint8_t) (ecc_tmp >> 8); 502 ecc[9] = (uint8_t) (ecc_tmp >> 8);
499 ecc[10] = (uint8_t) (ecc_tmp >> 16); 503 ecc[10] = (uint8_t) (ecc_tmp >> 16);
500 ecc[11] = (uint8_t) (ecc_tmp >> 24); 504 ecc[11] = (uint8_t) (ecc_tmp >> 24);
501 505
502 ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS)); 506 ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
503 ecc[12] = (uint8_t) (ecc_tmp >> 16); 507 ecc[12] = (uint8_t) (ecc_tmp >> 16);
504 508
505 return 0; 509 return 0;
@@ -519,7 +523,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
519 uint32_t bank = host->bank; 523 uint32_t bank = host->bank;
520 uint32_t ecc_tmp; 524 uint32_t ecc_tmp;
521 525
522 ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); 526 ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
523 ecc[0] = (uint8_t) (ecc_tmp >> 0); 527 ecc[0] = (uint8_t) (ecc_tmp >> 0);
524 ecc[1] = (uint8_t) (ecc_tmp >> 8); 528 ecc[1] = (uint8_t) (ecc_tmp >> 8);
525 ecc[2] = (uint8_t) (ecc_tmp >> 16); 529 ecc[2] = (uint8_t) (ecc_tmp >> 16);
@@ -628,10 +632,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
628 uint32_t *p = (uint32_t *)buf; 632 uint32_t *p = (uint32_t *)buf;
629 len = len >> 2; 633 len = len >> 2;
630 for (i = 0; i < len; i++) 634 for (i = 0; i < len; i++)
631 writel(p[i], chip->IO_ADDR_W); 635 writel_relaxed(p[i], chip->IO_ADDR_W);
632 } else { 636 } else {
633 for (i = 0; i < len; i++) 637 for (i = 0; i < len; i++)
634 writeb(buf[i], chip->IO_ADDR_W); 638 writeb_relaxed(buf[i], chip->IO_ADDR_W);
635 } 639 }
636} 640}
637 641
@@ -651,10 +655,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
651 uint32_t *p = (uint32_t *)buf; 655 uint32_t *p = (uint32_t *)buf;
652 len = len >> 2; 656 len = len >> 2;
653 for (i = 0; i < len; i++) 657 for (i = 0; i < len; i++)
654 p[i] = readl(chip->IO_ADDR_R); 658 p[i] = readl_relaxed(chip->IO_ADDR_R);
655 } else { 659 } else {
656 for (i = 0; i < len; i++) 660 for (i = 0; i < len; i++)
657 buf[i] = readb(chip->IO_ADDR_R); 661 buf[i] = readb_relaxed(chip->IO_ADDR_R);
658 } 662 }
659} 663}
660 664
@@ -783,7 +787,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
783 uint32_t num_err, i; 787 uint32_t num_err, i;
784 uint32_t ecc1, ecc2, ecc3, ecc4; 788 uint32_t ecc1, ecc2, ecc3, ecc4;
785 789
786 num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; 790 num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
787 791
788 /* no bit flipping */ 792 /* no bit flipping */
789 if (likely(num_err == 0)) 793 if (likely(num_err == 0))
@@ -826,10 +830,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
826 * uint64_t array and error offset indexes are populated in err_idx 830 * uint64_t array and error offset indexes are populated in err_idx
827 * array 831 * array
828 */ 832 */
829 ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1)); 833 ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
830 ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2)); 834 ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
831 ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3)); 835 ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
832 ecc4 = readl(FSMC_NAND_REG(regs, bank, STS)); 836 ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
833 837
834 err_idx[0] = (ecc1 >> 0) & 0x1FFF; 838 err_idx[0] = (ecc1 >> 0) & 0x1FFF;
835 err_idx[1] = (ecc1 >> 13) & 0x1FFF; 839 err_idx[1] = (ecc1 >> 13) & 0x1FFF;