summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2015-03-02 14:55:24 +0100
committerStefan Agner <stefan.agner@toradex.com>2015-06-22 10:03:29 +0200
commitae05e71a1e1663649022e0893b90228cdb559c4d (patch)
tree92701b045aa8662a930f4e697a965d48662d6cc5
parentd8845554ca2a410c59f72c08167c7238ce2113d9 (diff)
mtd: fsl_nfc: operate with 60-byte hardware ECCtoradex_vf_3.18-next
Use 60-byte hardware ECC which allows up to 32-bit errors corrected per 2k page. This is required for newer Macronix SLC NAND flashes. Beside that, rename the driver to vf610_nfc, which is the new driver name used in the upstream driver. This makes this 3.18 kernel compatible with the new ECC format used in the V2.4 Beta 1 release/U-Boot 2015.04.
-rw-r--r--drivers/mtd/nand/fsl_nfc.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/drivers/mtd/nand/fsl_nfc.c b/drivers/mtd/nand/fsl_nfc.c
index bfc7b7b7190a..d9ae19f28c62 100644
--- a/drivers/mtd/nand/fsl_nfc.c
+++ b/drivers/mtd/nand/fsl_nfc.c
@@ -33,7 +33,7 @@
#include <linux/slab.h>
#include <linux/of_mtd.h>
-#define DRV_NAME "fsl_nfc"
+#define DRV_NAME "vf610_nfc"
/* Register Offsets */
#define NFC_FLASH_CMD1 0x3F00
@@ -70,6 +70,7 @@
/* NFC ECC mode define */
#define ECC_BYPASS 0
#define ECC_45_BYTE 6
+#define ECC_60_BYTE 7
/*** Register Mask and bit definitions */
@@ -155,15 +156,15 @@ struct fsl_nfc {
};
#define mtd_to_nfc(_mtd) container_of(_mtd, struct fsl_nfc, mtd)
-static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
-static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
+static u8 bbt_pattern[] = {'B', 'b', 't' };
+static u8 mirror_pattern[] = {'t', 'b', 'B' };
static struct nand_bbt_descr bbt_main_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
NAND_BBT_2BIT | NAND_BBT_VERSION,
- .offs = 11,
- .len = 4,
- .veroffs = 15,
+ .offs = 0,
+ .len = 3,
+ .veroffs = 3,
.maxblocks = 4,
.pattern = bbt_pattern,
};
@@ -171,13 +172,14 @@ static struct nand_bbt_descr bbt_main_descr = {
static struct nand_bbt_descr bbt_mirror_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
NAND_BBT_2BIT | NAND_BBT_VERSION,
- .offs = 11,
- .len = 4,
- .veroffs = 15,
+ .offs = 0,
+ .len = 3,
+ .veroffs = 3,
.maxblocks = 4,
.pattern = mirror_pattern,
};
+#if 0
static struct nand_ecclayout nfc_ecc45 = {
.eccbytes = 45,
.eccpos = {19, 20, 21, 22, 23,
@@ -190,6 +192,22 @@ static struct nand_ecclayout nfc_ecc45 = {
{.offset = 8,
.length = 11} }
};
+#endif
+
+static struct nand_ecclayout nfc_ecc60 = {
+ .eccbytes = 60,
+ .eccpos = { 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 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 },
+ .oobfree = {
+ {.offset = 2,
+ .length = 2} }
+};
static u32 nfc_read(struct mtd_info *mtd, uint reg)
{
@@ -608,10 +626,10 @@ static int nfc_init_controller(struct mtd_info *mtd, struct nfc_config *cfg, int
nfc_write(mtd, NFC_SECTOR_SIZE, page_sz);
if (cfg->hardware_ecc) {
- /* set ECC mode to 45 bytes OOB with 24 bits correction */
+ /* set ECC mode to 60 bytes OOB with 32 bits correction */
nfc_set_field(mtd, NFC_FLASH_CONFIG,
CONFIG_ECC_MODE_MASK,
- CONFIG_ECC_MODE_SHIFT, ECC_45_BYTE);
+ CONFIG_ECC_MODE_SHIFT, ECC_60_BYTE);
/* Enable ECC_STATUS */
nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
@@ -742,7 +760,7 @@ static int nfc_probe(struct platform_device *pdev)
goto error;
}
- chip->ecc.layout = &nfc_ecc45;
+ chip->ecc.layout = &nfc_ecc60;
/* propagate ecc.layout to mtd_info */
mtd->ecclayout = chip->ecc.layout;
@@ -751,14 +769,14 @@ static int nfc_probe(struct platform_device *pdev)
chip->ecc.correct = nfc_correct_data;
chip->ecc.mode = NAND_ECC_HW;
- chip->ecc.bytes = 45;
+ chip->ecc.bytes = 60;
chip->ecc.size = PAGE_2K;
- chip->ecc.strength = 24;
+ chip->ecc.strength = 32;
- /* set ECC mode to 45 bytes OOB with 24 bits correction */
+ /* set ECC mode to 60 bytes OOB with 32 bits correction */
nfc_set_field(mtd, NFC_FLASH_CONFIG,
CONFIG_ECC_MODE_MASK,
- CONFIG_ECC_MODE_SHIFT, ECC_45_BYTE);
+ CONFIG_ECC_MODE_SHIFT, ECC_60_BYTE);
}
/* second phase scan */