diff options
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 30 |
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 | */ | ||
590 | static 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 | |||
584 | static void preset_v1_v2(struct mtd_info *mtd) | 602 | static 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 | ||