Lines Matching full:ecc

22  *	if we have HW ECC support.
262 res = chip->ecc.read_oob(chip, first_page + page_offset); in nand_block_bad()
430 status = chip->ecc.write_oob_raw(chip, page & chip->pagemask); in nand_do_write_oob()
432 status = chip->ecc.write_oob(chip, page & chip->pagemask); in nand_do_write_oob()
2495 * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
2499 * @ecc: ECC buffer
2500 * @ecclen: ECC length
2505 * Check if a data buffer and its associated ECC and OOB data contains only
2512 * 1/ ECC algorithms are working on pre-defined block sizes which are usually
2513 * different from the NAND page size. When fixing bitflips, ECC engines will
2520 * the payload data but also their associated ECC data, because a user might
2522 * shouldn't consider the chunk as erased, and checking ECC bytes prevent
2525 * data are protected by the ECC engine.
2527 * extra OOB data to an ECC chunk.
2534 void *ecc, int ecclen, in nand_check_erased_ecc_chunk() argument
2547 ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold); in nand_check_erased_ecc_chunk()
2562 memset(ecc, 0xff, ecclen); in nand_check_erased_ecc_chunk()
2587 * nand_read_page_raw - [INTERN] read raw page data without ecc
2593 * Not for syndrome calculating ECC controllers, which use a special oob layout.
2658 * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
2670 int eccsize = chip->ecc.size; in nand_read_page_raw_syndrome()
2671 int eccbytes = chip->ecc.bytes; in nand_read_page_raw_syndrome()
2679 for (steps = chip->ecc.steps; steps > 0; steps--) { in nand_read_page_raw_syndrome()
2686 if (chip->ecc.prepad) { in nand_read_page_raw_syndrome()
2687 ret = nand_read_data_op(chip, oob, chip->ecc.prepad, in nand_read_page_raw_syndrome()
2692 oob += chip->ecc.prepad; in nand_read_page_raw_syndrome()
2701 if (chip->ecc.postpad) { in nand_read_page_raw_syndrome()
2702 ret = nand_read_data_op(chip, oob, chip->ecc.postpad, in nand_read_page_raw_syndrome()
2707 oob += chip->ecc.postpad; in nand_read_page_raw_syndrome()
2722 * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
2732 int i, eccsize = chip->ecc.size, ret; in nand_read_page_swecc()
2733 int eccbytes = chip->ecc.bytes; in nand_read_page_swecc()
2734 int eccsteps = chip->ecc.steps; in nand_read_page_swecc()
2736 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_read_page_swecc()
2737 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_swecc()
2740 chip->ecc.read_page_raw(chip, buf, 1, page); in nand_read_page_swecc()
2743 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_read_page_swecc()
2746 chip->ecc.total); in nand_read_page_swecc()
2750 eccsteps = chip->ecc.steps; in nand_read_page_swecc()
2756 stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]); in nand_read_page_swecc()
2768 * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function
2788 /* Column address within the page aligned to ECC size (256bytes) */ in nand_read_subpage()
2789 start_step = data_offs / chip->ecc.size; in nand_read_subpage()
2790 end_step = (data_offs + readlen - 1) / chip->ecc.size; in nand_read_subpage()
2792 index = start_step * chip->ecc.bytes; in nand_read_subpage()
2794 /* Data size aligned to ECC ecc.size */ in nand_read_subpage()
2795 datafrag_len = num_steps * chip->ecc.size; in nand_read_subpage()
2796 eccfrag_len = num_steps * chip->ecc.bytes; in nand_read_subpage()
2798 data_col_addr = start_step * chip->ecc.size; in nand_read_subpage()
2805 /* Calculate ECC */ in nand_read_subpage()
2806 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) in nand_read_subpage()
2807 chip->ecc.calculate(chip, p, &chip->ecc.calc_buf[i]); in nand_read_subpage()
2811 * ecc.pos. Let's make sure that there are no gaps in ECC positions. in nand_read_subpage()
2828 * Send the command to read the particular ECC bytes take care in nand_read_subpage()
2835 if ((oobregion.offset + (num_steps * chip->ecc.bytes)) & in nand_read_subpage()
2847 ret = mtd_ooblayout_get_eccbytes(mtd, chip->ecc.code_buf, in nand_read_subpage()
2853 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { in nand_read_subpage()
2856 stat = chip->ecc.correct(chip, p, &chip->ecc.code_buf[i], in nand_read_subpage()
2857 &chip->ecc.calc_buf[i]); in nand_read_subpage()
2859 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_subpage()
2861 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, in nand_read_subpage()
2862 &chip->ecc.code_buf[i], in nand_read_subpage()
2863 chip->ecc.bytes, in nand_read_subpage()
2865 chip->ecc.strength); in nand_read_subpage()
2879 * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
2885 * Not for syndrome calculating ECC controllers which need a special oob layout.
2891 int i, eccsize = chip->ecc.size, ret; in nand_read_page_hwecc()
2892 int eccbytes = chip->ecc.bytes; in nand_read_page_hwecc()
2893 int eccsteps = chip->ecc.steps; in nand_read_page_hwecc()
2895 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_read_page_hwecc()
2896 uint8_t *ecc_code = chip->ecc.code_buf; in nand_read_page_hwecc()
2904 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_hwecc()
2910 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_read_page_hwecc()
2919 chip->ecc.total); in nand_read_page_hwecc()
2923 eccsteps = chip->ecc.steps; in nand_read_page_hwecc()
2929 stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]); in nand_read_page_hwecc()
2931 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_hwecc()
2936 chip->ecc.strength); in nand_read_page_hwecc()
2950 * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
2963 int ret, i, eccsize = chip->ecc.size; in nand_read_page_syndrome()
2964 int eccbytes = chip->ecc.bytes; in nand_read_page_syndrome()
2965 int eccsteps = chip->ecc.steps; in nand_read_page_syndrome()
2966 int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad; in nand_read_page_syndrome()
2978 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_read_page_syndrome()
2984 if (chip->ecc.prepad) { in nand_read_page_syndrome()
2985 ret = nand_read_data_op(chip, oob, chip->ecc.prepad, in nand_read_page_syndrome()
2990 oob += chip->ecc.prepad; in nand_read_page_syndrome()
2993 chip->ecc.hwctl(chip, NAND_ECC_READSYN); in nand_read_page_syndrome()
2999 stat = chip->ecc.correct(chip, p, oob, NULL); in nand_read_page_syndrome()
3003 if (chip->ecc.postpad) { in nand_read_page_syndrome()
3004 ret = nand_read_data_op(chip, oob, chip->ecc.postpad, in nand_read_page_syndrome()
3009 oob += chip->ecc.postpad; in nand_read_page_syndrome()
3013 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_read_page_syndrome()
3015 stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, in nand_read_page_syndrome()
3019 chip->ecc.strength); in nand_read_page_syndrome()
3079 * when there are too many bitflips in a page (i.e., ECC error). After setting
3107 * nand_do_read_ops - [INTERN] Read data with ECC
3168 * the read methods return max bitflips per ecc step. in nand_do_read_ops()
3171 ret = chip->ecc.read_page_raw(chip, bufpoi, in nand_do_read_ops()
3176 ret = chip->ecc.read_subpage(chip, col, bytes, in nand_do_read_ops()
3179 ret = chip->ecc.read_page(chip, bufpoi, in nand_do_read_ops()
3298 * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
3307 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; in nand_read_oob_syndrome()
3308 int eccsize = chip->ecc.size; in nand_read_oob_syndrome()
3312 ret = nand_read_page_op(chip, page, chip->ecc.size, NULL, 0); in nand_read_oob_syndrome()
3316 for (i = 0; i < chip->ecc.steps; i++) { in nand_read_oob_syndrome()
3366 * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
3374 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; in nand_write_oob_syndrome()
3375 int eccsize = chip->ecc.size, length = mtd->oobsize; in nand_write_oob_syndrome()
3376 int ret, i, len, pos, sndcmd = 0, steps = chip->ecc.steps; in nand_write_oob_syndrome()
3380 * data-ecc-data-ecc ... ecc-oob in nand_write_oob_syndrome()
3382 * data-pad-ecc-pad-data-pad .... ecc-pad-oob in nand_write_oob_syndrome()
3384 if (!chip->ecc.prepad && !chip->ecc.postpad) { in nand_write_oob_syndrome()
3474 ret = chip->ecc.read_oob_raw(chip, page); in nand_do_read_oob()
3476 ret = chip->ecc.read_oob(chip, page); in nand_do_read_oob()
3572 * Not for syndrome calculating ECC controllers, which use a special oob layout.
3638 * We need a special oob layout and handling even when ECC isn't checked.
3645 int eccsize = chip->ecc.size; in nand_write_page_raw_syndrome()
3646 int eccbytes = chip->ecc.bytes; in nand_write_page_raw_syndrome()
3654 for (steps = chip->ecc.steps; steps > 0; steps--) { in nand_write_page_raw_syndrome()
3661 if (chip->ecc.prepad) { in nand_write_page_raw_syndrome()
3662 ret = nand_write_data_op(chip, oob, chip->ecc.prepad, in nand_write_page_raw_syndrome()
3667 oob += chip->ecc.prepad; in nand_write_page_raw_syndrome()
3676 if (chip->ecc.postpad) { in nand_write_page_raw_syndrome()
3677 ret = nand_write_data_op(chip, oob, chip->ecc.postpad, in nand_write_page_raw_syndrome()
3682 oob += chip->ecc.postpad; in nand_write_page_raw_syndrome()
3696 * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
3706 int i, eccsize = chip->ecc.size, ret; in nand_write_page_swecc()
3707 int eccbytes = chip->ecc.bytes; in nand_write_page_swecc()
3708 int eccsteps = chip->ecc.steps; in nand_write_page_swecc()
3709 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_page_swecc()
3712 /* Software ECC calculation */ in nand_write_page_swecc()
3714 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_write_page_swecc()
3717 chip->ecc.total); in nand_write_page_swecc()
3721 return chip->ecc.write_page_raw(chip, buf, 1, page); in nand_write_page_swecc()
3725 * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
3735 int i, eccsize = chip->ecc.size, ret; in nand_write_page_hwecc()
3736 int eccbytes = chip->ecc.bytes; in nand_write_page_hwecc()
3737 int eccsteps = chip->ecc.steps; in nand_write_page_hwecc()
3738 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_page_hwecc()
3746 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_page_hwecc()
3752 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_write_page_hwecc()
3756 chip->ecc.total); in nand_write_page_hwecc()
3769 * nand_write_subpage_hwecc - [REPLACEABLE] hardware ECC based subpage write
3783 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_write_subpage_hwecc()
3784 int ecc_size = chip->ecc.size; in nand_write_subpage_hwecc()
3785 int ecc_bytes = chip->ecc.bytes; in nand_write_subpage_hwecc()
3786 int ecc_steps = chip->ecc.steps; in nand_write_subpage_hwecc()
3798 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_subpage_hwecc()
3805 /* mask ECC of un-touched subpages by padding 0xFF */ in nand_write_subpage_hwecc()
3809 chip->ecc.calculate(chip, buf, ecc_calc); in nand_write_subpage_hwecc()
3821 /* copy calculated ECC for whole page to chip->buffer->oob */ in nand_write_subpage_hwecc()
3823 ecc_calc = chip->ecc.calc_buf; in nand_write_subpage_hwecc()
3825 chip->ecc.total); in nand_write_subpage_hwecc()
3839 * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
3852 int i, eccsize = chip->ecc.size; in nand_write_page_syndrome()
3853 int eccbytes = chip->ecc.bytes; in nand_write_page_syndrome()
3854 int eccsteps = chip->ecc.steps; in nand_write_page_syndrome()
3864 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in nand_write_page_syndrome()
3870 if (chip->ecc.prepad) { in nand_write_page_syndrome()
3871 ret = nand_write_data_op(chip, oob, chip->ecc.prepad, in nand_write_page_syndrome()
3876 oob += chip->ecc.prepad; in nand_write_page_syndrome()
3879 chip->ecc.calculate(chip, p, oob); in nand_write_page_syndrome()
3887 if (chip->ecc.postpad) { in nand_write_page_syndrome()
3888 ret = nand_write_data_op(chip, oob, chip->ecc.postpad, in nand_write_page_syndrome()
3893 oob += chip->ecc.postpad; in nand_write_page_syndrome()
3926 chip->ecc.write_subpage) in nand_write_page()
3932 status = chip->ecc.write_page_raw(chip, buf, oob_required, in nand_write_page()
3935 status = chip->ecc.write_subpage(chip, offset, data_len, buf, in nand_write_page()
3938 status = chip->ecc.write_page(chip, buf, oob_required, page); in nand_write_page()
3949 * nand_do_write_ops - [INTERN] NAND write with ECC
3954 * NAND write with ECC.
4078 * panic_nand_write - [MTD Interface] NAND write with ECC
4085 * NAND write with ECC. Used when performing writes in interrupt context, this
4904 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_engine_type_legacy()
4937 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_placement_legacy()
4951 err = of_property_read_string(np, "nand-ecc-mode", &pm); in of_get_rawnand_ecc_algo_legacy()
4965 struct nand_ecc_props *user_conf = &chip->base.ecc.user_conf; in of_get_nand_ecc_legacy_user_config()
5020 * ECC engine type, we will default to NAND_ECC_ENGINE_TYPE_ON_HOST. in rawnand_dt_init()
5022 nand->ecc.defaults.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in rawnand_dt_init()
5029 if (nand->ecc.user_conf.engine_type != NAND_ECC_ENGINE_TYPE_INVALID) in rawnand_dt_init()
5030 chip->ecc.engine_type = nand->ecc.user_conf.engine_type; in rawnand_dt_init()
5031 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) in rawnand_dt_init()
5032 chip->ecc.engine_type = nand->ecc.defaults.engine_type; in rawnand_dt_init()
5034 chip->ecc.placement = nand->ecc.user_conf.placement; in rawnand_dt_init()
5035 chip->ecc.algo = nand->ecc.user_conf.algo; in rawnand_dt_init()
5036 chip->ecc.strength = nand->ecc.user_conf.strength; in rawnand_dt_init()
5037 chip->ecc.size = nand->ecc.user_conf.step_size; in rawnand_dt_init()
5052 * to tweak some ECC-related parameters before nand_scan_tail(). This separation
5144 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_set_ecc_on_host_ops() local
5146 switch (ecc->placement) { in nand_set_ecc_on_host_ops()
5150 if (!ecc->read_page) in nand_set_ecc_on_host_ops()
5151 ecc->read_page = nand_read_page_hwecc; in nand_set_ecc_on_host_ops()
5152 if (!ecc->write_page) in nand_set_ecc_on_host_ops()
5153 ecc->write_page = nand_write_page_hwecc; in nand_set_ecc_on_host_ops()
5154 if (!ecc->read_page_raw) in nand_set_ecc_on_host_ops()
5155 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_on_host_ops()
5156 if (!ecc->write_page_raw) in nand_set_ecc_on_host_ops()
5157 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_on_host_ops()
5158 if (!ecc->read_oob) in nand_set_ecc_on_host_ops()
5159 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_on_host_ops()
5160 if (!ecc->write_oob) in nand_set_ecc_on_host_ops()
5161 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_on_host_ops()
5162 if (!ecc->read_subpage) in nand_set_ecc_on_host_ops()
5163 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_on_host_ops()
5164 if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) in nand_set_ecc_on_host_ops()
5165 ecc->write_subpage = nand_write_subpage_hwecc; in nand_set_ecc_on_host_ops()
5169 if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) && in nand_set_ecc_on_host_ops()
5170 (!ecc->read_page || in nand_set_ecc_on_host_ops()
5171 ecc->read_page == nand_read_page_hwecc || in nand_set_ecc_on_host_ops()
5172 !ecc->write_page || in nand_set_ecc_on_host_ops()
5173 ecc->write_page == nand_write_page_hwecc)) { in nand_set_ecc_on_host_ops()
5174 WARN(1, "No ECC functions supplied; hardware ECC not possible\n"); in nand_set_ecc_on_host_ops()
5178 if (!ecc->read_page) in nand_set_ecc_on_host_ops()
5179 ecc->read_page = nand_read_page_syndrome; in nand_set_ecc_on_host_ops()
5180 if (!ecc->write_page) in nand_set_ecc_on_host_ops()
5181 ecc->write_page = nand_write_page_syndrome; in nand_set_ecc_on_host_ops()
5182 if (!ecc->read_page_raw) in nand_set_ecc_on_host_ops()
5183 ecc->read_page_raw = nand_read_page_raw_syndrome; in nand_set_ecc_on_host_ops()
5184 if (!ecc->write_page_raw) in nand_set_ecc_on_host_ops()
5185 ecc->write_page_raw = nand_write_page_raw_syndrome; in nand_set_ecc_on_host_ops()
5186 if (!ecc->read_oob) in nand_set_ecc_on_host_ops()
5187 ecc->read_oob = nand_read_oob_syndrome; in nand_set_ecc_on_host_ops()
5188 if (!ecc->write_oob) in nand_set_ecc_on_host_ops()
5189 ecc->write_oob = nand_write_oob_syndrome; in nand_set_ecc_on_host_ops()
5194 ecc->placement); in nand_set_ecc_on_host_ops()
5205 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_set_ecc_soft_ops() local
5207 if (WARN_ON(ecc->engine_type != NAND_ECC_ENGINE_TYPE_SOFT)) in nand_set_ecc_soft_ops()
5210 switch (ecc->algo) { in nand_set_ecc_soft_ops()
5212 ecc->calculate = nand_calculate_ecc; in nand_set_ecc_soft_ops()
5213 ecc->correct = nand_correct_data; in nand_set_ecc_soft_ops()
5214 ecc->read_page = nand_read_page_swecc; in nand_set_ecc_soft_ops()
5215 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_soft_ops()
5216 ecc->write_page = nand_write_page_swecc; in nand_set_ecc_soft_ops()
5217 if (!ecc->read_page_raw) in nand_set_ecc_soft_ops()
5218 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_soft_ops()
5219 if (!ecc->write_page_raw) in nand_set_ecc_soft_ops()
5220 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_soft_ops()
5221 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_soft_ops()
5222 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_soft_ops()
5223 if (!ecc->size) in nand_set_ecc_soft_ops()
5224 ecc->size = 256; in nand_set_ecc_soft_ops()
5225 ecc->bytes = 3; in nand_set_ecc_soft_ops()
5226 ecc->strength = 1; in nand_set_ecc_soft_ops()
5229 ecc->options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; in nand_set_ecc_soft_ops()
5237 ecc->calculate = nand_bch_calculate_ecc; in nand_set_ecc_soft_ops()
5238 ecc->correct = nand_bch_correct_data; in nand_set_ecc_soft_ops()
5239 ecc->read_page = nand_read_page_swecc; in nand_set_ecc_soft_ops()
5240 ecc->read_subpage = nand_read_subpage; in nand_set_ecc_soft_ops()
5241 ecc->write_page = nand_write_page_swecc; in nand_set_ecc_soft_ops()
5242 if (!ecc->read_page_raw) in nand_set_ecc_soft_ops()
5243 ecc->read_page_raw = nand_read_page_raw; in nand_set_ecc_soft_ops()
5244 if (!ecc->write_page_raw) in nand_set_ecc_soft_ops()
5245 ecc->write_page_raw = nand_write_page_raw; in nand_set_ecc_soft_ops()
5246 ecc->read_oob = nand_read_oob_std; in nand_set_ecc_soft_ops()
5247 ecc->write_oob = nand_write_oob_std; in nand_set_ecc_soft_ops()
5250 * Board driver should supply ecc.size and ecc.strength in nand_set_ecc_soft_ops()
5254 if (!ecc->size && (mtd->oobsize >= 64)) { in nand_set_ecc_soft_ops()
5255 ecc->size = 512; in nand_set_ecc_soft_ops()
5256 ecc->strength = 4; in nand_set_ecc_soft_ops()
5260 * if no ecc placement scheme was provided pickup the default in nand_set_ecc_soft_ops()
5275 * We can only maximize ECC config when the default layout is in nand_set_ecc_soft_ops()
5280 nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH) { in nand_set_ecc_soft_ops()
5284 ecc->size = 1024; in nand_set_ecc_soft_ops()
5285 steps = mtd->writesize / ecc->size; in nand_set_ecc_soft_ops()
5289 ecc->strength = bytes * 8 / fls(8 * ecc->size); in nand_set_ecc_soft_ops()
5293 ecc->bytes = 0; in nand_set_ecc_soft_ops()
5294 ecc->priv = nand_bch_init(mtd); in nand_set_ecc_soft_ops()
5295 if (!ecc->priv) { in nand_set_ecc_soft_ops()
5296 WARN(1, "BCH ECC initialization failed!\n"); in nand_set_ecc_soft_ops()
5301 WARN(1, "Unsupported ECC algorithm!\n"); in nand_set_ecc_soft_ops()
5307 * nand_check_ecc_caps - check the sanity of preset ECC settings
5309 * @caps: ECC caps info structure
5310 * @oobavail: OOB size that the ECC engine can use
5312 * When ECC step size and strength are already set, check if they are supported
5313 * by the controller and the calculated ECC bytes fit within the chip's OOB.
5314 * On success, the calculated ECC bytes is set.
5322 int preset_step = chip->ecc.size; in nand_check_ecc_caps()
5323 int preset_strength = chip->ecc.strength; in nand_check_ecc_caps()
5343 pr_err("ECC (step, strength) = (%d, %d) does not fit in OOB", in nand_check_ecc_caps()
5348 chip->ecc.bytes = ecc_bytes; in nand_check_ecc_caps()
5354 pr_err("ECC (step, strength) = (%d, %d) not supported on this controller", in nand_check_ecc_caps()
5361 * nand_match_ecc_req - meet the chip's requirement with least ECC bytes
5363 * @caps: ECC engine caps info structure
5364 * @oobavail: OOB size that the ECC engine can use
5366 * If a chip's ECC requirement is provided, try to meet it with the least
5367 * number of ECC bytes (i.e. with the largest number of OOB-free bytes).
5368 * On success, the chosen ECC settings are set.
5423 * with the least number of ECC bytes. in nand_match_ecc_req()
5437 chip->ecc.size = best_step; in nand_match_ecc_req()
5438 chip->ecc.strength = best_strength; in nand_match_ecc_req()
5439 chip->ecc.bytes = best_ecc_bytes; in nand_match_ecc_req()
5445 * nand_maximize_ecc - choose the max ECC strength available
5447 * @caps: ECC engine caps info structure
5448 * @oobavail: OOB size that the ECC engine can use
5450 * Choose the max ECC strength that is supported on the controller, and can fit
5451 * within the chip's OOB. On success, the chosen ECC settings are set.
5469 /* If chip->ecc.size is already set, respect it */ in nand_maximize_ecc()
5470 if (chip->ecc.size && step_size != chip->ecc.size) in nand_maximize_ecc()
5507 chip->ecc.size = best_step; in nand_maximize_ecc()
5508 chip->ecc.strength = best_strength; in nand_maximize_ecc()
5509 chip->ecc.bytes = best_ecc_bytes; in nand_maximize_ecc()
5515 * nand_ecc_choose_conf - Set the ECC strength and ECC step size
5517 * @caps: ECC engine caps info structure
5518 * @oobavail: OOB size that the ECC engine can use
5520 * Choose the ECC configuration according to following logic.
5522 * 1. If both ECC step size and ECC strength are already set (usually by DT)
5524 * 2. If the user provided the nand-ecc-maximize property, then select maximum
5525 * ECC strength.
5526 * 3. Otherwise, try to match the ECC step size and ECC strength closest
5528 * requirement then fallback to the maximum ECC step size and ECC strength.
5530 * On success, the chosen ECC settings are set.
5541 if (chip->ecc.size && chip->ecc.strength) in nand_ecc_choose_conf()
5544 if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH) in nand_ecc_choose_conf()
5609 struct nand_ecc_ctrl *ecc = &chip->ecc; in nand_scan_tail() local
5641 !(ecc->engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in nand_scan_tail()
5642 ecc->algo == NAND_ECC_ALGO_BCH)) { in nand_scan_tail()
5658 * page with ECC layout when ->oobsize <= 128 for in nand_scan_tail()
5661 if (ecc->engine_type == NAND_ECC_ENGINE_TYPE_NONE) { in nand_scan_tail()
5675 * Check ECC mode, default to software if 3byte/512byte hardware ECC is in nand_scan_tail()
5676 * selected and we have 256 byte pagesize fallback to software ECC in nand_scan_tail()
5679 switch (ecc->engine_type) { in nand_scan_tail()
5685 if (mtd->writesize >= ecc->size) { in nand_scan_tail()
5686 if (!ecc->strength) { in nand_scan_tail()
5687 WARN(1, "Driver must set ecc.strength when using hardware ECC\n"); in nand_scan_tail()
5693 pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", in nand_scan_tail()
5694 ecc->size, mtd->writesize); in nand_scan_tail()
5695 ecc->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_scan_tail()
5696 ecc->algo = NAND_ECC_ALGO_HAMMING; in nand_scan_tail()
5706 if (!ecc->read_page || !ecc->write_page) { in nand_scan_tail()
5707 WARN(1, "No ECC functions supplied; on-die ECC not possible\n"); in nand_scan_tail()
5711 if (!ecc->read_oob) in nand_scan_tail()
5712 ecc->read_oob = nand_read_oob_std; in nand_scan_tail()
5713 if (!ecc->write_oob) in nand_scan_tail()
5714 ecc->write_oob = nand_write_oob_std; in nand_scan_tail()
5719 ecc->read_page = nand_read_page_raw; in nand_scan_tail()
5720 ecc->write_page = nand_write_page_raw; in nand_scan_tail()
5721 ecc->read_oob = nand_read_oob_std; in nand_scan_tail()
5722 ecc->read_page_raw = nand_read_page_raw; in nand_scan_tail()
5723 ecc->write_page_raw = nand_write_page_raw; in nand_scan_tail()
5724 ecc->write_oob = nand_write_oob_std; in nand_scan_tail()
5725 ecc->size = mtd->writesize; in nand_scan_tail()
5726 ecc->bytes = 0; in nand_scan_tail()
5727 ecc->strength = 0; in nand_scan_tail()
5731 WARN(1, "Invalid NAND_ECC_MODE %d\n", ecc->engine_type); in nand_scan_tail()
5736 if (ecc->correct || ecc->calculate) { in nand_scan_tail()
5737 ecc->calc_buf = kmalloc(mtd->oobsize, GFP_KERNEL); in nand_scan_tail()
5738 ecc->code_buf = kmalloc(mtd->oobsize, GFP_KERNEL); in nand_scan_tail()
5739 if (!ecc->calc_buf || !ecc->code_buf) { in nand_scan_tail()
5746 if (!ecc->read_oob_raw) in nand_scan_tail()
5747 ecc->read_oob_raw = ecc->read_oob; in nand_scan_tail()
5748 if (!ecc->write_oob_raw) in nand_scan_tail()
5749 ecc->write_oob_raw = ecc->write_oob; in nand_scan_tail()
5751 /* propagate ecc info to mtd_info */ in nand_scan_tail()
5752 mtd->ecc_strength = ecc->strength; in nand_scan_tail()
5753 mtd->ecc_step_size = ecc->size; in nand_scan_tail()
5756 * Set the number of read / write steps for one page depending on ECC in nand_scan_tail()
5759 ecc->steps = mtd->writesize / ecc->size; in nand_scan_tail()
5760 if (ecc->steps * ecc->size != mtd->writesize) { in nand_scan_tail()
5761 WARN(1, "Invalid ECC parameters\n"); in nand_scan_tail()
5766 ecc->total = ecc->steps * ecc->bytes; in nand_scan_tail()
5767 chip->base.ecc.ctx.total = ecc->total; in nand_scan_tail()
5769 if (ecc->total > mtd->oobsize) { in nand_scan_tail()
5770 WARN(1, "Total number of ECC bytes exceeded oobsize\n"); in nand_scan_tail()
5785 /* ECC sanity check: warn if it's too weak */ in nand_scan_tail()
5787 …pr_warn("WARNING: %s: the ECC used on your system (%db/%dB) is too weak compared to the one requir… in nand_scan_tail()
5788 mtd->name, chip->ecc.strength, chip->ecc.size, in nand_scan_tail()
5792 /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */ in nand_scan_tail()
5794 switch (ecc->steps) { in nand_scan_tail()
5811 switch (ecc->engine_type) { in nand_scan_tail()
5889 kfree(ecc->code_buf); in nand_scan_tail()
5890 kfree(ecc->calc_buf); in nand_scan_tail()
5956 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in nand_cleanup()
5957 chip->ecc.algo == NAND_ECC_ALGO_BCH) in nand_cleanup()
5958 nand_bch_free((struct nand_bch_control *)chip->ecc.priv); in nand_cleanup()
5965 kfree(chip->ecc.code_buf); in nand_cleanup()
5966 kfree(chip->ecc.calc_buf); in nand_cleanup()