summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Wu <josh.wu@atmel.com>2012-11-29 18:45:52 +0800
committerJosh Wu <josh.wu@atmel.com>2012-11-30 16:59:26 +0800
commit587aa30fdfb5bc27f9568b62395ff9855ae91b00 (patch)
tree9b9c97ce5d1500e468a3d2d1efa3abfd715a0cac
parent59f94a35a359800c5ef90d258583af7a1a702b63 (diff)
MTD: at91: atmel_nand: since PMECC support different ecc
correctable bits(2, 4, 8, 12, 24), add code to choose the ecc bits according to the ONFI parameter's minimum required ecc_bits. we'll check the ecc_bits (minimum required ecc correct bits) in ONFI parameter. If ecc_bits is smaller compare with CONFIG_PMECC_CAP in config file, then use ecc_bits. otherwise use CONFIG_PMECC_CAP. for non-ONFI support nand flash, we assume its minimum ecc_bits is 1.
-rw-r--r--drivers/mtd/nand/atmel_nand.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index e2f6c4f2a8..8a5dce2e58 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -675,6 +675,44 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
pmecc_writel(host->pmecc, ctrl, PMECC_CTRL_ENABLE);
}
+static int pmecc_choose_ecc_bits(int pre_ecc_bits, struct nand_chip *nand_chip)
+{
+ int ecc_bits = pre_ecc_bits;
+
+ if (nand_chip->onfi_version) {
+ printk(KERN_WARNING "ONFI params, minimum required ECC: %d\n",
+ nand_chip->onfi_params.ecc_bits);
+ if (nand_chip->onfi_params.ecc_bits < ecc_bits)
+ ecc_bits = nand_chip->onfi_params.ecc_bits;
+ } else {
+ /* For non-ONFI support nand flash, we assume the software
+ * ecc can work. That means the ecc_bits = 1.
+ */
+ ecc_bits = 1;
+ printk(KERN_WARNING "non-ONFI supported nand flash, assume minimum required ECC: 1\n");
+ }
+
+ if ((ecc_bits != 2) && (ecc_bits != 4) && (ecc_bits != 8) && (ecc_bits != 12) &&
+ (ecc_bits != 24)) {
+ /* use the most fitable ecc bits (the near bigger one ) */
+ if (ecc_bits < 2)
+ return 2;
+ else if (ecc_bits < 4)
+ return 4;
+ else if (ecc_bits < 8)
+ return 8;
+ else if (ecc_bits < 12)
+ return 12;
+ else if (ecc_bits < 24)
+ return 24;
+ else
+ /* not support by our pmecc hw */
+ return pre_ecc_bits;
+ } else {
+ return ecc_bits;
+ }
+}
+
static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
struct mtd_info *mtd)
{
@@ -688,7 +726,10 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
nand->ecc.correct = NULL;
nand->ecc.hwctl = NULL;
- cap = host->pmecc_corr_cap = CONFIG_PMECC_CAP;
+ /* Choose PMECC ecc bits according to ONFI parameters */
+ host->pmecc_corr_cap = pmecc_choose_ecc_bits(CONFIG_PMECC_CAP, nand);
+ cap = host->pmecc_corr_cap;
+
sector_size = host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
host->pmecc_index_table_offset = CONFIG_PMECC_INDEX_TABLE_OFFSET;