Skip to content

Commit

Permalink
mtd: atmel_nand: introduce a new compatible string for sama5d4 chip
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Brian Norris <[email protected]>
  • Loading branch information
JoshWu authored and computersforpeace committed Jan 20, 2015
1 parent 267d46e commit 5158577
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Documentation/devicetree/bindings/mtd/atmel-nand.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Atmel NAND flash

Required properties:
- compatible : "atmel,at91rm9200-nand".
- compatible : should be "atmel,at91rm9200-nand" or "atmel,sama5d4-nand".
- reg : should specify localbus address and size used for the chip,
and hardware ECC controller if available.
If the hardware ECC is PMECC, it should contain address and size for
Expand Down
25 changes: 24 additions & 1 deletion drivers/mtd/nand/atmel_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ module_param(on_flash_bbt, int, 0);
#include "atmel_nand_ecc.h" /* Hardware ECC registers */
#include "atmel_nand_nfc.h" /* Nand Flash Controller definition */

struct atmel_nand_caps {
bool pmecc_correct_erase_page;
};

/* oob layout for large page size
* bad block info is on bytes 0 and 1
* the bytes have to be consecutives to avoid
Expand Down Expand Up @@ -124,6 +128,7 @@ struct atmel_nand_host {

struct atmel_nfc *nfc;

struct atmel_nand_caps *caps;
bool has_pmecc;
u8 pmecc_corr_cap;
u16 pmecc_sector_size;
Expand Down Expand Up @@ -849,6 +854,10 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
uint8_t *buf_pos;
int max_bitflips = 0;

/* If can correct bitfilps from erased page, do the normal check */
if (host->caps->pmecc_correct_erase_page)
goto normal_check;

for (i = 0; i < nand_chip->ecc.total; i++)
if (ecc[i] != 0xff)
goto normal_check;
Expand Down Expand Up @@ -1474,6 +1483,8 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
ecc_writel(host->ecc, CR, ATMEL_ECC_RST);
}

static const struct of_device_id atmel_nand_dt_ids[];

static int atmel_of_init_port(struct atmel_nand_host *host,
struct device_node *np)
{
Expand All @@ -1483,6 +1494,9 @@ static int atmel_of_init_port(struct atmel_nand_host *host,
struct atmel_nand_data *board = &host->board;
enum of_gpio_flags flags = 0;

host->caps = (struct atmel_nand_caps *)
of_match_device(atmel_nand_dt_ids, host->dev)->data;

if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
if (val >= 32) {
dev_err(host->dev, "invalid addr-offset %u\n", val);
Expand Down Expand Up @@ -2288,8 +2302,17 @@ static int atmel_nand_remove(struct platform_device *pdev)
return 0;
}

static struct atmel_nand_caps at91rm9200_caps = {
.pmecc_correct_erase_page = false,
};

static struct atmel_nand_caps sama5d4_caps = {
.pmecc_correct_erase_page = true,
};

static const struct of_device_id atmel_nand_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-nand" },
{ .compatible = "atmel,at91rm9200-nand", .data = &at91rm9200_caps },
{ .compatible = "atmel,sama5d4-nand", .data = &sama5d4_caps },
{ /* sentinel */ }
};

Expand Down

0 comments on commit 5158577

Please sign in to comment.