aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorWu, Josh <Josh.wu@atmel.com>2015-01-19 03:33:06 -0500
committerBrian Norris <computersforpeace@gmail.com>2015-01-20 15:47:01 -0500
commit51585778f63adaadbc67399e172fcf11daa9f032 (patch)
treee3d933ed03654569a1bb6df9068d7d61f7b277f6 /drivers/mtd
parent267d46e635c575e9c8b2932d9617266e6e67ee99 (diff)
mtd: atmel_nand: introduce a new compatible string for sama5d4 chip
Since in SAMA5D4 chip, the PMECC can correct bit flips in erased page. So we add a DT property to indicate this hardware character. If the PMECC support correct bitflip erased page (all data are 0xff). Then we can use the PMECC correct the page and skip the erased page check. Signed-off-by: Josh Wu <josh.wu@atmel.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/atmel_nand.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 7346d16cf61a..d93c849b70b5 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -63,6 +63,10 @@ module_param(on_flash_bbt, int, 0);
63#include "atmel_nand_ecc.h" /* Hardware ECC registers */ 63#include "atmel_nand_ecc.h" /* Hardware ECC registers */
64#include "atmel_nand_nfc.h" /* Nand Flash Controller definition */ 64#include "atmel_nand_nfc.h" /* Nand Flash Controller definition */
65 65
66struct atmel_nand_caps {
67 bool pmecc_correct_erase_page;
68};
69
66/* oob layout for large page size 70/* oob layout for large page size
67 * bad block info is on bytes 0 and 1 71 * bad block info is on bytes 0 and 1
68 * the bytes have to be consecutives to avoid 72 * the bytes have to be consecutives to avoid
@@ -124,6 +128,7 @@ struct atmel_nand_host {
124 128
125 struct atmel_nfc *nfc; 129 struct atmel_nfc *nfc;
126 130
131 struct atmel_nand_caps *caps;
127 bool has_pmecc; 132 bool has_pmecc;
128 u8 pmecc_corr_cap; 133 u8 pmecc_corr_cap;
129 u16 pmecc_sector_size; 134 u16 pmecc_sector_size;
@@ -849,6 +854,10 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
849 uint8_t *buf_pos; 854 uint8_t *buf_pos;
850 int max_bitflips = 0; 855 int max_bitflips = 0;
851 856
857 /* If can correct bitfilps from erased page, do the normal check */
858 if (host->caps->pmecc_correct_erase_page)
859 goto normal_check;
860
852 for (i = 0; i < nand_chip->ecc.total; i++) 861 for (i = 0; i < nand_chip->ecc.total; i++)
853 if (ecc[i] != 0xff) 862 if (ecc[i] != 0xff)
854 goto normal_check; 863 goto normal_check;
@@ -1474,6 +1483,8 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
1474 ecc_writel(host->ecc, CR, ATMEL_ECC_RST); 1483 ecc_writel(host->ecc, CR, ATMEL_ECC_RST);
1475} 1484}
1476 1485
1486static const struct of_device_id atmel_nand_dt_ids[];
1487
1477static int atmel_of_init_port(struct atmel_nand_host *host, 1488static int atmel_of_init_port(struct atmel_nand_host *host,
1478 struct device_node *np) 1489 struct device_node *np)
1479{ 1490{
@@ -1483,6 +1494,9 @@ static int atmel_of_init_port(struct atmel_nand_host *host,
1483 struct atmel_nand_data *board = &host->board; 1494 struct atmel_nand_data *board = &host->board;
1484 enum of_gpio_flags flags = 0; 1495 enum of_gpio_flags flags = 0;
1485 1496
1497 host->caps = (struct atmel_nand_caps *)
1498 of_match_device(atmel_nand_dt_ids, host->dev)->data;
1499
1486 if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { 1500 if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
1487 if (val >= 32) { 1501 if (val >= 32) {
1488 dev_err(host->dev, "invalid addr-offset %u\n", val); 1502 dev_err(host->dev, "invalid addr-offset %u\n", val);
@@ -2288,8 +2302,17 @@ static int atmel_nand_remove(struct platform_device *pdev)
2288 return 0; 2302 return 0;
2289} 2303}
2290 2304
2305static struct atmel_nand_caps at91rm9200_caps = {
2306 .pmecc_correct_erase_page = false,
2307};
2308
2309static struct atmel_nand_caps sama5d4_caps = {
2310 .pmecc_correct_erase_page = true,
2311};
2312
2291static const struct of_device_id atmel_nand_dt_ids[] = { 2313static const struct of_device_id atmel_nand_dt_ids[] = {
2292 { .compatible = "atmel,at91rm9200-nand" }, 2314 { .compatible = "atmel,at91rm9200-nand", .data = &at91rm9200_caps },
2315 { .compatible = "atmel,sama5d4-nand", .data = &sama5d4_caps },
2293 { /* sentinel */ } 2316 { /* sentinel */ }
2294}; 2317};
2295 2318