aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/atmel_nand.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 4814fc9b237b..99aec46e2145 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -33,6 +33,7 @@
33#include <linux/io.h> 33#include <linux/io.h>
34 34
35#include <asm/arch/board.h> 35#include <asm/arch/board.h>
36#include <asm/arch/cpu.h>
36 37
37#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW 38#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW
38#define hard_ecc 1 39#define hard_ecc 1
@@ -264,6 +265,19 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
264 uint8_t *ecc_pos; 265 uint8_t *ecc_pos;
265 int stat; 266 int stat;
266 267
268 /*
269 * Errata: ALE is incorrectly wired up to the ECC controller
270 * on the AP7000, so it will include the address cycles in the
271 * ECC calculation.
272 *
273 * Workaround: Reset the parity registers before reading the
274 * actual data.
275 */
276 if (cpu_is_at32ap7000()) {
277 struct atmel_nand_host *host = chip->priv;
278 ecc_writel(host->ecc, CR, ATMEL_ECC_RST);
279 }
280
267 /* read the page */ 281 /* read the page */
268 chip->read_buf(mtd, p, eccsize); 282 chip->read_buf(mtd, p, eccsize);
269 283
@@ -377,9 +391,16 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
377} 391}
378 392
379/* 393/*
380 * Enable HW ECC : unsused 394 * Enable HW ECC : unused on most chips
381 */ 395 */
382static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) { ; } 396static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
397{
398 if (cpu_is_at32ap7000()) {
399 struct nand_chip *nand_chip = mtd->priv;
400 struct atmel_nand_host *host = nand_chip->priv;
401 ecc_writel(host->ecc, CR, ATMEL_ECC_RST);
402 }
403}
383 404
384#ifdef CONFIG_MTD_PARTITIONS 405#ifdef CONFIG_MTD_PARTITIONS
385static const char *part_probes[] = { "cmdlinepart", NULL }; 406static const char *part_probes[] = { "cmdlinepart", NULL };