mtd: atmel_nand: according to pmecc version to perform 0xff page correction
authorWu, Josh <Josh.wu@atmel.com>
Fri, 16 Jan 2015 03:54:46 +0000 (11:54 +0800)
committerAndreas Bießmann <andreas.devel@googlemail.com>
Sat, 7 Feb 2015 22:42:57 +0000 (23:42 +0100)
As the PMECC hardware has different version. In SAMA5D4 chip, the PMECC ip
can generate 0xff pmecc ECC value for all 0xff sector.

According to this, add PMECC version check, if it's SAMA5D4 then we always
let PMECC hardware to correct it.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
Acked-by: Bo Shen <voice.shen@atmel.com>
Acked-by: Andreas Bießmann <andreas.devel@googlemail.com>
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/atmel_nand_ecc.h

index 620b6e8ff9a4cfac6745eb6477718ce14a93d05f..b16e3aa15749428e1a9937f98767ae662b55acb6 100644 (file)
@@ -44,6 +44,7 @@ struct atmel_nand_host {
        u8              pmecc_corr_cap;
        u16             pmecc_sector_size;
        u32             pmecc_index_table_offset;
+       u32             pmecc_version;
 
        int             pmecc_bytes_per_sector;
        int             pmecc_sector_number;
@@ -486,6 +487,10 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
        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)
@@ -961,6 +966,10 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
        nand->ecc.write_page = atmel_nand_pmecc_write_page;
        nand->ecc.strength = cap;
 
+       /* Check the PMECC ip version */
+       host->pmecc_version = pmecc_readl(host->pmerrloc, version);
+       dev_dbg(host->dev, "PMECC IP version is: %x\n", host->pmecc_version);
+
        atmel_pmecc_core_init(mtd);
 
        return 0;
index eac860d13ca73638131f175fd28d6a38e47d738b..b2d2682a8835235d1a48e2bf67817cf15f0c3eb3 100644 (file)
@@ -123,6 +123,20 @@ struct pmecc_errloc_regs {
        u32 sigma[25];  /* 0x28-0x88 Error Location Sigma Registers */
        u32 el[24];     /* 0x8C-0xE8 Error Location Registers */
        u32 reserved1[5];       /* 0xEC-0xFC Reserved */
+
+       /*
+        * 0x100-0x1F8:
+        *   Reserved for AT91SAM9X5, AT91SAM9N12.
+        *   HSMC registers for SAMA5D3, SAMA5D4.
+        */
+       u32 reserved2[63];
+
+       /*
+        * 0x1FC:
+        *   PMECC version for AT91SAM9X5, AT91SAM9N12.
+        *   HSMC version for SAMA5D3, SAMA5D4. Can refer as PMECC version.
+        */
+       u32 version;
 };
 
 /* For Error Location Configuration Register */
@@ -137,6 +151,12 @@ struct pmecc_errloc_regs {
 #define                PMERRLOC_ERR_NUM_MASK           (0x1f << 8)
 #define                PMERRLOC_CALC_DONE              (1 << 0)
 
+/* PMECC IP version */
+#define PMECC_VERSION_SAMA5D4                  0x113
+#define PMECC_VERSION_SAMA5D3                  0x112
+#define PMECC_VERSION_AT91SAM9N12              0x102
+#define PMECC_VERSION_AT91SAM9X5               0x101
+
 /* Galois field dimension */
 #define PMECC_GF_DIMENSION_13                  13
 #define PMECC_GF_DIMENSION_14                  14