Loading drivers/mtd/nand/mxc_nand.c +105 −107 Original line number Diff line number Diff line Loading @@ -149,7 +149,7 @@ struct mxc_nand_devtype_data { int (*check_int)(struct mxc_nand_host *); void (*irq_control)(struct mxc_nand_host *, int); u32 (*get_ecc_status)(struct mxc_nand_host *); struct nand_ecclayout *ecclayout_512, *ecclayout_2k, *ecclayout_4k; const struct mtd_ooblayout_ops *ooblayout; void (*select_chip)(struct mtd_info *mtd, int chip); int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); Loading Loading @@ -200,73 +200,6 @@ struct mxc_nand_host { struct mxc_nand_platform_data pdata; }; /* OOB placement block for use with hardware ecc generation */ static struct nand_ecclayout nandv1_hw_eccoob_smallpage = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, .oobfree = {{0, 5}, {12, 4}, } }; static struct nand_ecclayout nandv1_hw_eccoob_largepage = { .eccbytes = 20, .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26, 38, 39, 40, 41, 42, 54, 55, 56, 57, 58}, .oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, } }; /* OOB description for 512 byte pages with 16 byte OOB */ static struct nand_ecclayout nandv2_hw_eccoob_smallpage = { .eccbytes = 1 * 9, .eccpos = { 7, 8, 9, 10, 11, 12, 13, 14, 15 }, .oobfree = { {.offset = 0, .length = 5} } }; /* OOB description for 2048 byte pages with 64 byte OOB */ static struct nand_ecclayout nandv2_hw_eccoob_largepage = { .eccbytes = 4 * 9, .eccpos = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26, 27, 28, 29, 30, 31, 39, 40, 41, 42, 43, 44, 45, 46, 47, 55, 56, 57, 58, 59, 60, 61, 62, 63 }, .oobfree = { {.offset = 2, .length = 4}, {.offset = 16, .length = 7}, {.offset = 32, .length = 7}, {.offset = 48, .length = 7} } }; /* OOB description for 4096 byte pages with 128 byte OOB */ static struct nand_ecclayout nandv2_hw_eccoob_4k = { .eccbytes = 8 * 9, .eccpos = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26, 27, 28, 29, 30, 31, 39, 40, 41, 42, 43, 44, 45, 46, 47, 55, 56, 57, 58, 59, 60, 61, 62, 63, 71, 72, 73, 74, 75, 76, 77, 78, 79, 87, 88, 89, 90, 91, 92, 93, 94, 95, 103, 104, 105, 106, 107, 108, 109, 110, 111, 119, 120, 121, 122, 123, 124, 125, 126, 127, }, .oobfree = { {.offset = 2, .length = 4}, {.offset = 16, .length = 7}, {.offset = 32, .length = 7}, {.offset = 48, .length = 7}, {.offset = 64, .length = 7}, {.offset = 80, .length = 7}, {.offset = 96, .length = 7}, {.offset = 112, .length = 7}, } }; static const char * const part_probes[] = { "cmdlinepart", "RedBoot", "ofpart", NULL }; Loading Loading @@ -942,6 +875,99 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) } } static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); if (section >= nand_chip->ecc.steps) return -ERANGE; oobregion->offset = (section * 16) + 6; oobregion->length = nand_chip->ecc.bytes; return 0; } static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); if (section > nand_chip->ecc.steps) return -ERANGE; if (!section) { if (mtd->writesize <= 512) { oobregion->offset = 0; oobregion->length = 5; } else { oobregion->offset = 2; oobregion->length = 4; } } else { oobregion->offset = ((section - 1) * 16) + nand_chip->ecc.bytes + 6; if (section < nand_chip->ecc.steps) oobregion->length = (section * 16) + 6 - oobregion->offset; else oobregion->length = mtd->oobsize - oobregion->offset; } return 0; } static const struct mtd_ooblayout_ops mxc_v1_ooblayout_ops = { .ecc = mxc_v1_ooblayout_ecc, .free = mxc_v1_ooblayout_free, }; static int mxc_v2_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; if (section >= nand_chip->ecc.steps) return -ERANGE; oobregion->offset = (section * stepsize) + 7; oobregion->length = nand_chip->ecc.bytes; return 0; } static int mxc_v2_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; if (section > nand_chip->ecc.steps) return -ERANGE; if (!section) { if (mtd->writesize <= 512) { oobregion->offset = 0; oobregion->length = 5; } else { oobregion->offset = 2; oobregion->length = 4; } } else { oobregion->offset = section * stepsize; oobregion->length = 7; } return 0; } static const struct mtd_ooblayout_ops mxc_v2_ooblayout_ops = { .ecc = mxc_v2_ooblayout_ecc, .free = mxc_v2_ooblayout_free, }; /* * v2 and v3 type controllers can do 4bit or 8bit ecc depending * on how much oob the nand chip has. For 8bit ecc we need at least Loading @@ -959,23 +985,6 @@ static int get_eccsize(struct mtd_info *mtd) return 8; } static void ecc_8bit_layout_4k(struct nand_ecclayout *layout) { int i, j; layout->eccbytes = 8*18; for (i = 0; i < 8; i++) for (j = 0; j < 18; j++) layout->eccpos[i*18 + j] = i*26 + j + 7; layout->oobfree[0].offset = 2; layout->oobfree[0].length = 4; for (i = 1; i < 8; i++) { layout->oobfree[i].offset = i*26; layout->oobfree[i].length = 7; } } static void preset_v1(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); Loading Loading @@ -1269,9 +1278,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { .check_int = check_int_v1_v2, .irq_control = irq_control_v1_v2, .get_ecc_status = get_ecc_status_v1, .ecclayout_512 = &nandv1_hw_eccoob_smallpage, .ecclayout_2k = &nandv1_hw_eccoob_largepage, .ecclayout_4k = &nandv1_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v1_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v1, .irqpending_quirk = 1, Loading @@ -1294,9 +1301,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { .check_int = check_int_v1_v2, .irq_control = irq_control_v1_v2, .get_ecc_status = get_ecc_status_v1, .ecclayout_512 = &nandv1_hw_eccoob_smallpage, .ecclayout_2k = &nandv1_hw_eccoob_largepage, .ecclayout_4k = &nandv1_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v1_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v1, .irqpending_quirk = 0, Loading @@ -1320,9 +1325,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { .check_int = check_int_v1_v2, .irq_control = irq_control_v1_v2, .get_ecc_status = get_ecc_status_v2, .ecclayout_512 = &nandv2_hw_eccoob_smallpage, .ecclayout_2k = &nandv2_hw_eccoob_largepage, .ecclayout_4k = &nandv2_hw_eccoob_4k, .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v2, .correct_data = mxc_nand_correct_data_v2_v3, .irqpending_quirk = 0, Loading @@ -1346,9 +1349,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { .check_int = check_int_v3, .irq_control = irq_control_v3, .get_ecc_status = get_ecc_status_v3, .ecclayout_512 = &nandv2_hw_eccoob_smallpage, .ecclayout_2k = &nandv2_hw_eccoob_largepage, .ecclayout_4k = &nandv2_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v2_v3, .irqpending_quirk = 0, Loading @@ -1373,9 +1374,7 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = { .check_int = check_int_v3, .irq_control = irq_control_v3, .get_ecc_status = get_ecc_status_v3, .ecclayout_512 = &nandv2_hw_eccoob_smallpage, .ecclayout_2k = &nandv2_hw_eccoob_largepage, .ecclayout_4k = &nandv2_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v2_v3, .irqpending_quirk = 0, Loading Loading @@ -1576,7 +1575,7 @@ static int mxcnd_probe(struct platform_device *pdev) this->select_chip = host->devtype_data->select_chip; this->ecc.size = 512; this->ecc.layout = host->devtype_data->ecclayout_512; mtd_set_ooblayout(mtd, host->devtype_data->ooblayout); if (host->pdata.hw_ecc) { this->ecc.calculate = mxc_nand_calculate_ecc; Loading Loading @@ -1650,12 +1649,11 @@ static int mxcnd_probe(struct platform_device *pdev) /* Call preset again, with correct writesize this time */ host->devtype_data->preset(mtd); if (mtd->writesize == 2048) this->ecc.layout = host->devtype_data->ecclayout_2k; else if (mtd->writesize == 4096) { this->ecc.layout = host->devtype_data->ecclayout_4k; if (get_eccsize(mtd) == 8) ecc_8bit_layout_4k(this->ecc.layout); if (!this->ecc.bytes) { if (host->eccsize == 8) this->ecc.bytes = 18; else if (host->eccsize == 4) this->ecc.bytes = 9; } /* Loading Loading
drivers/mtd/nand/mxc_nand.c +105 −107 Original line number Diff line number Diff line Loading @@ -149,7 +149,7 @@ struct mxc_nand_devtype_data { int (*check_int)(struct mxc_nand_host *); void (*irq_control)(struct mxc_nand_host *, int); u32 (*get_ecc_status)(struct mxc_nand_host *); struct nand_ecclayout *ecclayout_512, *ecclayout_2k, *ecclayout_4k; const struct mtd_ooblayout_ops *ooblayout; void (*select_chip)(struct mtd_info *mtd, int chip); int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); Loading Loading @@ -200,73 +200,6 @@ struct mxc_nand_host { struct mxc_nand_platform_data pdata; }; /* OOB placement block for use with hardware ecc generation */ static struct nand_ecclayout nandv1_hw_eccoob_smallpage = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, .oobfree = {{0, 5}, {12, 4}, } }; static struct nand_ecclayout nandv1_hw_eccoob_largepage = { .eccbytes = 20, .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26, 38, 39, 40, 41, 42, 54, 55, 56, 57, 58}, .oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, } }; /* OOB description for 512 byte pages with 16 byte OOB */ static struct nand_ecclayout nandv2_hw_eccoob_smallpage = { .eccbytes = 1 * 9, .eccpos = { 7, 8, 9, 10, 11, 12, 13, 14, 15 }, .oobfree = { {.offset = 0, .length = 5} } }; /* OOB description for 2048 byte pages with 64 byte OOB */ static struct nand_ecclayout nandv2_hw_eccoob_largepage = { .eccbytes = 4 * 9, .eccpos = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26, 27, 28, 29, 30, 31, 39, 40, 41, 42, 43, 44, 45, 46, 47, 55, 56, 57, 58, 59, 60, 61, 62, 63 }, .oobfree = { {.offset = 2, .length = 4}, {.offset = 16, .length = 7}, {.offset = 32, .length = 7}, {.offset = 48, .length = 7} } }; /* OOB description for 4096 byte pages with 128 byte OOB */ static struct nand_ecclayout nandv2_hw_eccoob_4k = { .eccbytes = 8 * 9, .eccpos = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26, 27, 28, 29, 30, 31, 39, 40, 41, 42, 43, 44, 45, 46, 47, 55, 56, 57, 58, 59, 60, 61, 62, 63, 71, 72, 73, 74, 75, 76, 77, 78, 79, 87, 88, 89, 90, 91, 92, 93, 94, 95, 103, 104, 105, 106, 107, 108, 109, 110, 111, 119, 120, 121, 122, 123, 124, 125, 126, 127, }, .oobfree = { {.offset = 2, .length = 4}, {.offset = 16, .length = 7}, {.offset = 32, .length = 7}, {.offset = 48, .length = 7}, {.offset = 64, .length = 7}, {.offset = 80, .length = 7}, {.offset = 96, .length = 7}, {.offset = 112, .length = 7}, } }; static const char * const part_probes[] = { "cmdlinepart", "RedBoot", "ofpart", NULL }; Loading Loading @@ -942,6 +875,99 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) } } static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); if (section >= nand_chip->ecc.steps) return -ERANGE; oobregion->offset = (section * 16) + 6; oobregion->length = nand_chip->ecc.bytes; return 0; } static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); if (section > nand_chip->ecc.steps) return -ERANGE; if (!section) { if (mtd->writesize <= 512) { oobregion->offset = 0; oobregion->length = 5; } else { oobregion->offset = 2; oobregion->length = 4; } } else { oobregion->offset = ((section - 1) * 16) + nand_chip->ecc.bytes + 6; if (section < nand_chip->ecc.steps) oobregion->length = (section * 16) + 6 - oobregion->offset; else oobregion->length = mtd->oobsize - oobregion->offset; } return 0; } static const struct mtd_ooblayout_ops mxc_v1_ooblayout_ops = { .ecc = mxc_v1_ooblayout_ecc, .free = mxc_v1_ooblayout_free, }; static int mxc_v2_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; if (section >= nand_chip->ecc.steps) return -ERANGE; oobregion->offset = (section * stepsize) + 7; oobregion->length = nand_chip->ecc.bytes; return 0; } static int mxc_v2_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *nand_chip = mtd_to_nand(mtd); int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; if (section > nand_chip->ecc.steps) return -ERANGE; if (!section) { if (mtd->writesize <= 512) { oobregion->offset = 0; oobregion->length = 5; } else { oobregion->offset = 2; oobregion->length = 4; } } else { oobregion->offset = section * stepsize; oobregion->length = 7; } return 0; } static const struct mtd_ooblayout_ops mxc_v2_ooblayout_ops = { .ecc = mxc_v2_ooblayout_ecc, .free = mxc_v2_ooblayout_free, }; /* * v2 and v3 type controllers can do 4bit or 8bit ecc depending * on how much oob the nand chip has. For 8bit ecc we need at least Loading @@ -959,23 +985,6 @@ static int get_eccsize(struct mtd_info *mtd) return 8; } static void ecc_8bit_layout_4k(struct nand_ecclayout *layout) { int i, j; layout->eccbytes = 8*18; for (i = 0; i < 8; i++) for (j = 0; j < 18; j++) layout->eccpos[i*18 + j] = i*26 + j + 7; layout->oobfree[0].offset = 2; layout->oobfree[0].length = 4; for (i = 1; i < 8; i++) { layout->oobfree[i].offset = i*26; layout->oobfree[i].length = 7; } } static void preset_v1(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); Loading Loading @@ -1269,9 +1278,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { .check_int = check_int_v1_v2, .irq_control = irq_control_v1_v2, .get_ecc_status = get_ecc_status_v1, .ecclayout_512 = &nandv1_hw_eccoob_smallpage, .ecclayout_2k = &nandv1_hw_eccoob_largepage, .ecclayout_4k = &nandv1_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v1_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v1, .irqpending_quirk = 1, Loading @@ -1294,9 +1301,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { .check_int = check_int_v1_v2, .irq_control = irq_control_v1_v2, .get_ecc_status = get_ecc_status_v1, .ecclayout_512 = &nandv1_hw_eccoob_smallpage, .ecclayout_2k = &nandv1_hw_eccoob_largepage, .ecclayout_4k = &nandv1_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v1_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v1, .irqpending_quirk = 0, Loading @@ -1320,9 +1325,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { .check_int = check_int_v1_v2, .irq_control = irq_control_v1_v2, .get_ecc_status = get_ecc_status_v2, .ecclayout_512 = &nandv2_hw_eccoob_smallpage, .ecclayout_2k = &nandv2_hw_eccoob_largepage, .ecclayout_4k = &nandv2_hw_eccoob_4k, .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v2, .correct_data = mxc_nand_correct_data_v2_v3, .irqpending_quirk = 0, Loading @@ -1346,9 +1349,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { .check_int = check_int_v3, .irq_control = irq_control_v3, .get_ecc_status = get_ecc_status_v3, .ecclayout_512 = &nandv2_hw_eccoob_smallpage, .ecclayout_2k = &nandv2_hw_eccoob_largepage, .ecclayout_4k = &nandv2_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v2_v3, .irqpending_quirk = 0, Loading @@ -1373,9 +1374,7 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = { .check_int = check_int_v3, .irq_control = irq_control_v3, .get_ecc_status = get_ecc_status_v3, .ecclayout_512 = &nandv2_hw_eccoob_smallpage, .ecclayout_2k = &nandv2_hw_eccoob_largepage, .ecclayout_4k = &nandv2_hw_eccoob_smallpage, /* XXX: needs fix */ .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, .correct_data = mxc_nand_correct_data_v2_v3, .irqpending_quirk = 0, Loading Loading @@ -1576,7 +1575,7 @@ static int mxcnd_probe(struct platform_device *pdev) this->select_chip = host->devtype_data->select_chip; this->ecc.size = 512; this->ecc.layout = host->devtype_data->ecclayout_512; mtd_set_ooblayout(mtd, host->devtype_data->ooblayout); if (host->pdata.hw_ecc) { this->ecc.calculate = mxc_nand_calculate_ecc; Loading Loading @@ -1650,12 +1649,11 @@ static int mxcnd_probe(struct platform_device *pdev) /* Call preset again, with correct writesize this time */ host->devtype_data->preset(mtd); if (mtd->writesize == 2048) this->ecc.layout = host->devtype_data->ecclayout_2k; else if (mtd->writesize == 4096) { this->ecc.layout = host->devtype_data->ecclayout_4k; if (get_eccsize(mtd) == 8) ecc_8bit_layout_4k(this->ecc.layout); if (!this->ecc.bytes) { if (host->eccsize == 8) this->ecc.bytes = 18; else if (host->eccsize == 4) this->ecc.bytes = 9; } /* Loading