Merge branch 'master' of git://git.denx.de/u-boot-spi
[oweals/u-boot.git] / drivers / mtd / nand / raw / pxa3xx_nand.c
index 454597355b7959c4897c2e28bade630693869535..4d2712df4c7a483243943171277e1f80dda15698 100644 (file)
@@ -327,14 +327,14 @@ static struct nand_ecclayout ecc_layout_2KB_bch4bit = {
 static struct nand_ecclayout ecc_layout_2KB_bch8bit = {
        .eccbytes = 64,
        .eccpos = {
-               64,  65,  66,  67,  68,  69,  70,  71,
-               72,  73,  74,  75,  76,  77,  78,  79,
-               80,  81,  82,  83,  84,  85,  86,  87,
-               88,  89,  90,  91,  92,  93,  94,  95,
-               96,  97,  98,  99,  100, 101, 102, 103,
-               104, 105, 106, 107, 108, 109, 110, 111,
-               112, 113, 114, 115, 116, 117, 118, 119,
-               120, 121, 122, 123, 124, 125, 126, 127},
+               32, 33, 34, 35, 36, 37, 38, 39,
+               40, 41, 42, 43, 44, 45, 46, 47,
+               48, 49, 50, 51, 52, 53, 54, 55,
+               56, 57, 58, 59, 60, 61, 62, 63,
+               64, 65, 66, 67, 68, 69, 70, 71,
+               72, 73, 74, 75, 76, 77, 78, 79,
+               80, 81, 82, 83, 84, 85, 86, 87,
+               88, 89, 90, 91, 92, 93, 94, 95},
        .oobfree = { {1, 4}, {6, 26} }
 };
 
@@ -1237,6 +1237,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
 {
        struct pxa3xx_nand_host *host = nand_get_controller_data(chip);
        struct pxa3xx_nand_info *info = host->info_data;
+       int bf;
 
        chip->read_buf(mtd, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1244,12 +1245,30 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
        if (info->retcode == ERR_CORERR && info->use_ecc) {
                mtd->ecc_stats.corrected += info->ecc_err_cnt;
 
-       } else if (info->retcode == ERR_UNCORERR) {
+       } else if (info->retcode == ERR_UNCORERR && info->ecc_bch) {
                /*
-                * for blank page (all 0xff), HW will calculate its ECC as
-                * 0, which is different from the ECC information within
-                * OOB, ignore such uncorrectable errors
+                * Empty pages will trigger uncorrectable errors. Re-read the
+                * entire page in raw mode and check for bits not being "1".
+                * If there are more than the supported strength, then it means
+                * this is an actual uncorrectable error.
                 */
+               chip->ecc.read_page_raw(mtd, chip, buf, oob_required, page);
+               bf = nand_check_erased_ecc_chunk(buf, mtd->writesize,
+                                                chip->oob_poi, mtd->oobsize,
+                                                NULL, 0, chip->ecc.strength);
+               if (bf < 0) {
+                       mtd->ecc_stats.failed++;
+               } else if (bf) {
+                       mtd->ecc_stats.corrected += bf;
+                       info->max_bitflips = max_t(unsigned int,
+                                                  info->max_bitflips, bf);
+                       info->retcode = ERR_CORERR;
+               } else {
+                       info->retcode = ERR_NONE;
+               }
+
+       } else if (info->retcode == ERR_UNCORERR && !info->ecc_bch) {
+               /* Raw read is not supported with Hamming ECC engine */
                if (is_buf_blank(buf, mtd->writesize))
                        info->retcode = ERR_NONE;
                else
@@ -1572,7 +1591,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
                info->chunk_size = 1024;
                info->spare_size = 0;
                info->last_chunk_size = 1024;
-               info->last_spare_size = 64;
+               info->last_spare_size = 32;
                info->ecc_size = 32;
                ecc->mode = NAND_ECC_HW;
                ecc->size = info->chunk_size;