Lines Matching full:ecc
18 #include <linux/mtd/nand-ecc-sw-bch.h>
122 /* GPMC ecc engine settings for read */
129 /* GPMC ecc engine settings for write */
170 /* fields specific for BCHx_HW ECC scheme */
623 * gen_true_ecc - This function will generate true ECC value
624 * @ecc_buf: buffer to store ecc code
626 * This generated true ECC value can be used when correcting
644 * @ecc_data1: ecc code from nand spare area
645 * @ecc_data2: ecc code from hardware register obtained from hardware ecc
648 * This function compares two ECC's and indicates if there is an error.
724 * ECC values are equal in omap_compare_ecc()
730 pr_debug("ECC UNCORRECTED_ERROR 1\n"); in omap_compare_ecc()
735 pr_debug("ECC UNCORRECTED_ERROR B\n"); in omap_compare_ecc()
752 pr_debug("Correcting single bit ECC error at offset: " in omap_compare_ecc()
771 * omap_correct_data - Compares the ECC read with HW generated ECC
774 * @read_ecc: ecc read from nand flash
775 * @calc_ecc: ecc read from HW ECC registers
777 * Compares the ecc read from nand spare area with ECC registers values
778 * and if ECC's mismatched, it will call 'omap_compare_ecc' for error
792 if (info->nand.ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST && in omap_correct_data()
793 info->nand.ecc.size == 2048) in omap_correct_data()
814 * omap_calculate_ecc - Generate non-inverted ECC bytes.
816 * @dat: The pointer to data on which ecc is computed
819 * Using noninverted ECC can be considered ugly since writing a blank
820 * page ie. padding will clear the ECC bytes. This is no problem as long
822 * an erased page will produce an ECC mismatch between generated and read
823 * ECC bytes that has to be dealt with separately.
835 /* read ecc result */ in omap_calculate_ecc()
846 * omap_enable_hwecc - This function enables the hardware ecc functionality
856 /* clear ecc and enable bits */ in omap_enable_hwecc()
860 /* program ecc and result sizes */ in omap_enable_hwecc()
861 val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | in omap_enable_hwecc()
879 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ in omap_enable_hwecc()
885 * omap_enable_hwecc_bch - Program GPMC to perform BCH ECC calculation
905 /* GPMC configurations for calculating ECC */ in omap_enable_hwecc_bch()
916 nsectors = chip->ecc.steps; in omap_enable_hwecc_bch()
936 nsectors = chip->ecc.steps; in omap_enable_hwecc_bch()
949 nsectors = chip->ecc.steps; in omap_enable_hwecc_bch()
952 ecc_size0 = 52; /* ECC bits in nibbles per sector */ in omap_enable_hwecc_bch()
953 ecc_size1 = 0; /* non-ECC bits in nibbles per sector */ in omap_enable_hwecc_bch()
966 /* Configure ecc size for BCH */ in omap_enable_hwecc_bch()
978 (info->gpmc_cs << 1) | /* ECC CS */ in omap_enable_hwecc_bch()
979 (0x1)); /* enable ECC */ in omap_enable_hwecc_bch()
983 /* Clear ecc and enable bits */ in omap_enable_hwecc_bch()
992 * _omap_calculate_ecc_bch - Generate ECC bytes for one sector
994 * @dat: The pointer to data on which ecc is computed
998 * Support calculating of BCH4/8/16 ECC vectors for one sector
1005 int eccbytes = info->nand.ecc.bytes; in _omap_calculate_ecc_bch()
1086 /* ECC scheme specific syndrome customizations */ in _omap_calculate_ecc_bch()
1090 * ECC of blank pages results in 0x0 on reading back in _omap_calculate_ecc_bch()
1096 /* Set 8th ECC byte as 0x0 for ROM compatibility */ in _omap_calculate_ecc_bch()
1101 * ECC of blank pages results in 0x0 on reading back in _omap_calculate_ecc_bch()
1107 /* Set 14th ECC byte as 0x0 for ROM compatibility */ in _omap_calculate_ecc_bch()
1120 * omap_calculate_ecc_bch_sw - ECC generator for sector for SW based correction
1122 * @dat: The pointer to data on which ecc is computed
1123 * @ecc_calc: Buffer storing the calculated ECC bytes
1125 * Support calculating of BCH4/8/16 ECC vectors for one sector. This is used
1126 * when SW based correction is required as ECC is required for one sector
1136 * omap_calculate_ecc_bch_multi - Generate ECC for multiple sectors
1138 * @dat: The pointer to data on which ecc is computed
1139 * @ecc_calc: Buffer storing the calculated ECC bytes
1141 * Support calculating of BCH4/8/16 ecc vectors for the entire page in one go.
1147 int eccbytes = info->nand.ecc.bytes; in omap_calculate_ecc_bch_multi()
1178 for (i = 0; i < info->nand.ecc.size; i++) { in erased_sector_bitflips()
1180 if (flip_bits > info->nand.ecc.strength) in erased_sector_bitflips()
1184 for (i = 0; i < info->nand.ecc.bytes - 1; i++) { in erased_sector_bitflips()
1186 if (flip_bits > info->nand.ecc.strength) in erased_sector_bitflips()
1195 memset(data, 0xFF, info->nand.ecc.size); in erased_sector_bitflips()
1196 memset(oob, 0xFF, info->nand.ecc.bytes); in erased_sector_bitflips()
1206 * @read_ecc: ecc read from nand flash
1207 * @calc_ecc: ecc read from HW ECC registers
1209 * Calculated ecc vector reported as zero in case of non-error pages.
1210 * In case of non-zero ecc vector, first filter out erased-pages, and
1217 struct nand_ecc_ctrl *ecc = &info->nand.ecc; in omap_elm_correct_data() local
1233 /* omit 7th ECC byte reserved for ROM code compatibility */ in omap_elm_correct_data()
1234 actual_eccbytes = ecc->bytes - 1; in omap_elm_correct_data()
1238 /* omit 14th ECC byte reserved for ROM code compatibility */ in omap_elm_correct_data()
1239 actual_eccbytes = ecc->bytes - 1; in omap_elm_correct_data()
1243 actual_eccbytes = ecc->bytes; in omap_elm_correct_data()
1259 * In case of error, non zero ecc reported. in omap_elm_correct_data()
1263 eccflag = 1; /* non zero ecc, error present */ in omap_elm_correct_data()
1272 * calc_ecc[] matches pattern for ECC(all 0xff) in omap_elm_correct_data()
1276 buf = &data[info->nand.ecc.size * i]; in omap_elm_correct_data()
1286 * number of 0-bits within ECC limits in omap_elm_correct_data()
1303 /* Update the ecc vector */ in omap_elm_correct_data()
1304 calc_ecc += ecc->bytes; in omap_elm_correct_data()
1305 read_ecc += ecc->bytes; in omap_elm_correct_data()
1336 error_max = (ecc->size + actual_eccbytes) * 8; in omap_elm_correct_data()
1368 data += ecc->size; in omap_elm_correct_data()
1369 spare_ecc += ecc->bytes; in omap_elm_correct_data()
1376 * omap_write_page_bch - BCH ecc based write page function for entire page
1389 uint8_t *ecc_calc = chip->ecc.calc_buf; in omap_write_page_bch()
1398 /* Enable GPMC ecc engine */ in omap_write_page_bch()
1399 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in omap_write_page_bch()
1405 /* Update ecc vector from GPMC result registers */ in omap_write_page_bch()
1420 /* Write ecc vector to OOB area */ in omap_write_page_bch()
1427 * omap_write_subpage_bch - BCH hardware ECC based subpage write
1443 u8 *ecc_calc = chip->ecc.calc_buf; in omap_write_subpage_bch()
1444 int ecc_size = chip->ecc.size; in omap_write_subpage_bch()
1445 int ecc_bytes = chip->ecc.bytes; in omap_write_subpage_bch()
1453 * as ECC is calculated by hardware. in omap_write_subpage_bch()
1454 * ECC is calculated for all subpages but we choose in omap_write_subpage_bch()
1462 /* Enable GPMC ECC engine */ in omap_write_subpage_bch()
1463 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in omap_write_subpage_bch()
1473 /* Mask ECC of un-touched subpages with 0xFFs */ in omap_write_subpage_bch()
1489 * Copy the calculated ECC for the whole page including the in omap_write_subpage_bch()
1506 * omap_read_page_bch - BCH ecc based page read function for entire page
1512 * For BCH ecc scheme, GPMC used for syndrome calculation and ELM module
1516 * ecc engine enabled. ecc vector updated after read of OOB data.
1517 * For non error pages ecc vector reported as zero.
1524 uint8_t *ecc_calc = chip->ecc.calc_buf; in omap_read_page_bch()
1525 uint8_t *ecc_code = chip->ecc.code_buf; in omap_read_page_bch()
1534 /* Enable GPMC ecc engine */ in omap_read_page_bch()
1535 chip->ecc.hwctl(chip, NAND_ECC_READ); in omap_read_page_bch()
1554 /* Calculate ecc bytes */ in omap_read_page_bch()
1568 stat = chip->ecc.correct(chip, in omap_read_page_bch()
1680 /* select ecc-scheme for NAND */ in omap_get_dt_info()
1681 if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { in omap_get_dt_info()
1682 dev_err(dev, "ti,nand-ecc-opt not found\n"); in omap_get_dt_info()
1704 dev_err(dev, "unrecognized value for ti,nand-ecc-opt\n"); in omap_get_dt_info()
1739 oobregion->length = chip->ecc.total; in omap_ooblayout_ecc()
1758 off += chip->ecc.total; in omap_ooblayout_free()
1769 .ecc = omap_ooblayout_ecc,
1786 * reserved after each ECC step. in omap_sw_ooblayout_ecc()
1807 * reserved after each ECC step. in omap_sw_ooblayout_free()
1820 .ecc = omap_sw_ooblayout_ecc,
1926 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in omap_nand_attach_chip()
1927 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in omap_nand_attach_chip()
1931 /* Populate MTD interface based on ECC scheme */ in omap_nand_attach_chip()
1935 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
1936 chip->ecc.bytes = 3; in omap_nand_attach_chip()
1937 chip->ecc.size = 512; in omap_nand_attach_chip()
1938 chip->ecc.strength = 1; in omap_nand_attach_chip()
1939 chip->ecc.calculate = omap_calculate_ecc; in omap_nand_attach_chip()
1940 chip->ecc.hwctl = omap_enable_hwecc; in omap_nand_attach_chip()
1941 chip->ecc.correct = omap_correct_data; in omap_nand_attach_chip()
1943 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
1952 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
1953 chip->ecc.size = 512; in omap_nand_attach_chip()
1954 chip->ecc.bytes = 7; in omap_nand_attach_chip()
1955 chip->ecc.strength = 4; in omap_nand_attach_chip()
1956 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
1957 chip->ecc.correct = rawnand_sw_bch_correct; in omap_nand_attach_chip()
1958 chip->ecc.calculate = omap_calculate_ecc_bch_sw; in omap_nand_attach_chip()
1961 oobbytes_per_step = chip->ecc.bytes + 1; in omap_nand_attach_chip()
1971 pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n"); in omap_nand_attach_chip()
1972 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
1973 chip->ecc.size = 512; in omap_nand_attach_chip()
1975 chip->ecc.bytes = 7 + 1; in omap_nand_attach_chip()
1976 chip->ecc.strength = 4; in omap_nand_attach_chip()
1977 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
1978 chip->ecc.correct = omap_elm_correct_data; in omap_nand_attach_chip()
1979 chip->ecc.read_page = omap_read_page_bch; in omap_nand_attach_chip()
1980 chip->ecc.write_page = omap_write_page_bch; in omap_nand_attach_chip()
1981 chip->ecc.write_subpage = omap_write_subpage_bch; in omap_nand_attach_chip()
1983 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
1989 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
1990 chip->ecc.size = 512; in omap_nand_attach_chip()
1991 chip->ecc.bytes = 13; in omap_nand_attach_chip()
1992 chip->ecc.strength = 8; in omap_nand_attach_chip()
1993 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
1994 chip->ecc.correct = rawnand_sw_bch_correct; in omap_nand_attach_chip()
1995 chip->ecc.calculate = omap_calculate_ecc_bch_sw; in omap_nand_attach_chip()
1998 oobbytes_per_step = chip->ecc.bytes + 1; in omap_nand_attach_chip()
2008 pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n"); in omap_nand_attach_chip()
2009 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2010 chip->ecc.size = 512; in omap_nand_attach_chip()
2012 chip->ecc.bytes = 13 + 1; in omap_nand_attach_chip()
2013 chip->ecc.strength = 8; in omap_nand_attach_chip()
2014 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2015 chip->ecc.correct = omap_elm_correct_data; in omap_nand_attach_chip()
2016 chip->ecc.read_page = omap_read_page_bch; in omap_nand_attach_chip()
2017 chip->ecc.write_page = omap_write_page_bch; in omap_nand_attach_chip()
2018 chip->ecc.write_subpage = omap_write_subpage_bch; in omap_nand_attach_chip()
2020 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
2025 pr_info("Using OMAP_ECC_BCH16_CODE_HW ECC scheme\n"); in omap_nand_attach_chip()
2026 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2027 chip->ecc.size = 512; in omap_nand_attach_chip()
2028 chip->ecc.bytes = 26; in omap_nand_attach_chip()
2029 chip->ecc.strength = 16; in omap_nand_attach_chip()
2030 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2031 chip->ecc.correct = omap_elm_correct_data; in omap_nand_attach_chip()
2032 chip->ecc.read_page = omap_read_page_bch; in omap_nand_attach_chip()
2033 chip->ecc.write_page = omap_write_page_bch; in omap_nand_attach_chip()
2034 chip->ecc.write_subpage = omap_write_subpage_bch; in omap_nand_attach_chip()
2036 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
2040 dev_err(dev, "Invalid or unsupported ECC scheme\n"); in omap_nand_attach_chip()
2045 chip->ecc.steps = mtd->writesize / chip->ecc.size; in omap_nand_attach_chip()
2046 info->neccpg = chip->ecc.steps / ERROR_VECTOR_MAX; in omap_nand_attach_chip()
2051 info->nsteps_per_eccpg = chip->ecc.steps; in omap_nand_attach_chip()
2053 info->eccpg_size = info->nsteps_per_eccpg * chip->ecc.size; in omap_nand_attach_chip()
2054 info->eccpg_bytes = info->nsteps_per_eccpg * chip->ecc.bytes; in omap_nand_attach_chip()
2057 info->nsteps_per_eccpg, chip->ecc.size, in omap_nand_attach_chip()
2058 chip->ecc.bytes); in omap_nand_attach_chip()
2063 /* Check if NAND device's OOB is enough to store ECC signatures */ in omap_nand_attach_chip()
2065 (mtd->writesize / chip->ecc.size)); in omap_nand_attach_chip()
2177 /* Shared among all NAND instances to synchronize access to the ECC Engine */