Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 332654
b: refs/heads/master
c: a41b51a
h: refs/heads/master
v: v3
  • Loading branch information
Josh Wu authored and David Woodhouse committed Jul 6, 2012
1 parent 22a63c6 commit 53ddf6e
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fae255253b393d5e4f0d77d5afa103bfc8b47a97
refs/heads/master: a41b51a1f7c15a1b00f30a3ad2d0373ad51b883d
40 changes: 39 additions & 1 deletion trunk/Documentation/devicetree/bindings/mtd/atmel-nand.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Atmel NAND flash
Required properties:
- compatible : "atmel,at91rm9200-nand".
- reg : should specify localbus address and size used for the chip,
and if availlable the ECC.
and hardware ECC controller if available.
If the hardware ECC is PMECC, it should contain address and size for
PMECC, PMECC Error Location controller and ROM which has lookup tables.
- atmel,nand-addr-offset : offset for the address latch.
- atmel,nand-cmd-offset : offset for the command latch.
- #address-cells, #size-cells : Must be present if the device has sub-nodes
Expand All @@ -16,6 +18,15 @@ Optional properties:
- nand-ecc-mode : String, operation mode of the NAND ecc mode, soft by default.
Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
"soft_bch".
- atmel,has-pmecc : boolean to enable Programmable Multibit ECC hardware.
Only supported by at91sam9x5 or later sam9 product.
- atmel,pmecc-cap : error correct capability for Programmable Multibit ECC
Controller. Supported values are: 2, 4, 8, 12, 24.
- atmel,pmecc-sector-size : sector size for ECC computation. Supported values
are: 512, 1024.
- atmel,pmecc-lookup-table-offset : includes two offsets of lookup table in ROM
for different sector size. First one is for sector size 512, the next is for
sector size 1024.
- nand-bus-width : 8 or 16 bus width if not present 8
- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false

Expand All @@ -39,3 +50,30 @@ nand0: nand@40000000,0 {
...
};
};

/* for PMECC supported chips */
nand0: nand@40000000 {
compatible = "atmel,at91rm9200-nand";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x40000000 0x10000000 /* bus addr & size */
0xffffe000 0x00000600 /* PMECC addr & size */
0xffffe600 0x00000200 /* PMECC ERRLOC addr & size */
0x00100000 0x00100000 /* ROM addr & size */
>;
atmel,nand-addr-offset = <21>; /* ale */
atmel,nand-cmd-offset = <22>; /* cle */
nand-on-flash-bbt;
nand-ecc-mode = "hw";
atmel,has-pmecc; /* enable PMECC */
atmel,pmecc-cap = <2>;
atmel,pmecc-sector-size = <512>;
atmel,pmecc-lookup-table-offset = <0x8000 0x10000>;
gpios = <&pioD 5 0 /* rdy */
&pioD 4 0 /* nce */
0 /* cd */
>;
partition@0 {
...
};
};
52 changes: 51 additions & 1 deletion trunk/drivers/mtd/nand/atmel_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ struct atmel_nand_host {

struct completion comp;
struct dma_chan *dma_chan;

bool has_pmecc;
u8 pmecc_corr_cap;
u16 pmecc_sector_size;
u32 pmecc_lookup_table_offset;
};

static int cpu_has_dma(void)
Expand Down Expand Up @@ -481,7 +486,8 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
struct device_node *np)
{
u32 val;
u32 val, table_offset;
u32 offset[2];
int ecc_mode;
struct atmel_nand_data *board = &host->board;
enum of_gpio_flags flags;
Expand Down Expand Up @@ -517,6 +523,50 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
board->enable_pin = of_get_gpio(np, 1);
board->det_pin = of_get_gpio(np, 2);

host->has_pmecc = of_property_read_bool(np, "atmel,has-pmecc");

if (!(board->ecc_mode == NAND_ECC_HW) || !host->has_pmecc)
return 0; /* Not using PMECC */

/* use PMECC, get correction capability, sector size and lookup
* table offset.
*/
if (of_property_read_u32(np, "atmel,pmecc-cap", &val) != 0) {
dev_err(host->dev, "Cannot decide PMECC Capability\n");
return -EINVAL;
} else if ((val != 2) && (val != 4) && (val != 8) && (val != 12) &&
(val != 24)) {
dev_err(host->dev,
"Unsupported PMECC correction capability: %d; should be 2, 4, 8, 12 or 24\n",
val);
return -EINVAL;
}
host->pmecc_corr_cap = (u8)val;

if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) != 0) {
dev_err(host->dev, "Cannot decide PMECC Sector Size\n");
return -EINVAL;
} else if ((val != 512) && (val != 1024)) {
dev_err(host->dev,
"Unsupported PMECC sector size: %d; should be 512 or 1024 bytes\n",
val);
return -EINVAL;
}
host->pmecc_sector_size = (u16)val;

if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset",
offset, 2) != 0) {
dev_err(host->dev, "Cannot get PMECC lookup table offset\n");
return -EINVAL;
}
table_offset = host->pmecc_sector_size == 512 ? offset[0] : offset[1];

if (!table_offset) {
dev_err(host->dev, "Invalid PMECC lookup table offset\n");
return -EINVAL;
}
host->pmecc_lookup_table_offset = table_offset;

return 0;
}
#else
Expand Down

0 comments on commit 53ddf6e

Please sign in to comment.