Merge tag 'u-boot-stm32-20211012' of https://source.denx.de/u-boot/custodians/u-boot-stm
[platform/kernel/u-boot.git] / drivers / mtd / nand / raw / atmel_nand.c
index abc432c..06bf5ac 100644 (file)
@@ -24,6 +24,7 @@
 #include <nand.h>
 #include <watchdog.h>
 #include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/rawnand.h>
 
 #ifdef CONFIG_ATMEL_NAND_HWECC
 
@@ -493,21 +494,9 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
 {
        struct nand_chip *nand_chip = mtd_to_nand(mtd);
        struct atmel_nand_host *host = nand_get_controller_data(nand_chip);
-       int i, err_nbr, eccbytes;
-       uint8_t *buf_pos;
-
-       /* SAMA5D4 PMECC IP can correct errors for all 0xff page */
-       if (host->pmecc_version >= PMECC_VERSION_SAMA5D4)
-               goto normal_check;
-
-       eccbytes = nand_chip->ecc.bytes;
-       for (i = 0; i < eccbytes; i++)
-               if (ecc[i] != 0xff)
-                       goto normal_check;
-       /* Erased page, return OK */
-       return 0;
+       int i, err_nbr;
+       u8 *buf_pos, *ecc_pos;
 
-normal_check:
        for (i = 0; i < host->pmecc_sector_number; i++) {
                err_nbr = 0;
                if (pmecc_stat & 0x1) {
@@ -518,15 +507,26 @@ normal_check:
                        pmecc_get_sigma(mtd);
 
                        err_nbr = pmecc_err_location(mtd);
-                       if (err_nbr == -1) {
+                       if (err_nbr >= 0) {
+                               pmecc_correct_data(mtd, buf_pos, ecc, i,
+                                                  host->pmecc_bytes_per_sector,
+                                                  err_nbr);
+                       } else if (host->pmecc_version < PMECC_VERSION_SAMA5D4) {
+                               ecc_pos = ecc + i * host->pmecc_bytes_per_sector;
+
+                               err_nbr = nand_check_erased_ecc_chunk(
+                                       buf_pos, host->pmecc_sector_size,
+                                       ecc_pos, host->pmecc_bytes_per_sector,
+                                       NULL, 0, host->pmecc_corr_cap);
+                       }
+
+                       if (err_nbr < 0) {
                                dev_err(mtd->dev, "PMECC: Too many errors\n");
                                mtd->ecc_stats.failed++;
                                return -EBADMSG;
-                       } else {
-                               pmecc_correct_data(mtd, buf_pos, ecc, i,
-                                       host->pmecc_bytes_per_sector, err_nbr);
-                               mtd->ecc_stats.corrected += err_nbr;
                        }
+
+                       mtd->ecc_stats.corrected += err_nbr;
                }
                pmecc_stat >>= 1;
        }