aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekon Gupta <pekon@ti.com>2014-02-17 02:41:23 -0500
committerBrian Norris <computersforpeace@gmail.com>2014-02-23 17:49:56 -0500
commiteae39cb4934d3daab3ec828c5201c955b2e56af9 (patch)
treef8bb7cc273f5d0db9e41425568ce16cc4394f145
parent28fa65e643ed7cf753e89db20745e264c41f3682 (diff)
mtd: nand: omap: fix ecclayout to be in sync with u-boot NAND driver
Fixes: commit a919e51161b58ed7e6e663daba99ab7d558808f3 mtd: nand: omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in device_probe Fixes ecclayout mismatch introduced in above commit for following ecc-schemes: - OMAP_ECC_BCH4_CODE_HW_DETECTION_SW - OMAP_ECC_BCH8_CODE_HW_DETECTION_SW However, this patch also touches other ecc-schemes as the fix required refactoring common code, into ecc-scheme specific code. This patch aligns ecc-layout for below ecc-schemes as per reference [1],[2],[3] +---+------------+-------------++-------------+-------------+ |OOB|BCH8_CODE_HW|BCH8_CODE_HW_||HAM1_CODE_HW |HAM1_CODE_HW | |pos| | DETECTION_SW||(x8 device) |(x16 device) | +---+------------+-------------++-------------+-------------+ | 0 |BADBLK_MARK | BADBLK_MARK || BADBLK_MARK | BADBLK_MARK | | 1 |BADBLK_MARK | BADBLK_MARK || eccpos[0] | BADBLK_MARK | | 2 | eccpos[0] | eccpos[0] || eccpos[1] | eccpos[0] | | 3 | eccpos[1] | eccpos[1] || eccpos[2] | eccpos[1] | | 4 | eccpos[2] | eccpos[2] || eccpos[3] | eccpos[2] | | 5 | eccpos[3] | eccpos[3] || eccpos[4] | eccpos[3] | | 6 | eccpos[4] | eccpos[4] || eccpos[5] | eccpos[4] | | 7 | eccpos[5] | eccpos[5] || eccpos[6] | eccpos[5] | | 8 | eccpos[6] | eccpos[6] || eccpos[7] | eccpos[6] | | 9 | eccpos[7] | eccpos[7] || eccpos[8] | eccpos[7] | |10 | eccpos[8] | eccpos[8] || eccpos[9] | eccpos[8] | |11 | eccpos[9] | eccpos[9] || eccpos[10] | eccpos[9] | |12 | eccpos[10] | eccpos[10] || eccpos[11] | eccpos[10] | |13 | eccpos[11] | eccpos[11] || oobfree[0] | eccpos[11] | |14 | eccpos[12] | eccpos[12] || oobfree[1] | oobfree[0] | |15 | eccpos[13] | <reserved> || oobfree[2] | oobfree[1] | +---+------------+-------------++-------------+-------------+ |16 | eccpos[14] | eccpos[13] || oobfree[3] | oobfree[2] | |...| [...] | [...] || [...] | [...] | |56 | eccpos[54] | eccpos[51] || oobfree[43] | oobfree[42] | |57 | eccpos[55] | <reserved> || oobfree[44] | oobfree[43] | +===+============+=============+==============+=============+ |58 | oobfree[0] | oobfree[0] || oobfree[45] | oobfree[44] | |59 | oobfree[1] | oobfree[1] || oobfree[46] | oobfree[45] | |60 | oobfree[2] | oobfree[2] || oobfree[47] | oobfree[46] | |61 | oobfree[3] | oobfree[3] || oobfree[48] | oobfree[47] | |62 | oobfree[4] | oobfree[4] || oobfree[49] | oobfree[48] | |63 | oobfree[5] | oobfree[5] || oobfree[50] | oobfree[49] | +---+------------+-------------+--------------+-------------+ [1] ecc-layout expected by ROM code, as specified in SoC TRM under: Chapter="Initialization" Section="Device Initialization by ROM code" Sub-Section="Memory Booting" Heading="NAND" Figure="ECC Locations in NAND Spare Areas" [2] ecc-layout updates in u-boot http://lists.denx.de/pipermail/u-boot/2013-November/167551.html [3] u-boot configurations to match above ecc-layout are documented at https://processors.wiki.ti.com/index.php/Linux_Core_NAND_User%27s_Guide CC: <stable@vger.kernel.org> # 3.13.x+ Reported-by: Enric Balletbo Serra <eballetbo@iseebcn.com> Tested-by: Enric Balletbo i Serra <eballetbo@gmail.com> Tested-by: Stefan Roese <sr@denx.de> Signed-off-by: Pekon Gupta <pekon@ti.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/nand/omap2.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index ef4190a02b7b..34ef941e3bfb 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1633,6 +1633,7 @@ static int omap_nand_probe(struct platform_device *pdev)
1633 int i; 1633 int i;
1634 dma_cap_mask_t mask; 1634 dma_cap_mask_t mask;
1635 unsigned sig; 1635 unsigned sig;
1636 unsigned oob_index;
1636 struct resource *res; 1637 struct resource *res;
1637 struct mtd_part_parser_data ppdata = {}; 1638 struct mtd_part_parser_data ppdata = {};
1638 1639
@@ -1826,9 +1827,11 @@ static int omap_nand_probe(struct platform_device *pdev)
1826 (mtd->writesize / 1827 (mtd->writesize /
1827 nand_chip->ecc.size); 1828 nand_chip->ecc.size);
1828 if (nand_chip->options & NAND_BUSWIDTH_16) 1829 if (nand_chip->options & NAND_BUSWIDTH_16)
1829 ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; 1830 oob_index = BADBLOCK_MARKER_LENGTH;
1830 else 1831 else
1831 ecclayout->eccpos[0] = 1; 1832 oob_index = 1;
1833 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1834 ecclayout->eccpos[i] = oob_index;
1832 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1835 ecclayout->oobfree->offset = ecclayout->eccpos[0] +
1833 ecclayout->eccbytes; 1836 ecclayout->eccbytes;
1834 break; 1837 break;
@@ -1847,7 +1850,12 @@ static int omap_nand_probe(struct platform_device *pdev)
1847 ecclayout->eccbytes = nand_chip->ecc.bytes * 1850 ecclayout->eccbytes = nand_chip->ecc.bytes *
1848 (mtd->writesize / 1851 (mtd->writesize /
1849 nand_chip->ecc.size); 1852 nand_chip->ecc.size);
1850 ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; 1853 oob_index = BADBLOCK_MARKER_LENGTH;
1854 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) {
1855 ecclayout->eccpos[i] = oob_index;
1856 if (((i + 1) % nand_chip->ecc.bytes) == 0)
1857 oob_index++;
1858 }
1851 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1859 ecclayout->oobfree->offset = ecclayout->eccpos[0] +
1852 ecclayout->eccbytes; 1860 ecclayout->eccbytes;
1853 /* software bch library is used for locating errors */ 1861 /* software bch library is used for locating errors */
@@ -1883,7 +1891,9 @@ static int omap_nand_probe(struct platform_device *pdev)
1883 ecclayout->eccbytes = nand_chip->ecc.bytes * 1891 ecclayout->eccbytes = nand_chip->ecc.bytes *
1884 (mtd->writesize / 1892 (mtd->writesize /
1885 nand_chip->ecc.size); 1893 nand_chip->ecc.size);
1886 ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; 1894 oob_index = BADBLOCK_MARKER_LENGTH;
1895 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1896 ecclayout->eccpos[i] = oob_index;
1887 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1897 ecclayout->oobfree->offset = ecclayout->eccpos[0] +
1888 ecclayout->eccbytes; 1898 ecclayout->eccbytes;
1889 /* This ECC scheme requires ELM H/W block */ 1899 /* This ECC scheme requires ELM H/W block */
@@ -1913,7 +1923,12 @@ static int omap_nand_probe(struct platform_device *pdev)
1913 ecclayout->eccbytes = nand_chip->ecc.bytes * 1923 ecclayout->eccbytes = nand_chip->ecc.bytes *
1914 (mtd->writesize / 1924 (mtd->writesize /
1915 nand_chip->ecc.size); 1925 nand_chip->ecc.size);
1916 ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; 1926 oob_index = BADBLOCK_MARKER_LENGTH;
1927 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) {
1928 ecclayout->eccpos[i] = oob_index;
1929 if (((i + 1) % nand_chip->ecc.bytes) == 0)
1930 oob_index++;
1931 }
1917 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1932 ecclayout->oobfree->offset = ecclayout->eccpos[0] +
1918 ecclayout->eccbytes; 1933 ecclayout->eccbytes;
1919 /* software bch library is used for locating errors */ 1934 /* software bch library is used for locating errors */
@@ -1956,7 +1971,9 @@ static int omap_nand_probe(struct platform_device *pdev)
1956 ecclayout->eccbytes = nand_chip->ecc.bytes * 1971 ecclayout->eccbytes = nand_chip->ecc.bytes *
1957 (mtd->writesize / 1972 (mtd->writesize /
1958 nand_chip->ecc.size); 1973 nand_chip->ecc.size);
1959 ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; 1974 oob_index = BADBLOCK_MARKER_LENGTH;
1975 for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1976 ecclayout->eccpos[i] = oob_index;
1960 ecclayout->oobfree->offset = ecclayout->eccpos[0] + 1977 ecclayout->oobfree->offset = ecclayout->eccpos[0] +
1961 ecclayout->eccbytes; 1978 ecclayout->eccbytes;
1962 break; 1979 break;
@@ -1975,8 +1992,6 @@ static int omap_nand_probe(struct platform_device *pdev)
1975 /* populate remaining ECC layout data */ 1992 /* populate remaining ECC layout data */
1976 ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH + 1993 ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH +
1977 ecclayout->eccbytes); 1994 ecclayout->eccbytes);
1978 for (i = 1; i < ecclayout->eccbytes; i++)
1979 ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
1980 /* check if NAND device's OOB is enough to store ECC signatures */ 1995 /* check if NAND device's OOB is enough to store ECC signatures */
1981 if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { 1996 if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
1982 pr_err("not enough OOB bytes required = %d, available=%d\n", 1997 pr_err("not enough OOB bytes required = %d, available=%d\n",