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 | ||
