From 7604a3f920031aa6f3426eedf44494b69ae291e1 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 28 Aug 2013 14:54:26 +0000 Subject: MTD: atmel_nand: support for software BCH ECC Add possible to use software BCH ECC for atmel nand driver Signed-off-by: Bo Shen --- drivers/mtd/nand/atmel_nand.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/mtd/nand/atmel_nand.c') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index da83f06e473..10011c6a8f4 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1178,7 +1178,11 @@ int atmel_nand_chip_init(int devnum, ulong base_addr) mtd->priv = nand; nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr; +#ifdef CONFIG_NAND_ECC_BCH + nand->ecc.mode = NAND_ECC_SOFT_BCH; +#else nand->ecc.mode = NAND_ECC_SOFT; +#endif #ifdef CONFIG_SYS_NAND_DBW_16 nand->options = NAND_BUSWIDTH_16; #endif -- cgit v1.2.3 From 16dddef6050471f47c84b6c929ae3c4bc9c0fb46 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Fri, 18 Oct 2013 17:46:31 +0800 Subject: mtd: atmel_nand: enable PMECC support for 8k bytes page NAND flash increase the delay to 75us to support the 8k bytes page nand flash Signed-off-by: Josh Wu --- drivers/mtd/nand/atmel_nand.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/mtd/nand/atmel_nand.c') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 10011c6a8f4..1d8c860f1af 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -827,6 +827,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, switch (mtd->writesize) { case 2048: case 4096: + case 8192: host->pmecc_degree = (sector_size == 512) ? PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14; host->pmecc_cw_len = (1 << host->pmecc_degree) - 1; @@ -840,6 +841,13 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, nand->ecc.steps = 1; nand->ecc.bytes = host->pmecc_bytes_per_sector * host->pmecc_sector_number; + + if (nand->ecc.bytes > MTD_MAX_ECCPOS_ENTRIES_LARGE) { + dev_err(host->dev, "too large eccpos entries. max support ecc.bytes is %d\n", + MTD_MAX_ECCPOS_ENTRIES_LARGE); + return -EINVAL; + } + if (nand->ecc.bytes > mtd->oobsize - 2) { printk(KERN_ERR "No room for ECC bytes\n"); return -EINVAL; @@ -1190,7 +1198,7 @@ int atmel_nand_chip_init(int devnum, ulong base_addr) #ifdef CONFIG_SYS_NAND_READY_PIN nand->dev_ready = at91_nand_ready; #endif - nand->chip_delay = 20; + nand->chip_delay = 75; ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL); if (ret) -- cgit v1.2.3 From c55cc573eaf1ba7318b1b692c673a28b99f5195c Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Fri, 18 Oct 2013 17:46:33 +0800 Subject: mtd: atmel_nand: don't print bit correction message in driver Since for some MLC nand, bit errors happened too often. Just disable it to avoid noise Signed-off-by: Josh Wu --- drivers/mtd/nand/atmel_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/nand/atmel_nand.c') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 1d8c860f1af..92547432ac8 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -452,7 +452,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, *(buf + byte_pos) ^= (1 << bit_pos); pos = sector_num * host->pmecc_sector_size + byte_pos; - printk(KERN_INFO "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", + dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", pos, bit_pos, err_byte, *(buf + byte_pos)); } else { /* Bit flip in OOB area */ @@ -462,7 +462,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, ecc[tmp] ^= (1 << bit_pos); pos = tmp + nand_chip->ecc.layout->eccpos[0]; - printk(KERN_INFO "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", + dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", pos, bit_pos, err_byte, ecc[tmp]); } -- cgit v1.2.3 From c0dc3dec697e930d290145e127a86ff31f7c2dde Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Fri, 18 Oct 2013 17:46:34 +0800 Subject: mtd: atmel_nand: use dev_xxx instead of printk Signed-off-by: Josh Wu --- drivers/mtd/nand/atmel_nand.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/mtd/nand/atmel_nand.c') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 92547432ac8..16b7df0f721 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -412,7 +412,7 @@ static int pmecc_err_location(struct mtd_info *mtd) } if (!timeout) { - printk(KERN_ERR "atmel_nand : Timeout to calculate PMECC error location\n"); + dev_err(host->dev, "atmel_nand : Timeout to calculate PMECC error location\n"); return -1; } @@ -500,7 +500,7 @@ normal_check: err_nbr = pmecc_err_location(mtd); if (err_nbr == -1) { - printk(KERN_ERR "PMECC: Too many errors\n"); + dev_err(host->dev, "PMECC: Too many errors\n"); mtd->ecc_stats.failed++; return -EIO; } else { @@ -544,7 +544,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, } if (!timeout) { - printk(KERN_ERR "atmel_nand : Timeout to read PMECC page\n"); + dev_err(host->dev, "atmel_nand : Timeout to read PMECC page\n"); return -1; } @@ -584,7 +584,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, } if (!timeout) { - printk(KERN_ERR "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n"); + dev_err(host->dev, "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n"); goto out; } @@ -849,7 +849,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, } if (nand->ecc.bytes > mtd->oobsize - 2) { - printk(KERN_ERR "No room for ECC bytes\n"); + dev_err(host->dev, "No room for ECC bytes\n"); return -EINVAL; } pmecc_config_ecc_layout(&atmel_pmecc_oobinfo, @@ -860,7 +860,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, case 512: case 1024: /* TODO */ - printk(KERN_ERR "Unsupported page size for PMECC, use Software ECC\n"); + dev_err(host->dev, "Unsupported page size for PMECC, use Software ECC\n"); default: /* page size not handled by HW ECC */ /* switching back to soft ECC */ @@ -1043,7 +1043,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, /* it doesn't seems to be a freshly * erased block. * We can't correct so many errors */ - printk(KERN_WARNING "atmel_nand : multiple errors detected." + dev_warn(host->dev, "atmel_nand : multiple errors detected." " Unable to correct.\n"); return -EIO; } @@ -1053,12 +1053,12 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, /* there's nothing much to do here. * the bit error is on the ECC itself. */ - printk(KERN_WARNING "atmel_nand : one bit error on ECC code." + dev_warn(host->dev, "atmel_nand : one bit error on ECC code." " Nothing to correct\n"); return 0; } - printk(KERN_WARNING "atmel_nand : one bit error on data." + dev_warn(host->dev, "atmel_nand : one bit error on data." " (word offset in the page :" " 0x%x bit offset : 0x%x)\n", ecc_word, ecc_bit); @@ -1070,7 +1070,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, /* 8 bits words */ dat[ecc_word] ^= (1 << ecc_bit); } - printk(KERN_WARNING "atmel_nand : error corrected\n"); + dev_warn(host->dev, "atmel_nand : error corrected\n"); return 1; } @@ -1226,6 +1226,6 @@ void board_nand_init(void) int i; for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) if (atmel_nand_chip_init(i, base_addr[i])) - printk(KERN_ERR "atmel_nand: Fail to initialize #%d chip", + dev_err(host->dev, "atmel_nand: Fail to initialize #%d chip", i); } -- cgit v1.2.3