diff options
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 58 |
1 files changed, 16 insertions, 42 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 438a967bd6..db13f5b7e4 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -107,8 +107,6 @@ struct atmel_nand_host { void *ecc_code; }; -static struct nand_ecclayout atmel_pmecc_oobinfo; - /* * Enable NAND. */ @@ -201,22 +199,6 @@ static int pmecc_get_ecc_bytes(int cap, int sector_size) return (m * cap + 7) / 8; } -static void pmecc_config_ecc_layout(struct nand_ecclayout *layout, - int oobsize, int ecc_len) -{ - int i; - - layout->eccbytes = ecc_len; - - /* ECC will occupy the last ecc_len bytes continuously */ - for (i = 0; i < ecc_len; i++) - layout->eccpos[i] = oobsize - ecc_len + i; - - layout->oobfree[0].offset = 2; - layout->oobfree[0].length = - oobsize - ecc_len - layout->oobfree[0].offset; -} - static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) { int table_size; @@ -574,7 +556,7 @@ 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_chip->priv; - int i, err_nbr, ret, bitflips = 0; + int i, err_nbr, ret, max_bitflips = 0; uint8_t *buf_pos; uint8_t *ecc_code = host->ecc_code; @@ -583,7 +565,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf) if (ret) return ret; - for (i = 0; i < nand_chip->ecc.bytes; i++) + for (i = 0; i < nand_chip->ecc.bytes * nand_chip->ecc.steps; i++) if (ecc_code[i] != 0xff) goto normal_check; /* Erased page, return OK */ @@ -608,13 +590,13 @@ normal_check: pmecc_correct_data(mtd, buf_pos, ecc_code, i, host->pmecc_bytes_per_sector, err_nbr); mtd->ecc_stats.corrected += err_nbr; - bitflips += err_nbr; + max_bitflips = max(max_bitflips, err_nbr); } } pmecc_stat >>= 1; } - return bitflips; + return max_bitflips; } static int atmel_nand_pmecc_read_page(struct nand_chip *chip, uint8_t *buf, @@ -622,7 +604,6 @@ static int atmel_nand_pmecc_read_page(struct nand_chip *chip, uint8_t *buf, { struct mtd_info *mtd = nand_to_mtd(chip); struct atmel_nand_host *host = chip->priv; - int eccsize = chip->ecc.size; uint32_t stat; int ret; @@ -636,7 +617,7 @@ static int atmel_nand_pmecc_read_page(struct nand_chip *chip, uint8_t *buf, nand_read_page_op(chip, page, 0, NULL, 0); - chip->legacy.read_buf(chip, buf, eccsize); + chip->legacy.read_buf(chip, buf, mtd->writesize); chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize); ret = wait_on_timeout(PMECC_MAX_TIMEOUT_MS, @@ -711,7 +692,7 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd) struct nand_chip *nand_chip = mtd_to_nand(mtd); struct atmel_nand_host *host = nand_chip->priv; uint32_t val = 0; - struct nand_ecclayout *ecc_layout; + int eccbytes; pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); @@ -758,11 +739,10 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd) | PMECC_CFG_AUTO_DISABLE); pmecc_writel(host->ecc, CFG, val); - ecc_layout = host->ecclayout; + eccbytes = host->pmecc_sector_number * host->pmecc_bytes_per_sector; pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1); - pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]); - pmecc_writel(host->ecc, EADDR, - ecc_layout->eccpos[ecc_layout->eccbytes - 1]); + pmecc_writel(host->ecc, SADDR, mtd->oobsize - eccbytes); + pmecc_writel(host->ecc, EADDR, mtd->oobsize - 1); /* See datasheet about PMECC Clock Control Register */ pmecc_writel(host->ecc, CLK, 2); pmecc_writel(host->ecc, IDR, 0xff); @@ -914,9 +894,6 @@ static int __init atmel_pmecc_nand_init_params(struct device_d *dev, host->board->pmecc_lookup_table_offset = 0; } - /* ECC is calculated for the whole page (1 step) */ - nand_chip->ecc.size = mtd->writesize; - /* set ECC page size and oob layout */ switch (mtd->writesize) { case 2048: @@ -932,18 +909,16 @@ static int __init atmel_pmecc_nand_init_params(struct device_d *dev, host->pmecc_index_of = host->pmecc_rom_base + host->board->pmecc_lookup_table_offset; - nand_chip->ecc.steps = 1; - nand_chip->ecc.bytes = host->pmecc_bytes_per_sector * - host->pmecc_sector_number; + nand_chip->ecc.steps = host->pmecc_sector_number; + nand_chip->ecc.bytes = host->pmecc_bytes_per_sector; + nand_chip->ecc.size = sector_size; + nand_chip->ecc.strength = cap; + if (nand_chip->ecc.bytes > mtd->oobsize - 2) { dev_err(host->dev, "No room for ECC bytes\n"); return -EINVAL; } - pmecc_config_ecc_layout(&atmel_pmecc_oobinfo, - mtd->oobsize, - nand_chip->ecc.bytes); - host->ecclayout = &atmel_pmecc_oobinfo; - mtd_set_ecclayout(mtd, host->ecclayout); + mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); break; case 512: case 1024: @@ -1016,7 +991,6 @@ static int atmel_nand_read_page(struct nand_chip *chip, uint8_t *buf, { struct mtd_info *mtd = nand_to_mtd(chip); struct atmel_nand_host *host = chip->priv; - int eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; uint32_t *eccpos = host->ecclayout->eccpos; uint8_t *p = buf; @@ -1027,7 +1001,7 @@ static int atmel_nand_read_page(struct nand_chip *chip, uint8_t *buf, nand_read_page_op(chip, page, 0, NULL, 0); /* read the page */ - chip->legacy.read_buf(chip, p, eccsize); + chip->legacy.read_buf(chip, p, mtd->writesize); /* move to ECC position if needed */ if (eccpos[0] != 0) { |