aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-08-06 09:53:10 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-08-06 11:38:03 -0400
commit6e85dfdc19ef526edec285aed47c83934882e9bd (patch)
treeba9fe60c6aab5cbc6dec94abd58b8eaf6f2f9d5e /drivers/mtd/nand
parent94f77e50d658be1d3ff23fb65e4d075a6f4ebee3 (diff)
mxc_nand: support 8bit ecc
Nand devices with at least 26 bytes of oob data per 512 byte block can have 8bit ecc on v2 type controllers. This is currently not tested, but at least this patch puts the ECC_MODE bit into a well defined state. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/mxc_nand.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index f5fd25461a09..1433a8389109 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -58,6 +58,7 @@
58#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a) 58#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
59#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c) 59#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
60 60
61#define NFC_V2_CONFIG1_ECC_MODE_4 (1 << 0)
61#define NFC_V1_V2_CONFIG1_SP_EN (1 << 2) 62#define NFC_V1_V2_CONFIG1_SP_EN (1 << 2)
62#define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3) 63#define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3)
63#define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4) 64#define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4)
@@ -581,6 +582,23 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
581 } 582 }
582} 583}
583 584
585/*
586 * v2 and v3 type controllers can do 4bit or 8bit ecc depending
587 * on how much oob the nand chip has. For 8bit ecc we need at least
588 * 26 bytes of oob data per 512 byte block.
589 */
590static int get_eccsize(struct mtd_info *mtd)
591{
592 int oobbytes_per_512 = 0;
593
594 oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize;
595
596 if (oobbytes_per_512 < 26)
597 return 4;
598 else
599 return 8;
600}
601
584static void preset_v1_v2(struct mtd_info *mtd) 602static void preset_v1_v2(struct mtd_info *mtd)
585{ 603{
586 struct nand_chip *nand_chip = mtd->priv; 604 struct nand_chip *nand_chip = mtd->priv;
@@ -596,6 +614,15 @@ static void preset_v1_v2(struct mtd_info *mtd)
596 } else { 614 } else {
597 tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN; 615 tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
598 } 616 }
617
618 if (nfc_is_v21() && mtd->writesize) {
619 host->eccsize = get_eccsize(mtd);
620 if (host->eccsize == 4)
621 tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
622 } else {
623 host->eccsize = 1;
624 }
625
599 writew(tmp, NFC_V1_V2_CONFIG1); 626 writew(tmp, NFC_V1_V2_CONFIG1);
600 /* preset operation */ 627 /* preset operation */
601 628
@@ -859,6 +886,9 @@ static int __init mxcnd_probe(struct platform_device *pdev)
859 goto escan; 886 goto escan;
860 } 887 }
861 888
889 /* Call preset again, with correct writesize this time */
890 host->preset(mtd);
891
862 if (mtd->writesize == 2048) 892 if (mtd->writesize == 2048)
863 this->ecc.layout = oob_largepage; 893 this->ecc.layout = oob_largepage;
864 894