aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/nand_base.c99
1 files changed, 95 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c3afccde8a2..d902370df3e0 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -748,6 +748,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
748 * @mtd: mtd info structure 748 * @mtd: mtd info structure
749 * @chip: nand chip info structure 749 * @chip: nand chip info structure
750 * @buf: buffer to store read data 750 * @buf: buffer to store read data
751 *
752 * Not for syndrome calculating ecc controllers, which use a special oob layout
751 */ 753 */
752static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 754static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
753 uint8_t *buf) 755 uint8_t *buf)
@@ -758,6 +760,47 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
758} 760}
759 761
760/** 762/**
763 * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
764 * @mtd: mtd info structure
765 * @chip: nand chip info structure
766 * @buf: buffer to store read data
767 *
768 * We need a special oob layout and handling even when OOB isn't used.
769 */
770static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
771 uint8_t *buf)
772{
773 int eccsize = chip->ecc.size;
774 int eccbytes = chip->ecc.bytes;
775 uint8_t *oob = chip->oob_poi;
776 int steps, size;
777
778 for (steps = chip->ecc.steps; steps > 0; steps--) {
779 chip->read_buf(mtd, buf, eccsize);
780 buf += eccsize;
781
782 if (chip->ecc.prepad) {
783 chip->read_buf(mtd, oob, chip->ecc.prepad);
784 oob += chip->ecc.prepad;
785 }
786
787 chip->read_buf(mtd, oob, eccbytes);
788 oob += eccbytes;
789
790 if (chip->ecc.postpad) {
791 chip->read_buf(mtd, oob, chip->ecc.postpad);
792 oob += chip->ecc.postpad;
793 }
794 }
795
796 size = mtd->oobsize - (oob - chip->oob_poi);
797 if (size)
798 chip->read_buf(mtd, oob, size);
799
800 return 0;
801}
802
803/**
761 * nand_read_page_swecc - [REPLACABLE] software ecc based page read function 804 * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
762 * @mtd: mtd info structure 805 * @mtd: mtd info structure
763 * @chip: nand chip info structure 806 * @chip: nand chip info structure
@@ -1482,6 +1525,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1482 * @mtd: mtd info structure 1525 * @mtd: mtd info structure
1483 * @chip: nand chip info structure 1526 * @chip: nand chip info structure
1484 * @buf: data buffer 1527 * @buf: data buffer
1528 *
1529 * Not for syndrome calculating ecc controllers, which use a special oob layout
1485 */ 1530 */
1486static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 1531static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1487 const uint8_t *buf) 1532 const uint8_t *buf)
@@ -1491,6 +1536,44 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1491} 1536}
1492 1537
1493/** 1538/**
1539 * nand_write_page_raw_syndrome - [Intern] raw page write function
1540 * @mtd: mtd info structure
1541 * @chip: nand chip info structure
1542 * @buf: data buffer
1543 *
1544 * We need a special oob layout and handling even when ECC isn't checked.
1545 */
1546static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1547 const uint8_t *buf)
1548{
1549 int eccsize = chip->ecc.size;
1550 int eccbytes = chip->ecc.bytes;
1551 uint8_t *oob = chip->oob_poi;
1552 int steps, size;
1553
1554 for (steps = chip->ecc.steps; steps > 0; steps--) {
1555 chip->write_buf(mtd, buf, eccsize);
1556 buf += eccsize;
1557
1558 if (chip->ecc.prepad) {
1559 chip->write_buf(mtd, oob, chip->ecc.prepad);
1560 oob += chip->ecc.prepad;
1561 }
1562
1563 chip->read_buf(mtd, oob, eccbytes);
1564 oob += eccbytes;
1565
1566 if (chip->ecc.postpad) {
1567 chip->write_buf(mtd, oob, chip->ecc.postpad);
1568 oob += chip->ecc.postpad;
1569 }
1570 }
1571
1572 size = mtd->oobsize - (oob - chip->oob_poi);
1573 if (size)
1574 chip->write_buf(mtd, oob, size);
1575}
1576/**
1494 * nand_write_page_swecc - [REPLACABLE] software ecc based page write function 1577 * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
1495 * @mtd: mtd info structure 1578 * @mtd: mtd info structure
1496 * @chip: nand chip info structure 1579 * @chip: nand chip info structure
@@ -2569,10 +2652,6 @@ int nand_scan_tail(struct mtd_info *mtd)
2569 * check ECC mode, default to software if 3byte/512byte hardware ECC is 2652 * check ECC mode, default to software if 3byte/512byte hardware ECC is
2570 * selected and we have 256 byte pagesize fallback to software ECC 2653 * selected and we have 256 byte pagesize fallback to software ECC
2571 */ 2654 */
2572 if (!chip->ecc.read_page_raw)
2573 chip->ecc.read_page_raw = nand_read_page_raw;
2574 if (!chip->ecc.write_page_raw)
2575 chip->ecc.write_page_raw = nand_write_page_raw;
2576 2655
2577 switch (chip->ecc.mode) { 2656 switch (chip->ecc.mode) {
2578 case NAND_ECC_HW: 2657 case NAND_ECC_HW:
@@ -2581,6 +2660,10 @@ int nand_scan_tail(struct mtd_info *mtd)
2581 chip->ecc.read_page = nand_read_page_hwecc; 2660 chip->ecc.read_page = nand_read_page_hwecc;
2582 if (!chip->ecc.write_page) 2661 if (!chip->ecc.write_page)
2583 chip->ecc.write_page = nand_write_page_hwecc; 2662 chip->ecc.write_page = nand_write_page_hwecc;
2663 if (!chip->ecc.read_page_raw)
2664 chip->ecc.read_page_raw = nand_read_page_raw;
2665 if (!chip->ecc.write_page_raw)
2666 chip->ecc.write_page_raw = nand_write_page_raw;
2584 if (!chip->ecc.read_oob) 2667 if (!chip->ecc.read_oob)
2585 chip->ecc.read_oob = nand_read_oob_std; 2668 chip->ecc.read_oob = nand_read_oob_std;
2586 if (!chip->ecc.write_oob) 2669 if (!chip->ecc.write_oob)
@@ -2602,6 +2685,10 @@ int nand_scan_tail(struct mtd_info *mtd)
2602 chip->ecc.read_page = nand_read_page_syndrome; 2685 chip->ecc.read_page = nand_read_page_syndrome;
2603 if (!chip->ecc.write_page) 2686 if (!chip->ecc.write_page)
2604 chip->ecc.write_page = nand_write_page_syndrome; 2687 chip->ecc.write_page = nand_write_page_syndrome;
2688 if (!chip->ecc.read_page_raw)
2689 chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
2690 if (!chip->ecc.write_page_raw)
2691 chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
2605 if (!chip->ecc.read_oob) 2692 if (!chip->ecc.read_oob)
2606 chip->ecc.read_oob = nand_read_oob_syndrome; 2693 chip->ecc.read_oob = nand_read_oob_syndrome;
2607 if (!chip->ecc.write_oob) 2694 if (!chip->ecc.write_oob)
@@ -2620,6 +2707,8 @@ int nand_scan_tail(struct mtd_info *mtd)
2620 chip->ecc.read_page = nand_read_page_swecc; 2707 chip->ecc.read_page = nand_read_page_swecc;
2621 chip->ecc.read_subpage = nand_read_subpage; 2708 chip->ecc.read_subpage = nand_read_subpage;
2622 chip->ecc.write_page = nand_write_page_swecc; 2709 chip->ecc.write_page = nand_write_page_swecc;
2710 chip->ecc.read_page_raw = nand_read_page_raw;
2711 chip->ecc.write_page_raw = nand_write_page_raw;
2623 chip->ecc.read_oob = nand_read_oob_std; 2712 chip->ecc.read_oob = nand_read_oob_std;
2624 chip->ecc.write_oob = nand_write_oob_std; 2713 chip->ecc.write_oob = nand_write_oob_std;
2625 chip->ecc.size = 256; 2714 chip->ecc.size = 256;
@@ -2632,6 +2721,8 @@ int nand_scan_tail(struct mtd_info *mtd)
2632 chip->ecc.read_page = nand_read_page_raw; 2721 chip->ecc.read_page = nand_read_page_raw;
2633 chip->ecc.write_page = nand_write_page_raw; 2722 chip->ecc.write_page = nand_write_page_raw;
2634 chip->ecc.read_oob = nand_read_oob_std; 2723 chip->ecc.read_oob = nand_read_oob_std;
2724 chip->ecc.read_page_raw = nand_read_page_raw;
2725 chip->ecc.write_page_raw = nand_write_page_raw;
2635 chip->ecc.write_oob = nand_write_oob_std; 2726 chip->ecc.write_oob = nand_write_oob_std;
2636 chip->ecc.size = mtd->writesize; 2727 chip->ecc.size = mtd->writesize;
2637 chip->ecc.bytes = 0; 2728 chip->ecc.bytes = 0;