diff options
-rw-r--r-- | drivers/mtd/nand/davinci_nand.c | 23 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/s3c2410_nand.c | 31 | ||||
-rw-r--r-- | include/linux/mtd/mtd-abi.h | 2 |
4 files changed, 45 insertions, 13 deletions
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index eabaf3e..41a9568 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -182,13 +182,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char * #ifdef CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = { -/* - * TI uses a different layout for 4K page deviecs. Since the - * eccpos filed can hold only a limited number of entries, adding - * support for 4K page will result in compilation warnings - * 4K Support will be added later - */ -#ifdef CONFIG_SYS_NAND_PAGE_2K +#if defined(CONFIG_SYS_NAND_PAGE_2K) .eccbytes = 40, .eccpos = { 24, 25, 26, 27, 28, @@ -200,6 +194,21 @@ static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = { .oobfree = { {.offset = 2, .length = 22, }, }, +#elif defined(CONFIG_SYS_NAND_PAGE_4K) + .eccbytes = 80, + .eccpos = { + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + }, + .oobfree = { + {.offset = 2, .length = 46, }, + }, #endif }; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6da261c..7171bdd 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1061,7 +1061,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3 int stat; stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); - if (stat < 0) + if (stat == -1) mtd->ecc_stats.failed++; else mtd->ecc_stats.corrected += stat; diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index f2f3e72..815c78e 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -36,6 +36,21 @@ #define S3C2410_ADDR_NALE 4 #define S3C2410_ADDR_NCLE 8 +#ifdef CONFIG_NAND_SPL + +/* in the early stage of NAND flash booting, printf() is not available */ +#define printf(fmt, args...) + +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + + for (i = 0; i < len; i++) + buf[i] = readb(this->IO_ADDR_R); +} +#endif + static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; @@ -83,9 +98,10 @@ void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - ecc_code[0] = NFECC0; - ecc_code[1] = NFECC1; - ecc_code[2] = NFECC2; + struct s3c2410_nand *nand = s3c2410_get_base_nand(); + ecc_code[0] = readb(&nand->NFECC); + ecc_code[1] = readb(&nand->NFECC + 1); + ecc_code[2] = readb(&nand->NFECC + 2); debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]); @@ -130,8 +146,13 @@ int board_nand_init(struct nand_chip *nand) /* initialize nand_chip data structure */ nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA; + nand->select_chip = NULL; + /* read_buf and write_buf are default */ /* read_byte and write_byte are default */ +#ifdef CONFIG_NAND_SPL + nand->read_buf = nand_read_buf; +#endif /* hwcontrol always must be implemented */ nand->cmd_ctrl = s3c2410_hwcontrol; @@ -142,7 +163,9 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.hwctl = s3c2410_nand_enable_hwecc; nand->ecc.calculate = s3c2410_nand_calculate_ecc; nand->ecc.correct = s3c2410_nand_correct_data; - nand->ecc.mode = NAND_ECC_HW3_512; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; #else nand->ecc.mode = NAND_ECC_SOFT; #endif diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h index 410c5dd..8d5f60c 100644 --- a/include/linux/mtd/mtd-abi.h +++ b/include/linux/mtd/mtd-abi.h @@ -123,7 +123,7 @@ struct nand_oobfree { */ struct nand_ecclayout { uint32_t eccbytes; - uint32_t eccpos[64]; + uint32_t eccpos[128]; uint32_t oobavail; struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; }; |