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>
262 res = chip->ecc.read_oob(chip, first_page + page_offset); in nand_block_bad()
479 status = chip->ecc.write_oob_raw(chip, page & chip->pagemask); in nand_do_write_oob()
481 status = chip->ecc.write_oob(chip, page & chip->pagemask); in nand_do_write_oob()
2841 * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
2845 * @ecc: ECC buffer
2846 * @ecclen: ECC length
2851 * Check if a data buffer and its associated ECC and OOB data contains only
2858 * 1/ ECC algorithms are working on pre-defined block sizes which are usually
2859 * different from the NAND page size. When fixing bitflips, ECC engines will
2866 * the payload data but also their associated ECC data, because a user might
2868 * shouldn't consider the chunk as erased, and checking ECC bytes prevent
2871 * data are protected by the ECC engine.
2873 * extra OOB data to an ECC chunk.
2880 void *ecc, int ecclen, in nand_check_erased_ecc_chunk() argument
2893 ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold); in nand_check_erased_ecc_chunk()
2908 memset(ecc, 0xff, ecclen); in nand_check_erased_ecc_chunk()
2933 * nand_read_page_raw - [INTERN] read raw page data without ecc
2939 * Not for syndrome calculating ECC controllers, which use a special oob layout.
3004 * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
3016 int eccsize = chip->ecc.size; in nand_read_page_raw_syndrome()
3017 int eccbytes = chip->ecc.bytes; in nand_read_page_raw_syndrome()
3025 for (steps = chip->ecc.steps; steps > 0; steps--) { in nand_read_page_raw_syndrome()
3032 if (chip->ecc.prepad) { in nand_read_page_raw_syndrome()
3033 ret = nand_read_data_op(chip, oob, chip->ecc.prepad, in nand_read_page_raw_syndrome()
3038 oob += chip->ecc.prepad; in nand_read_page_raw_syndrome()
3047 if (chip->ecc.postpad) { in nand_read_page_raw_syndrome()
3048 ret = nand_read_data_op(chip, oob, chip->ecc.postpad, in nand_read_page_raw_syndrome()
3053 oob += chip->ecc.postpad; in nand_read_page_raw_syndrome()
3068 * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
3078 int i, eccsize = chip->ecc.size, ret; in nand_read_page_swecc()
3079 int eccbytes = chip->ecc.bytes; in nand_read_page_swecc()
3080 int eccsteps = chip->ecc.steps; in nand_read_page_swecc()
3082 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_read_page_swecc()
3083 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_swecc()
3086 chip->ecc.read_page_raw(chip, buf, 1, page); in nand_read_page_swecc()
3089 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_read_page_swecc()
3092 chip->ecc.total); in nand_read_page_swecc()
3096 eccsteps = chip->ecc.steps; in nand_read_page_swecc()
3102 stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]); in nand_read_page_swecc()
3114 * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function
3134 /* Column address within the page aligned to ECC size (256bytes) */ in nand_read_subpage()
3135 start_step = data_offs / chip->ecc.size; in nand_read_subpage()
3136 end_step = (data_offs + readlen - 1) / chip->ecc.size; in nand_read_subpage()
3138 index = start_step * chip->ecc.bytes; in nand_read_subpage()
3140 /* Data size aligned to ECC ecc.size */ in nand_read_subpage()
3141 datafrag_len = num_steps * chip->ecc.size; in nand_read_subpage()
3142 eccfrag_len = num_steps * chip->ecc.bytes; in nand_read_subpage()
3144 data_col_addr = start_step * chip->ecc.size; in nand_read_subpage()
3151 /* Calculate ECC */ in nand_read_subpage()
3152 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) in nand_read_subpage()
3153 chip->ecc.calculate(chip, p, &chip->ecc.calc_buf[i]); in nand_read_subpage()
3157 * ecc.pos. Let's make sure that there are no gaps in ECC positions. in nand_read_subpage()
3174 * Send the command to read the particular ECC bytes take care in nand_read_subpage()
3181 if ((oobregion.offset + (num_steps * chip->ecc.bytes)) & in nand_read_subpage()
3193 ret = mtd_ooblayout_get_eccbytes(mtd, chip->ecc.code_buf, in nand_read_subpage()
3199 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { in nand_read_subpage()
3202 stat = chip->ecc.correct(chip, p, &chip->ecc.code_buf[i], in nand_read_subpage()
3203 &chip->ecc.calc_buf[i]); in nand_read_subpage()
3205 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_subpage()
3207 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, in nand_read_subpage()
3208 &chip->ecc.code_buf[i], in nand_read_subpage()
3209 chip->ecc.bytes, in nand_read_subpage()
3211 chip->ecc.strength); in nand_read_subpage()
3225 * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
3231 * Not for syndrome calculating ECC controllers which need a special oob layout.
3237 int i, eccsize = chip->ecc.size, ret; in nand_read_page_hwecc()
3238 int eccbytes = chip->ecc.bytes; in nand_read_page_hwecc()
3239 int eccsteps = chip->ecc.steps; in nand_read_page_hwecc()
3241 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_read_page_hwecc()
3242 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_hwecc()
3250 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_hwecc()
3256 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_read_page_hwecc()
3265 chip->ecc.total); in nand_read_page_hwecc()
3269 eccsteps = chip->ecc.steps; in nand_read_page_hwecc()
3275 stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]); in nand_read_page_hwecc()
3277 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_hwecc()
3282 chip->ecc.strength); in nand_read_page_hwecc()
3296 * nand_read_page_hwecc_oob_first - Hardware ECC page read with ECC
3303 * Hardware ECC for large page chips, which requires the ECC data to be
3310 int i, eccsize = chip->ecc.size, ret; in nand_read_page_hwecc_oob_first()
3311 int eccbytes = chip->ecc.bytes; in nand_read_page_hwecc_oob_first()
3312 int eccsteps = chip->ecc.steps; in nand_read_page_hwecc_oob_first()
3314 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_hwecc_oob_first()
3328 chip->ecc.total); in nand_read_page_hwecc_oob_first()
3335 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_hwecc_oob_first()
3341 stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); in nand_read_page_hwecc_oob_first()
3343 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_hwecc_oob_first()
3348 chip->ecc.strength); in nand_read_page_hwecc_oob_first()
3363 * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
3376 int ret, i, eccsize = chip->ecc.size; in nand_read_page_syndrome()
3377 int eccbytes = chip->ecc.bytes; in nand_read_page_syndrome()
3378 int eccsteps = chip->ecc.steps; in nand_read_page_syndrome()
3379 int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad; in nand_read_page_syndrome()
3391 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_syndrome()
3397 if (chip->ecc.prepad) { in nand_read_page_syndrome()
3398 ret = nand_read_data_op(chip, oob, chip->ecc.prepad, in nand_read_page_syndrome()
3403 oob += chip->ecc.prepad; in nand_read_page_syndrome()
3406 chip->ecc.hwctl(chip, NAND_ECC_READSYN); in nand_read_page_syndrome()
3412 stat = chip->ecc.correct(chip, p, oob, NULL); in nand_read_page_syndrome()
3416 if (chip->ecc.postpad) { in nand_read_page_syndrome()
3417 ret = nand_read_data_op(chip, oob, chip->ecc.postpad, in nand_read_page_syndrome()
3422 oob += chip->ecc.postpad; in nand_read_page_syndrome()
3426 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_syndrome()
3428 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, in nand_read_page_syndrome()
3432 chip->ecc.strength); in nand_read_page_syndrome()
3537 * when there are too many bitflips in a page (i.e., ECC error). After setting
3565 * nand_do_read_ops - [INTERN] Read data with ECC
3633 * the read methods return max bitflips per ecc step. in nand_do_read_ops()
3636 ret = chip->ecc.read_page_raw(chip, bufpoi, in nand_do_read_ops()
3641 ret = chip->ecc.read_subpage(chip, col, bytes, in nand_do_read_ops()
3644 ret = chip->ecc.read_page(chip, bufpoi, in nand_do_read_ops()
3768 * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
3777 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; in nand_read_oob_syndrome()
3778 int eccsize = chip->ecc.size; in nand_read_oob_syndrome()
3782 ret = nand_read_page_op(chip, page, chip->ecc.size, NULL, 0); in nand_read_oob_syndrome()
3786 for (i = 0; i < chip->ecc.steps; i++) { in nand_read_oob_syndrome()
3836 * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
3844 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; in nand_write_oob_syndrome()
3845 int eccsize = chip->ecc.size, length = mtd->oobsize; in nand_write_oob_syndrome()
3846 int ret, i, len, pos, sndcmd = 0, steps = chip->ecc.steps; in nand_write_oob_syndrome()
3850 * data-ecc-data-ecc ... ecc-oob in nand_write_oob_syndrome()
3852 * data-pad-ecc-pad-data-pad .... ecc-pad-oob in nand_write_oob_syndrome()
3854 if (!chip->ecc.prepad && !chip->ecc.postpad) { in nand_write_oob_syndrome()
3948 ret = chip->ecc.read_oob_raw(chip, page); in nand_do_read_oob()
3950 ret = chip->ecc.read_oob(chip, page); in nand_do_read_oob()
4054 * Not for syndrome calculating ECC controllers, which use a special oob layout.
4120 * We need a special oob layout and handling even when ECC isn't checked.
4127 int eccsize = chip->ecc.size; in nand_write_page_raw_syndrome()
4128 int eccbytes = chip->ecc.bytes; in nand_write_page_raw_syndrome()
4136 for (steps = chip->ecc.steps; steps > 0; steps--) { in nand_write_page_raw_syndrome()
4143 if (chip->ecc.prepad) { in nand_write_page_raw_syndrome()
4144 ret = nand_write_data_op(chip, oob, chip->ecc.prepad, in nand_write_page_raw_syndrome()
4149 oob += chip->ecc.prepad; in nand_write_page_raw_syndrome()
4158 if (chip->ecc.postpad) { in nand_write_page_raw_syndrome()
4159 ret = nand_write_data_op(chip, oob, chip->ecc.postpad, in nand_write_page_raw_syndrome()
4164 oob += chip->ecc.postpad; in nand_write_page_raw_syndrome()
4178 * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
4188 int i, eccsize = chip->ecc.size, ret; in nand_write_page_swecc()
4189 int eccbytes = chip->ecc.bytes; in nand_write_page_swecc()
4190 int eccsteps = chip->ecc.steps; in nand_write_page_swecc()
4191 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_page_swecc()
4194 /* Software ECC calculation */ in nand_write_page_swecc()
4196 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_write_page_swecc()
4199 chip->ecc.total); in nand_write_page_swecc()
4203 return chip->ecc.write_page_raw(chip, buf, 1, page); in nand_write_page_swecc()
4207 * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
4217 int i, eccsize = chip->ecc.size, ret; in nand_write_page_hwecc()
4218 int eccbytes = chip->ecc.bytes; in nand_write_page_hwecc()
4219 int eccsteps = chip->ecc.steps; in nand_write_page_hwecc()
4220 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_page_hwecc()
4228 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_page_hwecc()
4234 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_write_page_hwecc()
4238 chip->ecc.total); in nand_write_page_hwecc()
4251 * nand_write_subpage_hwecc - [REPLACEABLE] hardware ECC based subpage write
4265 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_subpage_hwecc()
4266 int ecc_size = chip->ecc.size; in nand_write_subpage_hwecc()
4267 int ecc_bytes = chip->ecc.bytes; in nand_write_subpage_hwecc()
4268 int ecc_steps = chip->ecc.steps; in nand_write_subpage_hwecc()
4280 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_subpage_hwecc()
4287 /* mask ECC of un-touched subpages by padding 0xFF */ in nand_write_subpage_hwecc()
4291 chip->ecc.calculate(chip, buf, ecc_calc); in nand_write_subpage_hwecc()
4303 /* copy calculated ECC for whole page to chip->buffer->oob */ in nand_write_subpage_hwecc()
4305 ecc_calc = chip->ecc.calc_buf; in nand_write_subpage_hwecc()
4307 chip->ecc.total); in nand_write_subpage_hwecc()
4321 * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
4334 int i, eccsize = chip->ecc.size; in nand_write_page_syndrome()
4335 int eccbytes = chip->ecc.bytes; in nand_write_page_syndrome()
4336 int eccsteps = chip->ecc.steps; in nand_write_page_syndrome()
4346 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_page_syndrome()
4352 if (chip->ecc.prepad) { in nand_write_page_syndrome()
4353 ret = nand_write_data_op(chip, oob, chip->ecc.prepad, in nand_write_page_syndrome()
4358 oob += chip->ecc.prepad; in nand_write_page_syndrome()
4361 chip->ecc.calculate(chip, p, oob); in nand_write_page_syndrome()
4369 if (chip->ecc.postpad) { in nand_write_page_syndrome()
4370 ret = nand_write_data_op(chip, oob, chip->ecc.postpad, in nand_write_page_syndrome()
4375 oob += chip->ecc.postpad; in nand_write_page_syndrome()
4408 chip->ecc.write_subpage) in nand_write_page()
4414 status = chip->ecc.write_page_raw(chip, buf, oob_required, in nand_write_page()
4417 status = chip->ecc.write_subpage(chip, offset, data_len, buf, in nand_write_page()
4420 status = chip->ecc.write_page(chip, buf, oob_required, page); in nand_write_page()
4431 * nand_do_write_ops - [INTERN] NAND write with ECC
4436 * NAND write with ECC.
4564 * panic_nand_write - [MTD Interface] NAND write with ECC
4571 * NAND write with ECC. Used when performing writes in interrupt context, this
5217 * ECC correction enabled, so in this case refuse to perform the in rawnand_late_check_supported_ops()
5220 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_DIE) in rawnand_late_check_supported_ops()
5230 if (!(chip->ecc.read_page == nand_read_page_hwecc || in rawnand_late_check_supported_ops()
5231 chip->ecc.read_page == nand_read_page_syndrome || in rawnand_late_check_supported_ops()
5232 chip->ecc.read_page == nand_read_page_swecc)) in rawnand_late_check_supported_ops()
5454 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_engine_type_legacy()
5487 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_placement_legacy()
5501 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_algo_legacy()
5515 struct nand_ecc_props *user_conf = &chip->base.ecc.user_conf; in of_get_nand_ecc_legacy_user_config()
5639 * ECC engine type, we will default to NAND_ECC_ENGINE_TYPE_ON_HOST. in rawnand_dt_init()
5641 nand->ecc.defaults.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in rawnand_dt_init()
5648 if (nand->ecc.user_conf.engine_type != NAND_ECC_ENGINE_TYPE_INVALID) in rawnand_dt_init()
5649 chip->ecc.engine_type = nand->ecc.user_conf.engine_type; in rawnand_dt_init()
5650 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) in rawnand_dt_init()
5651 chip->ecc.engine_type = nand->ecc.defaults.engine_type; in rawnand_dt_init()
5653 chip->ecc.placement = nand->ecc.user_conf.placement; in rawnand_dt_init()
5654 chip->ecc.algo = nand->ecc.user_conf.algo; in rawnand_dt_init()
5655 chip->ecc.strength = nand->ecc.user_conf.strength; in rawnand_dt_init()
5656 chip->ecc.size = nand->ecc.user_conf.step_size; in rawnand_dt_init()
5671 * to tweak some ECC-related parameters before nand_scan_tail(). This separation
5768 base->ecc.user_conf.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in rawnand_sw_hamming_init()
5769 base->ecc.user_conf.algo = NAND_ECC_ALGO_HAMMING; in rawnand_sw_hamming_init()
5770 base->ecc.user_conf.strength = chip->ecc.strength; in rawnand_sw_hamming_init()
5771 base->ecc.user_conf.step_size = chip->ecc.size; in rawnand_sw_hamming_init()
5777 engine_conf = base->ecc.ctx.priv; in rawnand_sw_hamming_init()
5779 if (chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER) in rawnand_sw_hamming_init()
5782 chip->ecc.size = base->ecc.ctx.conf.step_size; in rawnand_sw_hamming_init()
5783 chip->ecc.strength = base->ecc.ctx.conf.strength; in rawnand_sw_hamming_init()
5784 chip->ecc.total = base->ecc.ctx.total; in rawnand_sw_hamming_init()
5785 chip->ecc.steps = nanddev_get_ecc_nsteps(base); in rawnand_sw_hamming_init()
5786 chip->ecc.bytes = base->ecc.ctx.total / nanddev_get_ecc_nsteps(base); in rawnand_sw_hamming_init()
5827 base->ecc.user_conf.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in rawnand_sw_bch_init()
5828 base->ecc.user_conf.algo = NAND_ECC_ALGO_BCH; in rawnand_sw_bch_init()
5829 base->ecc.user_conf.step_size = chip->ecc.size; in rawnand_sw_bch_init()
5830 base->ecc.user_conf.strength = chip->ecc.strength; in rawnand_sw_bch_init()
5836 chip->ecc.size = ecc_conf->step_size; in rawnand_sw_bch_init()
5837 chip->ecc.strength = ecc_conf->strength; in rawnand_sw_bch_init()
5838 chip->ecc.total = base->ecc.ctx.total; in rawnand_sw_bch_init()
5839 chip->ecc.steps = nanddev_get_ecc_nsteps(base); in rawnand_sw_bch_init()
5840 chip->ecc.bytes = base->ecc.ctx.total / nanddev_get_ecc_nsteps(base); in rawnand_sw_bch_init()
5874 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_set_ecc_on_host_ops() local
5876 switch (ecc->placement) { in nand_set_ecc_on_host_ops()
5880 if (!ecc->read_page) in nand_set_ecc_on_host_ops()
5881 ecc->read_page = nand_read_page_hwecc; in nand_set_ecc_on_host_ops()
5882 if (!ecc->write_page) in nand_set_ecc_on_host_ops()
5883 ecc->write_page = nand_write_page_hwecc; in nand_set_ecc_on_host_ops()
5884 if (!ecc->read_page_raw) in nand_set_ecc_on_host_ops()
5885 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_on_host_ops()
5886 if (!ecc->write_page_raw) in nand_set_ecc_on_host_ops()
5887 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_on_host_ops()
5888 if (!ecc->read_oob) in nand_set_ecc_on_host_ops()
5889 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_on_host_ops()
5890 if (!ecc->write_oob) in nand_set_ecc_on_host_ops()
5891 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_on_host_ops()
5892 if (!ecc->read_subpage) in nand_set_ecc_on_host_ops()
5893 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_on_host_ops()
5894 if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) in nand_set_ecc_on_host_ops()
5895 ecc->write_subpage = nand_write_subpage_hwecc; in nand_set_ecc_on_host_ops()
5899 if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) && in nand_set_ecc_on_host_ops()
5900 (!ecc->read_page || in nand_set_ecc_on_host_ops()
5901 ecc->read_page == nand_read_page_hwecc || in nand_set_ecc_on_host_ops()
5902 !ecc->write_page || in nand_set_ecc_on_host_ops()
5903 ecc->write_page == nand_write_page_hwecc)) { in nand_set_ecc_on_host_ops()
5904 WARN(1, "No ECC functions supplied; hardware ECC not possible\n"); in nand_set_ecc_on_host_ops()
5908 if (!ecc->read_page) in nand_set_ecc_on_host_ops()
5909 ecc->read_page = nand_read_page_syndrome; in nand_set_ecc_on_host_ops()
5910 if (!ecc->write_page) in nand_set_ecc_on_host_ops()
5911 ecc->write_page = nand_write_page_syndrome; in nand_set_ecc_on_host_ops()
5912 if (!ecc->read_page_raw) in nand_set_ecc_on_host_ops()
5913 ecc->read_page_raw = nand_read_page_raw_syndrome; in nand_set_ecc_on_host_ops()
5914 if (!ecc->write_page_raw) in nand_set_ecc_on_host_ops()
5915 ecc->write_page_raw = nand_write_page_raw_syndrome; in nand_set_ecc_on_host_ops()
5916 if (!ecc->read_oob) in nand_set_ecc_on_host_ops()
5917 ecc->read_oob = nand_read_oob_syndrome; in nand_set_ecc_on_host_ops()
5918 if (!ecc->write_oob) in nand_set_ecc_on_host_ops()
5919 ecc->write_oob = nand_write_oob_syndrome; in nand_set_ecc_on_host_ops()
5924 ecc->placement); in nand_set_ecc_on_host_ops()
5935 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_set_ecc_soft_ops() local
5938 if (WARN_ON(ecc->engine_type != NAND_ECC_ENGINE_TYPE_SOFT)) in nand_set_ecc_soft_ops()
5941 switch (ecc->algo) { in nand_set_ecc_soft_ops()
5943 ecc->calculate = rawnand_sw_hamming_calculate; in nand_set_ecc_soft_ops()
5944 ecc->correct = rawnand_sw_hamming_correct; in nand_set_ecc_soft_ops()
5945 ecc->read_page = nand_read_page_swecc; in nand_set_ecc_soft_ops()
5946 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_soft_ops()
5947 ecc->write_page = nand_write_page_swecc; in nand_set_ecc_soft_ops()
5948 if (!ecc->read_page_raw) in nand_set_ecc_soft_ops()
5949 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_soft_ops()
5950 if (!ecc->write_page_raw) in nand_set_ecc_soft_ops()
5951 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_soft_ops()
5952 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_soft_ops()
5953 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_soft_ops()
5954 if (!ecc->size) in nand_set_ecc_soft_ops()
5955 ecc->size = 256; in nand_set_ecc_soft_ops()
5956 ecc->bytes = 3; in nand_set_ecc_soft_ops()
5957 ecc->strength = 1; in nand_set_ecc_soft_ops()
5960 ecc->options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; in nand_set_ecc_soft_ops()
5964 WARN(1, "Hamming ECC initialization failed!\n"); in nand_set_ecc_soft_ops()
5974 ecc->calculate = rawnand_sw_bch_calculate; in nand_set_ecc_soft_ops()
5975 ecc->correct = rawnand_sw_bch_correct; in nand_set_ecc_soft_ops()
5976 ecc->read_page = nand_read_page_swecc; in nand_set_ecc_soft_ops()
5977 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_soft_ops()
5978 ecc->write_page = nand_write_page_swecc; in nand_set_ecc_soft_ops()
5979 if (!ecc->read_page_raw) in nand_set_ecc_soft_ops()
5980 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_soft_ops()
5981 if (!ecc->write_page_raw) in nand_set_ecc_soft_ops()
5982 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_soft_ops()
5983 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_soft_ops()
5984 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_soft_ops()
5987 * We can only maximize ECC config when the default layout is in nand_set_ecc_soft_ops()
5991 if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH && in nand_set_ecc_soft_ops()
5993 nanddev->ecc.user_conf.flags &= ~NAND_ECC_MAXIMIZE_STRENGTH; in nand_set_ecc_soft_ops()
5997 WARN(1, "BCH ECC initialization failed!\n"); in nand_set_ecc_soft_ops()
6003 WARN(1, "Unsupported ECC algorithm!\n"); in nand_set_ecc_soft_ops()
6009 * nand_check_ecc_caps - check the sanity of preset ECC settings
6011 * @caps: ECC caps info structure
6012 * @oobavail: OOB size that the ECC engine can use
6014 * When ECC step size and strength are already set, check if they are supported
6015 * by the controller and the calculated ECC bytes fit within the chip's OOB.
6016 * On success, the calculated ECC bytes is set.
6024 int preset_step = chip->ecc.size; in nand_check_ecc_caps()
6025 int preset_strength = chip->ecc.strength; in nand_check_ecc_caps()
6045 pr_err("ECC (step, strength) = (%d, %d) does not fit in OOB", in nand_check_ecc_caps()
6050 chip->ecc.bytes = ecc_bytes; in nand_check_ecc_caps()
6056 pr_err("ECC (step, strength) = (%d, %d) not supported on this controller", in nand_check_ecc_caps()
6063 * nand_match_ecc_req - meet the chip's requirement with least ECC bytes
6065 * @caps: ECC engine caps info structure
6066 * @oobavail: OOB size that the ECC engine can use
6068 * If a chip's ECC requirement is provided, try to meet it with the least
6069 * number of ECC bytes (i.e. with the largest number of OOB-free bytes).
6070 * On success, the chosen ECC settings are set.
6125 * with the least number of ECC bytes. in nand_match_ecc_req()
6139 chip->ecc.size = best_step; in nand_match_ecc_req()
6140 chip->ecc.strength = best_strength; in nand_match_ecc_req()
6141 chip->ecc.bytes = best_ecc_bytes; in nand_match_ecc_req()
6147 * nand_maximize_ecc - choose the max ECC strength available
6149 * @caps: ECC engine caps info structure
6150 * @oobavail: OOB size that the ECC engine can use
6152 * Choose the max ECC strength that is supported on the controller, and can fit
6153 * within the chip's OOB. On success, the chosen ECC settings are set.
6171 /* If chip->ecc.size is already set, respect it */ in nand_maximize_ecc()
6172 if (chip->ecc.size && step_size != chip->ecc.size) in nand_maximize_ecc()
6209 chip->ecc.size = best_step; in nand_maximize_ecc()
6210 chip->ecc.strength = best_strength; in nand_maximize_ecc()
6211 chip->ecc.bytes = best_ecc_bytes; in nand_maximize_ecc()
6217 * nand_ecc_choose_conf - Set the ECC strength and ECC step size
6219 * @caps: ECC engine caps info structure
6220 * @oobavail: OOB size that the ECC engine can use
6222 * Choose the ECC configuration according to following logic.
6224 * 1. If both ECC step size and ECC strength are already set (usually by DT)
6226 * 2. If the user provided the nand-ecc-maximize property, then select maximum
6227 * ECC strength.
6228 * 3. Otherwise, try to match the ECC step size and ECC strength closest
6230 * requirement then fallback to the maximum ECC step size and ECC strength.
6232 * On success, the chosen ECC settings are set.
6243 if (chip->ecc.size && chip->ecc.strength) in nand_ecc_choose_conf()
6246 if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH) in nand_ecc_choose_conf()
6312 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_scan_tail() local
6344 !(ecc->engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in nand_scan_tail()
6345 ecc->algo == NAND_ECC_ALGO_BCH) && in nand_scan_tail()
6346 !(ecc->engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in nand_scan_tail()
6347 ecc->algo == NAND_ECC_ALGO_HAMMING)) { in nand_scan_tail()
6363 * page with ECC layout when ->oobsize <= 128 for in nand_scan_tail()
6366 if (ecc->engine_type == NAND_ECC_ENGINE_TYPE_NONE) { in nand_scan_tail()
6380 * Check ECC mode, default to software if 3byte/512byte hardware ECC is in nand_scan_tail()
6381 * selected and we have 256 byte pagesize fallback to software ECC in nand_scan_tail()
6384 switch (ecc->engine_type) { in nand_scan_tail()
6390 if (mtd->writesize >= ecc->size) { in nand_scan_tail()
6391 if (!ecc->strength) { in nand_scan_tail()
6392 WARN(1, "Driver must set ecc.strength when using hardware ECC\n"); in nand_scan_tail()
6398 pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", in nand_scan_tail()
6399 ecc->size, mtd->writesize); in nand_scan_tail()
6400 ecc->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_scan_tail()
6401 ecc->algo = NAND_ECC_ALGO_HAMMING; in nand_scan_tail()
6411 if (!ecc->read_page || !ecc->write_page) { in nand_scan_tail()
6412 WARN(1, "No ECC functions supplied; on-die ECC not possible\n"); in nand_scan_tail()
6416 if (!ecc->read_oob) in nand_scan_tail()
6417 ecc->read_oob = nand_read_oob_std; in nand_scan_tail()
6418 if (!ecc->write_oob) in nand_scan_tail()
6419 ecc->write_oob = nand_write_oob_std; in nand_scan_tail()
6424 ecc->read_page = nand_read_page_raw; in nand_scan_tail()
6425 ecc->write_page = nand_write_page_raw; in nand_scan_tail()
6426 ecc->read_oob = nand_read_oob_std; in nand_scan_tail()
6427 ecc->read_page_raw = nand_read_page_raw; in nand_scan_tail()
6428 ecc->write_page_raw = nand_write_page_raw; in nand_scan_tail()
6429 ecc->write_oob = nand_write_oob_std; in nand_scan_tail()
6430 ecc->size = mtd->writesize; in nand_scan_tail()
6431 ecc->bytes = 0; in nand_scan_tail()
6432 ecc->strength = 0; in nand_scan_tail()
6436 WARN(1, "Invalid NAND_ECC_MODE %d\n", ecc->engine_type); in nand_scan_tail()
6441 if (ecc->correct || ecc->calculate) { in nand_scan_tail()
6442 ecc->calc_buf = kmalloc(mtd->oobsize, GFP_KERNEL); in nand_scan_tail()
6443 ecc->code_buf = kmalloc(mtd->oobsize, GFP_KERNEL); in nand_scan_tail()
6444 if (!ecc->calc_buf || !ecc->code_buf) { in nand_scan_tail()
6451 if (!ecc->read_oob_raw) in nand_scan_tail()
6452 ecc->read_oob_raw = ecc->read_oob; in nand_scan_tail()
6453 if (!ecc->write_oob_raw) in nand_scan_tail()
6454 ecc->write_oob_raw = ecc->write_oob; in nand_scan_tail()
6456 /* Propagate ECC info to the generic NAND and MTD layers */ in nand_scan_tail()
6457 mtd->ecc_strength = ecc->strength; in nand_scan_tail()
6458 if (!base->ecc.ctx.conf.strength) in nand_scan_tail()
6459 base->ecc.ctx.conf.strength = ecc->strength; in nand_scan_tail()
6460 mtd->ecc_step_size = ecc->size; in nand_scan_tail()
6461 if (!base->ecc.ctx.conf.step_size) in nand_scan_tail()
6462 base->ecc.ctx.conf.step_size = ecc->size; in nand_scan_tail()
6465 * Set the number of read / write steps for one page depending on ECC in nand_scan_tail()
6468 if (!ecc->steps) in nand_scan_tail()
6469 ecc->steps = mtd->writesize / ecc->size; in nand_scan_tail()
6470 if (!base->ecc.ctx.nsteps) in nand_scan_tail()
6471 base->ecc.ctx.nsteps = ecc->steps; in nand_scan_tail()
6472 if (ecc->steps * ecc->size != mtd->writesize) { in nand_scan_tail()
6473 WARN(1, "Invalid ECC parameters\n"); in nand_scan_tail()
6478 if (!ecc->total) { in nand_scan_tail()
6479 ecc->total = ecc->steps * ecc->bytes; in nand_scan_tail()
6480 chip->base.ecc.ctx.total = ecc->total; in nand_scan_tail()
6483 if (ecc->total > mtd->oobsize) { in nand_scan_tail()
6484 WARN(1, "Total number of ECC bytes exceeded oobsize\n"); in nand_scan_tail()
6499 /* ECC sanity check: warn if it's too weak */ in nand_scan_tail()
6501 …pr_warn("WARNING: %s: the ECC used on your system (%db/%dB) is too weak compared to the one requir… in nand_scan_tail()
6502 mtd->name, chip->ecc.strength, chip->ecc.size, in nand_scan_tail()
6506 /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */ in nand_scan_tail()
6508 switch (ecc->steps) { in nand_scan_tail()
6525 switch (ecc->engine_type) { in nand_scan_tail()
6618 kfree(ecc->code_buf); in nand_scan_tail()
6619 kfree(ecc->calc_buf); in nand_scan_tail()
6685 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT) { in nand_cleanup()
6686 if (chip->ecc.algo == NAND_ECC_ALGO_HAMMING) in nand_cleanup()
6688 else if (chip->ecc.algo == NAND_ECC_ALGO_BCH) in nand_cleanup()
6700 kfree(chip->ecc.code_buf); in nand_cleanup()
6701 kfree(chip->ecc.calc_buf); in nand_cleanup()