Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Wu, Josh and committed by
Brian Norris
51585778 267d46e6

+25 -2
+1 -1
Documentation/devicetree/bindings/mtd/atmel-nand.txt
··· 1 1 Atmel NAND flash 2 2 3 3 Required properties: 4 - - compatible : "atmel,at91rm9200-nand". 4 + - compatible : should be "atmel,at91rm9200-nand" or "atmel,sama5d4-nand". 5 5 - reg : should specify localbus address and size used for the chip, 6 6 and hardware ECC controller if available. 7 7 If the hardware ECC is PMECC, it should contain address and size for
+24 -1
drivers/mtd/nand/atmel_nand.c
··· 63 63 #include "atmel_nand_ecc.h" /* Hardware ECC registers */ 64 64 #include "atmel_nand_nfc.h" /* Nand Flash Controller definition */ 65 65 66 + struct atmel_nand_caps { 67 + bool pmecc_correct_erase_page; 68 + }; 69 + 66 70 /* oob layout for large page size 67 71 * bad block info is on bytes 0 and 1 68 72 * the bytes have to be consecutives to avoid ··· 128 124 129 125 struct atmel_nfc *nfc; 130 126 127 + struct atmel_nand_caps *caps; 131 128 bool has_pmecc; 132 129 u8 pmecc_corr_cap; 133 130 u16 pmecc_sector_size; ··· 854 849 uint8_t *buf_pos; 855 850 int max_bitflips = 0; 856 851 852 + /* If can correct bitfilps from erased page, do the normal check */ 853 + if (host->caps->pmecc_correct_erase_page) 854 + goto normal_check; 855 + 857 856 for (i = 0; i < nand_chip->ecc.total; i++) 858 857 if (ecc[i] != 0xff) 859 858 goto normal_check; ··· 1483 1474 ecc_writel(host->ecc, CR, ATMEL_ECC_RST); 1484 1475 } 1485 1476 1477 + static const struct of_device_id atmel_nand_dt_ids[]; 1478 + 1486 1479 static int atmel_of_init_port(struct atmel_nand_host *host, 1487 1480 struct device_node *np) 1488 1481 { ··· 1493 1482 int ecc_mode; 1494 1483 struct atmel_nand_data *board = &host->board; 1495 1484 enum of_gpio_flags flags = 0; 1485 + 1486 + host->caps = (struct atmel_nand_caps *) 1487 + of_match_device(atmel_nand_dt_ids, host->dev)->data; 1496 1488 1497 1489 if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { 1498 1490 if (val >= 32) { ··· 2302 2288 return 0; 2303 2289 } 2304 2290 2291 + static struct atmel_nand_caps at91rm9200_caps = { 2292 + .pmecc_correct_erase_page = false, 2293 + }; 2294 + 2295 + static struct atmel_nand_caps sama5d4_caps = { 2296 + .pmecc_correct_erase_page = true, 2297 + }; 2298 + 2305 2299 static const struct of_device_id atmel_nand_dt_ids[] = { 2306 - { .compatible = "atmel,at91rm9200-nand" }, 2300 + { .compatible = "atmel,at91rm9200-nand", .data = &at91rm9200_caps }, 2301 + { .compatible = "atmel,sama5d4-nand", .data = &sama5d4_caps }, 2307 2302 { /* sentinel */ } 2308 2303 }; 2309 2304