Lines Matching full:ecc
22 * if we have HW ECC support.
38 #include <linux/mtd/nand-ecc-sw-hamming.h>
39 #include <linux/mtd/nand-ecc-sw-bch.h>
263 res = chip->ecc.read_oob(chip, first_page + page_offset); in nand_block_bad()
472 status = chip->ecc.write_oob_raw(chip, page & chip->pagemask); in nand_do_write_oob()
474 status = chip->ecc.write_oob(chip, page & chip->pagemask); in nand_do_write_oob()
2709 * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
2713 * @ecc: ECC buffer
2714 * @ecclen: ECC length
2719 * Check if a data buffer and its associated ECC and OOB data contains only
2726 * 1/ ECC algorithms are working on pre-defined block sizes which are usually
2727 * different from the NAND page size. When fixing bitflips, ECC engines will
2734 * the payload data but also their associated ECC data, because a user might
2736 * shouldn't consider the chunk as erased, and checking ECC bytes prevent
2739 * data are protected by the ECC engine.
2741 * extra OOB data to an ECC chunk.
2748 void *ecc, int ecclen, in nand_check_erased_ecc_chunk() argument
2761 ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold); in nand_check_erased_ecc_chunk()
2776 memset(ecc, 0xff, ecclen); in nand_check_erased_ecc_chunk()
2801 * nand_read_page_raw - [INTERN] read raw page data without ecc
2807 * Not for syndrome calculating ECC controllers, which use a special oob layout.
2872 * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
2884 int eccsize = chip->ecc.size; in nand_read_page_raw_syndrome()
2885 int eccbytes = chip->ecc.bytes; in nand_read_page_raw_syndrome()
2893 for (steps = chip->ecc.steps; steps > 0; steps--) { in nand_read_page_raw_syndrome()
2900 if (chip->ecc.prepad) { in nand_read_page_raw_syndrome()
2901 ret = nand_read_data_op(chip, oob, chip->ecc.prepad, in nand_read_page_raw_syndrome()
2906 oob += chip->ecc.prepad; in nand_read_page_raw_syndrome()
2915 if (chip->ecc.postpad) { in nand_read_page_raw_syndrome()
2916 ret = nand_read_data_op(chip, oob, chip->ecc.postpad, in nand_read_page_raw_syndrome()
2921 oob += chip->ecc.postpad; in nand_read_page_raw_syndrome()
2936 * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
2946 int i, eccsize = chip->ecc.size, ret; in nand_read_page_swecc()
2947 int eccbytes = chip->ecc.bytes; in nand_read_page_swecc()
2948 int eccsteps = chip->ecc.steps; in nand_read_page_swecc()
2950 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_read_page_swecc()
2951 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_swecc()
2954 chip->ecc.read_page_raw(chip, buf, 1, page); in nand_read_page_swecc()
2957 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_read_page_swecc()
2960 chip->ecc.total); in nand_read_page_swecc()
2964 eccsteps = chip->ecc.steps; in nand_read_page_swecc()
2970 stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]); in nand_read_page_swecc()
2982 * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function
3002 /* Column address within the page aligned to ECC size (256bytes) */ in nand_read_subpage()
3003 start_step = data_offs / chip->ecc.size; in nand_read_subpage()
3004 end_step = (data_offs + readlen - 1) / chip->ecc.size; in nand_read_subpage()
3006 index = start_step * chip->ecc.bytes; in nand_read_subpage()
3008 /* Data size aligned to ECC ecc.size */ in nand_read_subpage()
3009 datafrag_len = num_steps * chip->ecc.size; in nand_read_subpage()
3010 eccfrag_len = num_steps * chip->ecc.bytes; in nand_read_subpage()
3012 data_col_addr = start_step * chip->ecc.size; in nand_read_subpage()
3019 /* Calculate ECC */ in nand_read_subpage()
3020 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) in nand_read_subpage()
3021 chip->ecc.calculate(chip, p, &chip->ecc.calc_buf[i]); in nand_read_subpage()
3025 * ecc.pos. Let's make sure that there are no gaps in ECC positions. in nand_read_subpage()
3042 * Send the command to read the particular ECC bytes take care in nand_read_subpage()
3049 if ((oobregion.offset + (num_steps * chip->ecc.bytes)) & in nand_read_subpage()
3061 ret = mtd_ooblayout_get_eccbytes(mtd, chip->ecc.code_buf, in nand_read_subpage()
3067 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { in nand_read_subpage()
3070 stat = chip->ecc.correct(chip, p, &chip->ecc.code_buf[i], in nand_read_subpage()
3071 &chip->ecc.calc_buf[i]); in nand_read_subpage()
3073 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_subpage()
3075 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, in nand_read_subpage()
3076 &chip->ecc.code_buf[i], in nand_read_subpage()
3077 chip->ecc.bytes, in nand_read_subpage()
3079 chip->ecc.strength); in nand_read_subpage()
3093 * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
3099 * Not for syndrome calculating ECC controllers which need a special oob layout.
3105 int i, eccsize = chip->ecc.size, ret; in nand_read_page_hwecc()
3106 int eccbytes = chip->ecc.bytes; in nand_read_page_hwecc()
3107 int eccsteps = chip->ecc.steps; in nand_read_page_hwecc()
3109 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_read_page_hwecc()
3110 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_hwecc()
3118 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_hwecc()
3124 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_read_page_hwecc()
3133 chip->ecc.total); in nand_read_page_hwecc()
3137 eccsteps = chip->ecc.steps; in nand_read_page_hwecc()
3143 stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]); in nand_read_page_hwecc()
3145 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_hwecc()
3150 chip->ecc.strength); in nand_read_page_hwecc()
3164 * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
3177 int ret, i, eccsize = chip->ecc.size; in nand_read_page_syndrome()
3178 int eccbytes = chip->ecc.bytes; in nand_read_page_syndrome()
3179 int eccsteps = chip->ecc.steps; in nand_read_page_syndrome()
3180 int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad; in nand_read_page_syndrome()
3192 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_syndrome()
3198 if (chip->ecc.prepad) { in nand_read_page_syndrome()
3199 ret = nand_read_data_op(chip, oob, chip->ecc.prepad, in nand_read_page_syndrome()
3204 oob += chip->ecc.prepad; in nand_read_page_syndrome()
3207 chip->ecc.hwctl(chip, NAND_ECC_READSYN); in nand_read_page_syndrome()
3213 stat = chip->ecc.correct(chip, p, oob, NULL); in nand_read_page_syndrome()
3217 if (chip->ecc.postpad) { in nand_read_page_syndrome()
3218 ret = nand_read_data_op(chip, oob, chip->ecc.postpad, in nand_read_page_syndrome()
3223 oob += chip->ecc.postpad; in nand_read_page_syndrome()
3227 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_syndrome()
3229 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, in nand_read_page_syndrome()
3233 chip->ecc.strength); in nand_read_page_syndrome()
3293 * when there are too many bitflips in a page (i.e., ECC error). After setting
3321 * nand_do_read_ops - [INTERN] Read data with ECC
3386 * the read methods return max bitflips per ecc step. in nand_do_read_ops()
3389 ret = chip->ecc.read_page_raw(chip, bufpoi, in nand_do_read_ops()
3394 ret = chip->ecc.read_subpage(chip, col, bytes, in nand_do_read_ops()
3397 ret = chip->ecc.read_page(chip, bufpoi, in nand_do_read_ops()
3516 * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
3525 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; in nand_read_oob_syndrome()
3526 int eccsize = chip->ecc.size; in nand_read_oob_syndrome()
3530 ret = nand_read_page_op(chip, page, chip->ecc.size, NULL, 0); in nand_read_oob_syndrome()
3534 for (i = 0; i < chip->ecc.steps; i++) { in nand_read_oob_syndrome()
3584 * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
3592 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; in nand_write_oob_syndrome()
3593 int eccsize = chip->ecc.size, length = mtd->oobsize; in nand_write_oob_syndrome()
3594 int ret, i, len, pos, sndcmd = 0, steps = chip->ecc.steps; in nand_write_oob_syndrome()
3598 * data-ecc-data-ecc ... ecc-oob in nand_write_oob_syndrome()
3600 * data-pad-ecc-pad-data-pad .... ecc-pad-oob in nand_write_oob_syndrome()
3602 if (!chip->ecc.prepad && !chip->ecc.postpad) { in nand_write_oob_syndrome()
3696 ret = chip->ecc.read_oob_raw(chip, page); in nand_do_read_oob()
3698 ret = chip->ecc.read_oob(chip, page); in nand_do_read_oob()
3794 * Not for syndrome calculating ECC controllers, which use a special oob layout.
3860 * We need a special oob layout and handling even when ECC isn't checked.
3867 int eccsize = chip->ecc.size; in nand_write_page_raw_syndrome()
3868 int eccbytes = chip->ecc.bytes; in nand_write_page_raw_syndrome()
3876 for (steps = chip->ecc.steps; steps > 0; steps--) { in nand_write_page_raw_syndrome()
3883 if (chip->ecc.prepad) { in nand_write_page_raw_syndrome()
3884 ret = nand_write_data_op(chip, oob, chip->ecc.prepad, in nand_write_page_raw_syndrome()
3889 oob += chip->ecc.prepad; in nand_write_page_raw_syndrome()
3898 if (chip->ecc.postpad) { in nand_write_page_raw_syndrome()
3899 ret = nand_write_data_op(chip, oob, chip->ecc.postpad, in nand_write_page_raw_syndrome()
3904 oob += chip->ecc.postpad; in nand_write_page_raw_syndrome()
3918 * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
3928 int i, eccsize = chip->ecc.size, ret; in nand_write_page_swecc()
3929 int eccbytes = chip->ecc.bytes; in nand_write_page_swecc()
3930 int eccsteps = chip->ecc.steps; in nand_write_page_swecc()
3931 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_page_swecc()
3934 /* Software ECC calculation */ in nand_write_page_swecc()
3936 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_write_page_swecc()
3939 chip->ecc.total); in nand_write_page_swecc()
3943 return chip->ecc.write_page_raw(chip, buf, 1, page); in nand_write_page_swecc()
3947 * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
3957 int i, eccsize = chip->ecc.size, ret; in nand_write_page_hwecc()
3958 int eccbytes = chip->ecc.bytes; in nand_write_page_hwecc()
3959 int eccsteps = chip->ecc.steps; in nand_write_page_hwecc()
3960 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_page_hwecc()
3968 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_page_hwecc()
3974 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_write_page_hwecc()
3978 chip->ecc.total); in nand_write_page_hwecc()
3991 * nand_write_subpage_hwecc - [REPLACEABLE] hardware ECC based subpage write
4005 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_subpage_hwecc()
4006 int ecc_size = chip->ecc.size; in nand_write_subpage_hwecc()
4007 int ecc_bytes = chip->ecc.bytes; in nand_write_subpage_hwecc()
4008 int ecc_steps = chip->ecc.steps; in nand_write_subpage_hwecc()
4020 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_subpage_hwecc()
4027 /* mask ECC of un-touched subpages by padding 0xFF */ in nand_write_subpage_hwecc()
4031 chip->ecc.calculate(chip, buf, ecc_calc); in nand_write_subpage_hwecc()
4043 /* copy calculated ECC for whole page to chip->buffer->oob */ in nand_write_subpage_hwecc()
4045 ecc_calc = chip->ecc.calc_buf; in nand_write_subpage_hwecc()
4047 chip->ecc.total); in nand_write_subpage_hwecc()
4061 * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
4074 int i, eccsize = chip->ecc.size; in nand_write_page_syndrome()
4075 int eccbytes = chip->ecc.bytes; in nand_write_page_syndrome()
4076 int eccsteps = chip->ecc.steps; in nand_write_page_syndrome()
4086 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_page_syndrome()
4092 if (chip->ecc.prepad) { in nand_write_page_syndrome()
4093 ret = nand_write_data_op(chip, oob, chip->ecc.prepad, in nand_write_page_syndrome()
4098 oob += chip->ecc.prepad; in nand_write_page_syndrome()
4101 chip->ecc.calculate(chip, p, oob); in nand_write_page_syndrome()
4109 if (chip->ecc.postpad) { in nand_write_page_syndrome()
4110 ret = nand_write_data_op(chip, oob, chip->ecc.postpad, in nand_write_page_syndrome()
4115 oob += chip->ecc.postpad; in nand_write_page_syndrome()
4148 chip->ecc.write_subpage) in nand_write_page()
4154 status = chip->ecc.write_page_raw(chip, buf, oob_required, in nand_write_page()
4157 status = chip->ecc.write_subpage(chip, offset, data_len, buf, in nand_write_page()
4160 status = chip->ecc.write_page(chip, buf, oob_required, page); in nand_write_page()
4171 * nand_do_write_ops - [INTERN] NAND write with ECC
4176 * NAND write with ECC.
4304 * panic_nand_write - [MTD Interface] NAND write with ECC
4311 * NAND write with ECC. Used when performing writes in interrupt context, this
5134 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_engine_type_legacy()
5167 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_placement_legacy()
5181 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_algo_legacy()
5195 struct nand_ecc_props *user_conf = &chip->base.ecc.user_conf; in of_get_nand_ecc_legacy_user_config()
5319 * ECC engine type, we will default to NAND_ECC_ENGINE_TYPE_ON_HOST. in rawnand_dt_init()
5321 nand->ecc.defaults.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in rawnand_dt_init()
5328 if (nand->ecc.user_conf.engine_type != NAND_ECC_ENGINE_TYPE_INVALID) in rawnand_dt_init()
5329 chip->ecc.engine_type = nand->ecc.user_conf.engine_type; in rawnand_dt_init()
5330 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) in rawnand_dt_init()
5331 chip->ecc.engine_type = nand->ecc.defaults.engine_type; in rawnand_dt_init()
5333 chip->ecc.placement = nand->ecc.user_conf.placement; in rawnand_dt_init()
5334 chip->ecc.algo = nand->ecc.user_conf.algo; in rawnand_dt_init()
5335 chip->ecc.strength = nand->ecc.user_conf.strength; in rawnand_dt_init()
5336 chip->ecc.size = nand->ecc.user_conf.step_size; in rawnand_dt_init()
5351 * to tweak some ECC-related parameters before nand_scan_tail(). This separation
5447 base->ecc.user_conf.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in rawnand_sw_hamming_init()
5448 base->ecc.user_conf.algo = NAND_ECC_ALGO_HAMMING; in rawnand_sw_hamming_init()
5449 base->ecc.user_conf.strength = chip->ecc.strength; in rawnand_sw_hamming_init()
5450 base->ecc.user_conf.step_size = chip->ecc.size; in rawnand_sw_hamming_init()
5456 engine_conf = base->ecc.ctx.priv; in rawnand_sw_hamming_init()
5458 if (chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER) in rawnand_sw_hamming_init()
5461 chip->ecc.size = base->ecc.ctx.conf.step_size; in rawnand_sw_hamming_init()
5462 chip->ecc.strength = base->ecc.ctx.conf.strength; in rawnand_sw_hamming_init()
5463 chip->ecc.total = base->ecc.ctx.total; in rawnand_sw_hamming_init()
5464 chip->ecc.steps = nanddev_get_ecc_nsteps(base); in rawnand_sw_hamming_init()
5465 chip->ecc.bytes = base->ecc.ctx.total / nanddev_get_ecc_nsteps(base); in rawnand_sw_hamming_init()
5506 base->ecc.user_conf.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in rawnand_sw_bch_init()
5507 base->ecc.user_conf.algo = NAND_ECC_ALGO_BCH; in rawnand_sw_bch_init()
5508 base->ecc.user_conf.step_size = chip->ecc.size; in rawnand_sw_bch_init()
5509 base->ecc.user_conf.strength = chip->ecc.strength; in rawnand_sw_bch_init()
5515 chip->ecc.size = ecc_conf->step_size; in rawnand_sw_bch_init()
5516 chip->ecc.strength = ecc_conf->strength; in rawnand_sw_bch_init()
5517 chip->ecc.total = base->ecc.ctx.total; in rawnand_sw_bch_init()
5518 chip->ecc.steps = nanddev_get_ecc_nsteps(base); in rawnand_sw_bch_init()
5519 chip->ecc.bytes = base->ecc.ctx.total / nanddev_get_ecc_nsteps(base); in rawnand_sw_bch_init()
5553 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_set_ecc_on_host_ops() local
5555 switch (ecc->placement) { in nand_set_ecc_on_host_ops()
5559 if (!ecc->read_page) in nand_set_ecc_on_host_ops()
5560 ecc->read_page = nand_read_page_hwecc; in nand_set_ecc_on_host_ops()
5561 if (!ecc->write_page) in nand_set_ecc_on_host_ops()
5562 ecc->write_page = nand_write_page_hwecc; in nand_set_ecc_on_host_ops()
5563 if (!ecc->read_page_raw) in nand_set_ecc_on_host_ops()
5564 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_on_host_ops()
5565 if (!ecc->write_page_raw) in nand_set_ecc_on_host_ops()
5566 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_on_host_ops()
5567 if (!ecc->read_oob) in nand_set_ecc_on_host_ops()
5568 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_on_host_ops()
5569 if (!ecc->write_oob) in nand_set_ecc_on_host_ops()
5570 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_on_host_ops()
5571 if (!ecc->read_subpage) in nand_set_ecc_on_host_ops()
5572 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_on_host_ops()
5573 if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) in nand_set_ecc_on_host_ops()
5574 ecc->write_subpage = nand_write_subpage_hwecc; in nand_set_ecc_on_host_ops()
5578 if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) && in nand_set_ecc_on_host_ops()
5579 (!ecc->read_page || in nand_set_ecc_on_host_ops()
5580 ecc->read_page == nand_read_page_hwecc || in nand_set_ecc_on_host_ops()
5581 !ecc->write_page || in nand_set_ecc_on_host_ops()
5582 ecc->write_page == nand_write_page_hwecc)) { in nand_set_ecc_on_host_ops()
5583 WARN(1, "No ECC functions supplied; hardware ECC not possible\n"); in nand_set_ecc_on_host_ops()
5587 if (!ecc->read_page) in nand_set_ecc_on_host_ops()
5588 ecc->read_page = nand_read_page_syndrome; in nand_set_ecc_on_host_ops()
5589 if (!ecc->write_page) in nand_set_ecc_on_host_ops()
5590 ecc->write_page = nand_write_page_syndrome; in nand_set_ecc_on_host_ops()
5591 if (!ecc->read_page_raw) in nand_set_ecc_on_host_ops()
5592 ecc->read_page_raw = nand_read_page_raw_syndrome; in nand_set_ecc_on_host_ops()
5593 if (!ecc->write_page_raw) in nand_set_ecc_on_host_ops()
5594 ecc->write_page_raw = nand_write_page_raw_syndrome; in nand_set_ecc_on_host_ops()
5595 if (!ecc->read_oob) in nand_set_ecc_on_host_ops()
5596 ecc->read_oob = nand_read_oob_syndrome; in nand_set_ecc_on_host_ops()
5597 if (!ecc->write_oob) in nand_set_ecc_on_host_ops()
5598 ecc->write_oob = nand_write_oob_syndrome; in nand_set_ecc_on_host_ops()
5603 ecc->placement); in nand_set_ecc_on_host_ops()
5614 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_set_ecc_soft_ops() local
5617 if (WARN_ON(ecc->engine_type != NAND_ECC_ENGINE_TYPE_SOFT)) in nand_set_ecc_soft_ops()
5620 switch (ecc->algo) { in nand_set_ecc_soft_ops()
5622 ecc->calculate = rawnand_sw_hamming_calculate; in nand_set_ecc_soft_ops()
5623 ecc->correct = rawnand_sw_hamming_correct; in nand_set_ecc_soft_ops()
5624 ecc->read_page = nand_read_page_swecc; in nand_set_ecc_soft_ops()
5625 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_soft_ops()
5626 ecc->write_page = nand_write_page_swecc; in nand_set_ecc_soft_ops()
5627 if (!ecc->read_page_raw) in nand_set_ecc_soft_ops()
5628 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_soft_ops()
5629 if (!ecc->write_page_raw) in nand_set_ecc_soft_ops()
5630 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_soft_ops()
5631 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_soft_ops()
5632 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_soft_ops()
5633 if (!ecc->size) in nand_set_ecc_soft_ops()
5634 ecc->size = 256; in nand_set_ecc_soft_ops()
5635 ecc->bytes = 3; in nand_set_ecc_soft_ops()
5636 ecc->strength = 1; in nand_set_ecc_soft_ops()
5639 ecc->options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; in nand_set_ecc_soft_ops()
5643 WARN(1, "Hamming ECC initialization failed!\n"); in nand_set_ecc_soft_ops()
5653 ecc->calculate = rawnand_sw_bch_calculate; in nand_set_ecc_soft_ops()
5654 ecc->correct = rawnand_sw_bch_correct; in nand_set_ecc_soft_ops()
5655 ecc->read_page = nand_read_page_swecc; in nand_set_ecc_soft_ops()
5656 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_soft_ops()
5657 ecc->write_page = nand_write_page_swecc; in nand_set_ecc_soft_ops()
5658 if (!ecc->read_page_raw) in nand_set_ecc_soft_ops()
5659 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_soft_ops()
5660 if (!ecc->write_page_raw) in nand_set_ecc_soft_ops()
5661 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_soft_ops()
5662 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_soft_ops()
5663 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_soft_ops()
5666 * We can only maximize ECC config when the default layout is in nand_set_ecc_soft_ops()
5670 if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH && in nand_set_ecc_soft_ops()
5672 nanddev->ecc.user_conf.flags &= ~NAND_ECC_MAXIMIZE_STRENGTH; in nand_set_ecc_soft_ops()
5676 WARN(1, "BCH ECC initialization failed!\n"); in nand_set_ecc_soft_ops()
5682 WARN(1, "Unsupported ECC algorithm!\n"); in nand_set_ecc_soft_ops()
5688 * nand_check_ecc_caps - check the sanity of preset ECC settings
5690 * @caps: ECC caps info structure
5691 * @oobavail: OOB size that the ECC engine can use
5693 * When ECC step size and strength are already set, check if they are supported
5694 * by the controller and the calculated ECC bytes fit within the chip's OOB.
5695 * On success, the calculated ECC bytes is set.
5703 int preset_step = chip->ecc.size; in nand_check_ecc_caps()
5704 int preset_strength = chip->ecc.strength; in nand_check_ecc_caps()
5724 pr_err("ECC (step, strength) = (%d, %d) does not fit in OOB", in nand_check_ecc_caps()
5729 chip->ecc.bytes = ecc_bytes; in nand_check_ecc_caps()
5735 pr_err("ECC (step, strength) = (%d, %d) not supported on this controller", in nand_check_ecc_caps()
5742 * nand_match_ecc_req - meet the chip's requirement with least ECC bytes
5744 * @caps: ECC engine caps info structure
5745 * @oobavail: OOB size that the ECC engine can use
5747 * If a chip's ECC requirement is provided, try to meet it with the least
5748 * number of ECC bytes (i.e. with the largest number of OOB-free bytes).
5749 * On success, the chosen ECC settings are set.
5804 * with the least number of ECC bytes. in nand_match_ecc_req()
5818 chip->ecc.size = best_step; in nand_match_ecc_req()
5819 chip->ecc.strength = best_strength; in nand_match_ecc_req()
5820 chip->ecc.bytes = best_ecc_bytes; in nand_match_ecc_req()
5826 * nand_maximize_ecc - choose the max ECC strength available
5828 * @caps: ECC engine caps info structure
5829 * @oobavail: OOB size that the ECC engine can use
5831 * Choose the max ECC strength that is supported on the controller, and can fit
5832 * within the chip's OOB. On success, the chosen ECC settings are set.
5850 /* If chip->ecc.size is already set, respect it */ in nand_maximize_ecc()
5851 if (chip->ecc.size && step_size != chip->ecc.size) in nand_maximize_ecc()
5888 chip->ecc.size = best_step; in nand_maximize_ecc()
5889 chip->ecc.strength = best_strength; in nand_maximize_ecc()
5890 chip->ecc.bytes = best_ecc_bytes; in nand_maximize_ecc()
5896 * nand_ecc_choose_conf - Set the ECC strength and ECC step size
5898 * @caps: ECC engine caps info structure
5899 * @oobavail: OOB size that the ECC engine can use
5901 * Choose the ECC configuration according to following logic.
5903 * 1. If both ECC step size and ECC strength are already set (usually by DT)
5905 * 2. If the user provided the nand-ecc-maximize property, then select maximum
5906 * ECC strength.
5907 * 3. Otherwise, try to match the ECC step size and ECC strength closest
5909 * requirement then fallback to the maximum ECC step size and ECC strength.
5911 * On success, the chosen ECC settings are set.
5922 if (chip->ecc.size && chip->ecc.strength) in nand_ecc_choose_conf()
5925 if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH) in nand_ecc_choose_conf()
5990 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_scan_tail() local
6022 !(ecc->engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in nand_scan_tail()
6023 ecc->algo == NAND_ECC_ALGO_BCH) && in nand_scan_tail()
6024 !(ecc->engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in nand_scan_tail()
6025 ecc->algo == NAND_ECC_ALGO_HAMMING)) { in nand_scan_tail()
6041 * page with ECC layout when ->oobsize <= 128 for in nand_scan_tail()
6044 if (ecc->engine_type == NAND_ECC_ENGINE_TYPE_NONE) { in nand_scan_tail()
6058 * Check ECC mode, default to software if 3byte/512byte hardware ECC is in nand_scan_tail()
6059 * selected and we have 256 byte pagesize fallback to software ECC in nand_scan_tail()
6062 switch (ecc->engine_type) { in nand_scan_tail()
6068 if (mtd->writesize >= ecc->size) { in nand_scan_tail()
6069 if (!ecc->strength) { in nand_scan_tail()
6070 WARN(1, "Driver must set ecc.strength when using hardware ECC\n"); in nand_scan_tail()
6076 pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", in nand_scan_tail()
6077 ecc->size, mtd->writesize); in nand_scan_tail()
6078 ecc->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_scan_tail()
6079 ecc->algo = NAND_ECC_ALGO_HAMMING; in nand_scan_tail()
6089 if (!ecc->read_page || !ecc->write_page) { in nand_scan_tail()
6090 WARN(1, "No ECC functions supplied; on-die ECC not possible\n"); in nand_scan_tail()
6094 if (!ecc->read_oob) in nand_scan_tail()
6095 ecc->read_oob = nand_read_oob_std; in nand_scan_tail()
6096 if (!ecc->write_oob) in nand_scan_tail()
6097 ecc->write_oob = nand_write_oob_std; in nand_scan_tail()
6102 ecc->read_page = nand_read_page_raw; in nand_scan_tail()
6103 ecc->write_page = nand_write_page_raw; in nand_scan_tail()
6104 ecc->read_oob = nand_read_oob_std; in nand_scan_tail()
6105 ecc->read_page_raw = nand_read_page_raw; in nand_scan_tail()
6106 ecc->write_page_raw = nand_write_page_raw; in nand_scan_tail()
6107 ecc->write_oob = nand_write_oob_std; in nand_scan_tail()
6108 ecc->size = mtd->writesize; in nand_scan_tail()
6109 ecc->bytes = 0; in nand_scan_tail()
6110 ecc->strength = 0; in nand_scan_tail()
6114 WARN(1, "Invalid NAND_ECC_MODE %d\n", ecc->engine_type); in nand_scan_tail()
6119 if (ecc->correct || ecc->calculate) { in nand_scan_tail()
6120 ecc->calc_buf = kmalloc(mtd->oobsize, GFP_KERNEL); in nand_scan_tail()
6121 ecc->code_buf = kmalloc(mtd->oobsize, GFP_KERNEL); in nand_scan_tail()
6122 if (!ecc->calc_buf || !ecc->code_buf) { in nand_scan_tail()
6129 if (!ecc->read_oob_raw) in nand_scan_tail()
6130 ecc->read_oob_raw = ecc->read_oob; in nand_scan_tail()
6131 if (!ecc->write_oob_raw) in nand_scan_tail()
6132 ecc->write_oob_raw = ecc->write_oob; in nand_scan_tail()
6134 /* propagate ecc info to mtd_info */ in nand_scan_tail()
6135 mtd->ecc_strength = ecc->strength; in nand_scan_tail()
6136 mtd->ecc_step_size = ecc->size; in nand_scan_tail()
6139 * Set the number of read / write steps for one page depending on ECC in nand_scan_tail()
6142 if (!ecc->steps) in nand_scan_tail()
6143 ecc->steps = mtd->writesize / ecc->size; in nand_scan_tail()
6144 if (ecc->steps * ecc->size != mtd->writesize) { in nand_scan_tail()
6145 WARN(1, "Invalid ECC parameters\n"); in nand_scan_tail()
6150 if (!ecc->total) { in nand_scan_tail()
6151 ecc->total = ecc->steps * ecc->bytes; in nand_scan_tail()
6152 chip->base.ecc.ctx.total = ecc->total; in nand_scan_tail()
6155 if (ecc->total > mtd->oobsize) { in nand_scan_tail()
6156 WARN(1, "Total number of ECC bytes exceeded oobsize\n"); in nand_scan_tail()
6171 /* ECC sanity check: warn if it's too weak */ in nand_scan_tail()
6173 …pr_warn("WARNING: %s: the ECC used on your system (%db/%dB) is too weak compared to the one requir… in nand_scan_tail()
6174 mtd->name, chip->ecc.strength, chip->ecc.size, in nand_scan_tail()
6178 /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */ in nand_scan_tail()
6180 switch (ecc->steps) { in nand_scan_tail()
6197 switch (ecc->engine_type) { in nand_scan_tail()
6288 kfree(ecc->code_buf); in nand_scan_tail()
6289 kfree(ecc->calc_buf); in nand_scan_tail()
6355 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT) { in nand_cleanup()
6356 if (chip->ecc.algo == NAND_ECC_ALGO_HAMMING) in nand_cleanup()
6358 else if (chip->ecc.algo == NAND_ECC_ALGO_BCH) in nand_cleanup()
6370 kfree(chip->ecc.code_buf); in nand_cleanup()
6371 kfree(chip->ecc.calc_buf); in nand_cleanup()