Lines Matching +full:nand +full:- +full:no +full:- +full:ecc +full:- +full:engine
1 // SPDX-License-Identifier: GPL-2.0-only
10 #include <linux/dma-mapping.h>
18 #include <linux/mtd/nand-ecc-sw-bch.h>
21 #include <linux/omap-dma.h>
29 #include <linux/omap-gpmc.h>
30 #include <linux/platform_data/mtd-nand-omap2.h>
32 #define DRIVER_NAME "omap2-nand"
122 /* GPMC ecc engine settings for read */
129 /* GPMC ecc engine settings for write */
131 #define BCH_ECC_SIZE0 0x0 /* ecc_size0 = 0, no oob protection */
145 struct nand_chip nand; member
170 /* fields specific for BCHx_HW ECC scheme */
172 /* NAND ready gpio */
182 return container_of(mtd_to_nand(mtd), struct omap_nand_info, nand); in mtd_to_omap()
186 * omap_prefetch_enable - configures and starts prefetch transfer
192 * @info: NAND device structure containing platform data
200 return -1; in omap_prefetch_enable()
202 if (readl(info->reg.gpmc_prefetch_control)) in omap_prefetch_enable()
203 return -EBUSY; in omap_prefetch_enable()
206 writel(u32_count, info->reg.gpmc_prefetch_config2); in omap_prefetch_enable()
209 * enable the engine. Set which cs is has requested for. in omap_prefetch_enable()
214 writel(val, info->reg.gpmc_prefetch_config1); in omap_prefetch_enable()
216 /* Start the prefetch engine */ in omap_prefetch_enable()
217 writel(0x1, info->reg.gpmc_prefetch_control); in omap_prefetch_enable()
223 * omap_prefetch_reset - disables and stops the prefetch engine
230 config1 = readl(info->reg.gpmc_prefetch_config1); in omap_prefetch_reset()
232 return -EINVAL; in omap_prefetch_reset()
234 /* Stop the PFPW engine */ in omap_prefetch_reset()
235 writel(0x0, info->reg.gpmc_prefetch_control); in omap_prefetch_reset()
237 /* Reset/disable the PFPW engine */ in omap_prefetch_reset()
238 writel(0x0, info->reg.gpmc_prefetch_config1); in omap_prefetch_reset()
244 * omap_hwcontrol - hardware specific access to control-lines
245 * @chip: NAND chip object
248 * NAND_NCE: bit 0 -> don't care
249 * NAND_CLE: bit 1 -> Command Latch
250 * NAND_ALE: bit 2 -> Address Latch
260 writeb(cmd, info->reg.gpmc_nand_command); in omap_hwcontrol()
263 writeb(cmd, info->reg.gpmc_nand_address); in omap_hwcontrol()
266 writeb(cmd, info->reg.gpmc_nand_data); in omap_hwcontrol()
271 * omap_read_buf8 - read data from NAND controller into buffer
278 struct nand_chip *nand = mtd_to_nand(mtd); in omap_read_buf8() local
280 ioread8_rep(nand->legacy.IO_ADDR_R, buf, len); in omap_read_buf8()
284 * omap_write_buf8 - write buffer to NAND controller
295 while (len--) { in omap_write_buf8()
296 iowrite8(*p++, info->nand.legacy.IO_ADDR_W); in omap_write_buf8()
299 status = info->ops->nand_writebuffer_empty(); in omap_write_buf8()
305 * omap_read_buf16 - read data from NAND controller into buffer
312 struct nand_chip *nand = mtd_to_nand(mtd); in omap_read_buf16() local
314 ioread16_rep(nand->legacy.IO_ADDR_R, buf, len / 2); in omap_read_buf16()
318 * omap_write_buf16 - write buffer to NAND controller
331 while (len--) { in omap_write_buf16()
332 iowrite16(*p++, info->nand.legacy.IO_ADDR_W); in omap_write_buf16()
335 status = info->ops->nand_writebuffer_empty(); in omap_write_buf16()
341 * omap_read_buf_pref - read data from NAND controller into buffer
342 * @chip: NAND chip object
356 if (info->nand.options & NAND_BUSWIDTH_16) in omap_read_buf_pref()
361 len -= len % 4; in omap_read_buf_pref()
365 ret = omap_prefetch_enable(info->gpmc_cs, in omap_read_buf_pref()
368 /* PFPW engine is busy, use cpu copy method */ in omap_read_buf_pref()
369 if (info->nand.options & NAND_BUSWIDTH_16) in omap_read_buf_pref()
375 r_count = readl(info->reg.gpmc_prefetch_status); in omap_read_buf_pref()
378 ioread32_rep(info->nand.legacy.IO_ADDR_R, p, r_count); in omap_read_buf_pref()
380 len -= r_count << 2; in omap_read_buf_pref()
382 /* disable and stop the PFPW engine */ in omap_read_buf_pref()
383 omap_prefetch_reset(info->gpmc_cs, info); in omap_read_buf_pref()
388 * omap_write_buf_pref - write buffer to NAND controller
389 * @chip: NAND chip object
406 writeb(*buf, info->nand.legacy.IO_ADDR_W); in omap_write_buf_pref()
408 len--; in omap_write_buf_pref()
412 ret = omap_prefetch_enable(info->gpmc_cs, in omap_write_buf_pref()
415 /* PFPW engine is busy, use cpu copy method */ in omap_write_buf_pref()
416 if (info->nand.options & NAND_BUSWIDTH_16) in omap_write_buf_pref()
422 w_count = readl(info->reg.gpmc_prefetch_status); in omap_write_buf_pref()
425 for (i = 0; (i < w_count) && len; i++, len -= 2) in omap_write_buf_pref()
426 iowrite16(*p++, info->nand.legacy.IO_ADDR_W); in omap_write_buf_pref()
428 /* wait for data to flushed-out before reset the prefetch */ in omap_write_buf_pref()
434 val = readl(info->reg.gpmc_prefetch_status); in omap_write_buf_pref()
438 /* disable and stop the PFPW engine */ in omap_write_buf_pref()
439 omap_prefetch_reset(info->gpmc_cs, info); in omap_write_buf_pref()
476 n = dma_map_sg(info->dma->device->dev, &sg, 1, dir); in omap_nand_dma_transfer()
478 dev_err(&info->pdev->dev, in omap_nand_dma_transfer()
483 tx = dmaengine_prep_slave_sg(info->dma, &sg, n, in omap_nand_dma_transfer()
489 tx->callback = omap_nand_dma_callback; in omap_nand_dma_transfer()
490 tx->callback_param = &info->comp; in omap_nand_dma_transfer()
493 init_completion(&info->comp); in omap_nand_dma_transfer()
496 dma_async_issue_pending(info->dma); in omap_nand_dma_transfer()
499 ret = omap_prefetch_enable(info->gpmc_cs, in omap_nand_dma_transfer()
502 /* PFPW engine is busy, use cpu copy method */ in omap_nand_dma_transfer()
505 wait_for_completion(&info->comp); in omap_nand_dma_transfer()
511 val = readl(info->reg.gpmc_prefetch_status); in omap_nand_dma_transfer()
515 /* disable and stop the PFPW engine */ in omap_nand_dma_transfer()
516 omap_prefetch_reset(info->gpmc_cs, info); in omap_nand_dma_transfer()
518 dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); in omap_nand_dma_transfer()
522 dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); in omap_nand_dma_transfer()
524 if (info->nand.options & NAND_BUSWIDTH_16) in omap_nand_dma_transfer()
534 * omap_read_buf_dma_pref - read data from NAND controller into buffer
535 * @chip: NAND chip object
544 if (len <= mtd->oobsize) in omap_read_buf_dma_pref()
552 * omap_write_buf_dma_pref - write buffer to NAND controller
553 * @chip: NAND chip object
562 if (len <= mtd->oobsize) in omap_write_buf_dma_pref()
570 * omap_nand_irq - GPMC irq handler
579 bytes = readl(info->reg.gpmc_prefetch_status); in omap_nand_irq()
582 if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ in omap_nand_irq()
583 if (this_irq == info->gpmc_irq_count) in omap_nand_irq()
586 if (info->buf_len && (info->buf_len < bytes)) in omap_nand_irq()
587 bytes = info->buf_len; in omap_nand_irq()
588 else if (!info->buf_len) in omap_nand_irq()
590 iowrite32_rep(info->nand.legacy.IO_ADDR_W, (u32 *)info->buf, in omap_nand_irq()
592 info->buf = info->buf + bytes; in omap_nand_irq()
593 info->buf_len -= bytes; in omap_nand_irq()
596 ioread32_rep(info->nand.legacy.IO_ADDR_R, (u32 *)info->buf, in omap_nand_irq()
598 info->buf = info->buf + bytes; in omap_nand_irq()
600 if (this_irq == info->gpmc_irq_count) in omap_nand_irq()
607 complete(&info->comp); in omap_nand_irq()
609 disable_irq_nosync(info->gpmc_irq_fifo); in omap_nand_irq()
610 disable_irq_nosync(info->gpmc_irq_count); in omap_nand_irq()
616 * omap_read_buf_irq_pref - read data from NAND controller into buffer
617 * @chip: NAND chip object
628 if (len <= mtd->oobsize) { in omap_read_buf_irq_pref()
633 info->iomode = OMAP_NAND_IO_READ; in omap_read_buf_irq_pref()
634 info->buf = buf; in omap_read_buf_irq_pref()
635 init_completion(&info->comp); in omap_read_buf_irq_pref()
638 ret = omap_prefetch_enable(info->gpmc_cs, in omap_read_buf_irq_pref()
641 /* PFPW engine is busy, use cpu copy method */ in omap_read_buf_irq_pref()
644 info->buf_len = len; in omap_read_buf_irq_pref()
646 enable_irq(info->gpmc_irq_count); in omap_read_buf_irq_pref()
647 enable_irq(info->gpmc_irq_fifo); in omap_read_buf_irq_pref()
650 wait_for_completion(&info->comp); in omap_read_buf_irq_pref()
652 /* disable and stop the PFPW engine */ in omap_read_buf_irq_pref()
653 omap_prefetch_reset(info->gpmc_cs, info); in omap_read_buf_irq_pref()
657 if (info->nand.options & NAND_BUSWIDTH_16) in omap_read_buf_irq_pref()
664 * omap_write_buf_irq_pref - write buffer to NAND controller
665 * @chip: NAND chip object
678 if (len <= mtd->oobsize) { in omap_write_buf_irq_pref()
683 info->iomode = OMAP_NAND_IO_WRITE; in omap_write_buf_irq_pref()
684 info->buf = (u_char *) buf; in omap_write_buf_irq_pref()
685 init_completion(&info->comp); in omap_write_buf_irq_pref()
688 ret = omap_prefetch_enable(info->gpmc_cs, in omap_write_buf_irq_pref()
691 /* PFPW engine is busy, use cpu copy method */ in omap_write_buf_irq_pref()
694 info->buf_len = len; in omap_write_buf_irq_pref()
696 enable_irq(info->gpmc_irq_count); in omap_write_buf_irq_pref()
697 enable_irq(info->gpmc_irq_fifo); in omap_write_buf_irq_pref()
700 wait_for_completion(&info->comp); in omap_write_buf_irq_pref()
702 /* wait for data to flushed-out before reset the prefetch */ in omap_write_buf_irq_pref()
706 val = readl(info->reg.gpmc_prefetch_status); in omap_write_buf_irq_pref()
711 /* disable and stop the PFPW engine */ in omap_write_buf_irq_pref()
712 omap_prefetch_reset(info->gpmc_cs, info); in omap_write_buf_irq_pref()
716 if (info->nand.options & NAND_BUSWIDTH_16) in omap_write_buf_irq_pref()
723 * gen_true_ecc - This function will generate true ECC value
724 * @ecc_buf: buffer to store ecc code
726 * This generated true ECC value can be used when correcting
727 * data read from NAND flash memory core
743 * omap_compare_ecc - Detect (2 bits) and correct (1 bit) error in data
744 * @ecc_data1: ecc code from nand spare area
745 * @ecc_data2: ecc code from hardware register obtained from hardware ecc
748 * This function compares two ECC's and indicates if there is an error.
750 * If there is no error, %0 is returned. If there is an error but it
751 * was corrected, %1 is returned. Otherwise, %-1 is returned.
753 static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ in omap_compare_ecc()
824 * ECC values are equal in omap_compare_ecc()
830 pr_debug("ECC UNCORRECTED_ERROR 1\n"); in omap_compare_ecc()
831 return -EBADMSG; in omap_compare_ecc()
834 /* UN-Correctable error */ in omap_compare_ecc()
835 pr_debug("ECC UNCORRECTED_ERROR B\n"); in omap_compare_ecc()
836 return -EBADMSG; in omap_compare_ecc()
852 pr_debug("Correcting single bit ECC error at offset: " in omap_compare_ecc()
866 return -EBADMSG; in omap_compare_ecc()
871 * omap_correct_data - Compares the ECC read with HW generated ECC
872 * @chip: NAND chip object
874 * @read_ecc: ecc read from nand flash
875 * @calc_ecc: ecc read from HW ECC registers
877 * Compares the ecc read from nand spare area with ECC registers values
878 * and if ECC's mismatched, it will call 'omap_compare_ecc' for error
879 * detection and correction. If there are no errors, %0 is returned. If
881 * corrected errors is returned. If uncorrectable errors exist, %-1 is
892 if (info->nand.ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST && in omap_correct_data()
893 info->nand.ecc.size == 2048) in omap_correct_data()
914 * omap_calculate_ecc - Generate non-inverted ECC bytes.
915 * @chip: NAND chip object
916 * @dat: The pointer to data on which ecc is computed
919 * Using noninverted ECC can be considered ugly since writing a blank
920 * page ie. padding will clear the ECC bytes. This is no problem as long
922 * an erased page will produce an ECC mismatch between generated and read
923 * ECC bytes that has to be dealt with separately.
931 val = readl(info->reg.gpmc_ecc_config); in omap_calculate_ecc()
932 if (((val >> ECC_CONFIG_CS_SHIFT) & CS_MASK) != info->gpmc_cs) in omap_calculate_ecc()
933 return -EINVAL; in omap_calculate_ecc()
935 /* read ecc result */ in omap_calculate_ecc()
936 val = readl(info->reg.gpmc_ecc1_result); in omap_calculate_ecc()
946 * omap_enable_hwecc - This function enables the hardware ecc functionality
947 * @chip: NAND chip object
953 unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; in omap_enable_hwecc()
956 /* clear ecc and enable bits */ in omap_enable_hwecc()
958 writel(val, info->reg.gpmc_ecc_control); in omap_enable_hwecc()
960 /* program ecc and result sizes */ in omap_enable_hwecc()
961 val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | in omap_enable_hwecc()
963 writel(val, info->reg.gpmc_ecc_size_config); in omap_enable_hwecc()
968 writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); in omap_enable_hwecc()
971 writel(ECCCLEAR, info->reg.gpmc_ecc_control); in omap_enable_hwecc()
974 dev_info(&info->pdev->dev, in omap_enable_hwecc()
979 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ in omap_enable_hwecc()
980 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); in omap_enable_hwecc()
981 writel(val, info->reg.gpmc_ecc_config); in omap_enable_hwecc()
985 * omap_wait - wait until the command is done
986 * @this: NAND Chip structure
989 * the way it is called from MTD layer, we should wait till the NAND
993 * general NAND and SmartMedia specs
1003 writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command); in omap_wait()
1005 status = readb(info->reg.gpmc_nand_data); in omap_wait()
1011 status = readb(info->reg.gpmc_nand_data); in omap_wait()
1016 * omap_dev_ready - checks the NAND Ready GPIO line
1017 * @chip: NAND chip object
1025 return gpiod_get_value(info->ready_gpiod); in omap_dev_ready()
1029 * omap_enable_hwecc_bch - Program GPMC to perform BCH ECC calculation
1030 * @chip: NAND chip object
1033 * When using BCH with SW correction (i.e. no ELM), sector size is set
1036 * eccsize0 = 0 (no additional protected byte in spare area)
1045 enum omap_ecc ecc_opt = info->ecc_opt; in omap_enable_hwecc_bch()
1049 /* GPMC configurations for calculating ECC */ in omap_enable_hwecc_bch()
1060 nsectors = chip->ecc.steps; in omap_enable_hwecc_bch()
1080 nsectors = chip->ecc.steps; in omap_enable_hwecc_bch()
1093 nsectors = chip->ecc.steps; in omap_enable_hwecc_bch()
1096 ecc_size0 = 52; /* ECC bits in nibbles per sector */ in omap_enable_hwecc_bch()
1097 ecc_size1 = 0; /* non-ECC bits in nibbles per sector */ in omap_enable_hwecc_bch()
1108 writel(ECC1, info->reg.gpmc_ecc_control); in omap_enable_hwecc_bch()
1110 /* Configure ecc size for BCH */ in omap_enable_hwecc_bch()
1112 writel(val, info->reg.gpmc_ecc_size_config); in omap_enable_hwecc_bch()
1114 dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; in omap_enable_hwecc_bch()
1121 (((nsectors-1) & 0x7) << 4) | /* number of sectors */ in omap_enable_hwecc_bch()
1122 (info->gpmc_cs << 1) | /* ECC CS */ in omap_enable_hwecc_bch()
1123 (0x1)); /* enable ECC */ in omap_enable_hwecc_bch()
1125 writel(val, info->reg.gpmc_ecc_config); in omap_enable_hwecc_bch()
1127 /* Clear ecc and enable bits */ in omap_enable_hwecc_bch()
1128 writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); in omap_enable_hwecc_bch()
1136 * _omap_calculate_ecc_bch - Generate ECC bytes for one sector
1138 * @dat: The pointer to data on which ecc is computed
1142 * Support calculating of BCH4/8/16 ECC vectors for one sector
1149 int eccbytes = info->nand.ecc.bytes; in _omap_calculate_ecc_bch()
1150 struct gpmc_nand_regs *gpmc_regs = &info->reg; in _omap_calculate_ecc_bch()
1157 switch (info->ecc_opt) { in _omap_calculate_ecc_bch()
1160 bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); in _omap_calculate_ecc_bch()
1161 bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); in _omap_calculate_ecc_bch()
1162 bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]); in _omap_calculate_ecc_bch()
1163 bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]); in _omap_calculate_ecc_bch()
1180 bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); in _omap_calculate_ecc_bch()
1181 bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); in _omap_calculate_ecc_bch()
1192 val = readl(gpmc_regs->gpmc_bch_result6[i]); in _omap_calculate_ecc_bch()
1195 val = readl(gpmc_regs->gpmc_bch_result5[i]); in _omap_calculate_ecc_bch()
1200 val = readl(gpmc_regs->gpmc_bch_result4[i]); in _omap_calculate_ecc_bch()
1205 val = readl(gpmc_regs->gpmc_bch_result3[i]); in _omap_calculate_ecc_bch()
1210 val = readl(gpmc_regs->gpmc_bch_result2[i]); in _omap_calculate_ecc_bch()
1215 val = readl(gpmc_regs->gpmc_bch_result1[i]); in _omap_calculate_ecc_bch()
1220 val = readl(gpmc_regs->gpmc_bch_result0[i]); in _omap_calculate_ecc_bch()
1227 return -EINVAL; in _omap_calculate_ecc_bch()
1230 /* ECC scheme specific syndrome customizations */ in _omap_calculate_ecc_bch()
1231 switch (info->ecc_opt) { in _omap_calculate_ecc_bch()
1234 * ECC of blank pages results in 0x0 on reading back in _omap_calculate_ecc_bch()
1240 /* Set 8th ECC byte as 0x0 for ROM compatibility */ in _omap_calculate_ecc_bch()
1241 ecc_calc[eccbytes - 1] = 0x0; in _omap_calculate_ecc_bch()
1245 * ECC of blank pages results in 0x0 on reading back in _omap_calculate_ecc_bch()
1251 /* Set 14th ECC byte as 0x0 for ROM compatibility */ in _omap_calculate_ecc_bch()
1252 ecc_calc[eccbytes - 1] = 0x0; in _omap_calculate_ecc_bch()
1257 return -EINVAL; in _omap_calculate_ecc_bch()
1264 * omap_calculate_ecc_bch_sw - ECC generator for sector for SW based correction
1265 * @chip: NAND chip object
1266 * @dat: The pointer to data on which ecc is computed
1267 * @ecc_calc: Buffer storing the calculated ECC bytes
1269 * Support calculating of BCH4/8/16 ECC vectors for one sector. This is used
1270 * when SW based correction is required as ECC is required for one sector
1280 * omap_calculate_ecc_bch_multi - Generate ECC for multiple sectors
1282 * @dat: The pointer to data on which ecc is computed
1283 * @ecc_calc: Buffer storing the calculated ECC bytes
1285 * Support calculating of BCH4/8/16 ecc vectors for the entire page in one go.
1291 int eccbytes = info->nand.ecc.bytes; in omap_calculate_ecc_bch_multi()
1295 nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; in omap_calculate_ecc_bch_multi()
1308 * erased_sector_bitflips - count bit flips
1322 for (i = 0; i < info->nand.ecc.size; i++) { in erased_sector_bitflips()
1324 if (flip_bits > info->nand.ecc.strength) in erased_sector_bitflips()
1328 for (i = 0; i < info->nand.ecc.bytes - 1; i++) { in erased_sector_bitflips()
1330 if (flip_bits > info->nand.ecc.strength) in erased_sector_bitflips()
1339 memset(data, 0xFF, info->nand.ecc.size); in erased_sector_bitflips()
1340 memset(oob, 0xFF, info->nand.ecc.bytes); in erased_sector_bitflips()
1347 * omap_elm_correct_data - corrects page data area in case error reported
1348 * @chip: NAND chip object
1350 * @read_ecc: ecc read from nand flash
1351 * @calc_ecc: ecc read from HW ECC registers
1353 * Calculated ecc vector reported as zero in case of non-error pages.
1354 * In case of non-zero ecc vector, first filter out erased-pages, and
1355 * then process data via ELM to detect bit-flips.
1361 struct nand_ecc_ctrl *ecc = &info->nand.ecc; in omap_elm_correct_data() local
1362 int eccsteps = info->nsteps_per_eccpg; in omap_elm_correct_data()
1375 switch (info->ecc_opt) { in omap_elm_correct_data()
1377 /* omit 7th ECC byte reserved for ROM code compatibility */ in omap_elm_correct_data()
1378 actual_eccbytes = ecc->bytes - 1; in omap_elm_correct_data()
1382 /* omit 14th ECC byte reserved for ROM code compatibility */ in omap_elm_correct_data()
1383 actual_eccbytes = ecc->bytes - 1; in omap_elm_correct_data()
1387 actual_eccbytes = ecc->bytes; in omap_elm_correct_data()
1391 dev_err(&info->pdev->dev, "invalid driver configuration\n"); in omap_elm_correct_data()
1392 return -EINVAL; in omap_elm_correct_data()
1403 * In case of error, non zero ecc reported. in omap_elm_correct_data()
1407 eccflag = 1; /* non zero ecc, error present */ in omap_elm_correct_data()
1416 * calc_ecc[] matches pattern for ECC(all 0xff) in omap_elm_correct_data()
1417 * so this is definitely an erased-page in omap_elm_correct_data()
1420 buf = &data[info->nand.ecc.size * i]; in omap_elm_correct_data()
1422 * count number of 0-bits in read_buf. in omap_elm_correct_data()
1424 * check is introduced in generic NAND driver in omap_elm_correct_data()
1430 * number of 0-bits within ECC limits in omap_elm_correct_data()
1431 * So this may be an erased-page in omap_elm_correct_data()
1436 * Too many 0-bits. It may be a in omap_elm_correct_data()
1437 * - programmed-page, OR in omap_elm_correct_data()
1438 * - erased-page with many bit-flips in omap_elm_correct_data()
1447 /* Update the ecc vector */ in omap_elm_correct_data()
1448 calc_ecc += ecc->bytes; in omap_elm_correct_data()
1449 read_ecc += ecc->bytes; in omap_elm_correct_data()
1457 elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec); in omap_elm_correct_data()
1462 dev_err(&info->pdev->dev, in omap_elm_correct_data()
1463 "uncorrectable bit-flips found\n"); in omap_elm_correct_data()
1464 err = -EBADMSG; in omap_elm_correct_data()
1467 switch (info->ecc_opt) { in omap_elm_correct_data()
1478 return -EINVAL; in omap_elm_correct_data()
1480 error_max = (ecc->size + actual_eccbytes) * 8; in omap_elm_correct_data()
1485 byte_pos = (error_max - pos - 1) / 8; in omap_elm_correct_data()
1494 (byte_pos - 512), in omap_elm_correct_data()
1495 spare_ecc[byte_pos - 512]); in omap_elm_correct_data()
1496 spare_ecc[byte_pos - 512] ^= in omap_elm_correct_data()
1500 dev_err(&info->pdev->dev, in omap_elm_correct_data()
1501 "invalid bit-flip @ %d:%d\n", in omap_elm_correct_data()
1503 err = -EBADMSG; in omap_elm_correct_data()
1512 data += ecc->size; in omap_elm_correct_data()
1513 spare_ecc += ecc->bytes; in omap_elm_correct_data()
1520 * omap_write_page_bch - BCH ecc based write page function for entire page
1521 * @chip: nand chip info structure
1523 * @oob_required: must write chip->oob_poi to OOB
1533 uint8_t *ecc_calc = chip->ecc.calc_buf; in omap_write_page_bch()
1541 for (eccpg = 0; eccpg < info->neccpg; eccpg++) { in omap_write_page_bch()
1542 /* Enable GPMC ecc engine */ in omap_write_page_bch()
1543 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in omap_write_page_bch()
1546 chip->legacy.write_buf(chip, buf + (eccpg * info->eccpg_size), in omap_write_page_bch()
1547 info->eccpg_size); in omap_write_page_bch()
1549 /* Update ecc vector from GPMC result registers */ in omap_write_page_bch()
1551 buf + (eccpg * info->eccpg_size), in omap_write_page_bch()
1557 chip->oob_poi, in omap_write_page_bch()
1558 eccpg * info->eccpg_bytes, in omap_write_page_bch()
1559 info->eccpg_bytes); in omap_write_page_bch()
1564 /* Write ecc vector to OOB area */ in omap_write_page_bch()
1565 chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize); in omap_write_page_bch()
1571 * omap_write_subpage_bch - BCH hardware ECC based subpage write
1572 * @chip: nand chip info structure
1576 * @oob_required: must write chip->oob_poi to OOB
1587 u8 *ecc_calc = chip->ecc.calc_buf; in omap_write_subpage_bch()
1588 int ecc_size = chip->ecc.size; in omap_write_subpage_bch()
1589 int ecc_bytes = chip->ecc.bytes; in omap_write_subpage_bch()
1591 u32 end_step = (offset + data_len - 1) / ecc_size; in omap_write_subpage_bch()
1597 * as ECC is calculated by hardware. in omap_write_subpage_bch()
1598 * ECC is calculated for all subpages but we choose in omap_write_subpage_bch()
1605 for (eccpg = 0; eccpg < info->neccpg; eccpg++) { in omap_write_subpage_bch()
1606 /* Enable GPMC ECC engine */ in omap_write_subpage_bch()
1607 chip->ecc.hwctl(chip, NAND_ECC_WRITE); in omap_write_subpage_bch()
1610 chip->legacy.write_buf(chip, buf + (eccpg * info->eccpg_size), in omap_write_subpage_bch()
1611 info->eccpg_size); in omap_write_subpage_bch()
1613 for (step = 0; step < info->nsteps_per_eccpg; step++) { in omap_write_subpage_bch()
1614 unsigned int base_step = eccpg * info->nsteps_per_eccpg; in omap_write_subpage_bch()
1615 const u8 *bufoffs = buf + (eccpg * info->eccpg_size); in omap_write_subpage_bch()
1617 /* Mask ECC of un-touched subpages with 0xFFs */ in omap_write_subpage_bch()
1633 * Copy the calculated ECC for the whole page including the in omap_write_subpage_bch()
1636 ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, in omap_write_subpage_bch()
1637 eccpg * info->eccpg_bytes, in omap_write_subpage_bch()
1638 info->eccpg_bytes); in omap_write_subpage_bch()
1643 /* write OOB buffer to NAND device */ in omap_write_subpage_bch()
1644 chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize); in omap_write_subpage_bch()
1650 * omap_read_page_bch - BCH ecc based page read function for entire page
1651 * @chip: nand chip info structure
1653 * @oob_required: caller requires OOB data read to chip->oob_poi
1656 * For BCH ecc scheme, GPMC used for syndrome calculation and ELM module
1660 * ecc engine enabled. ecc vector updated after read of OOB data.
1661 * For non error pages ecc vector reported as zero.
1668 uint8_t *ecc_calc = chip->ecc.calc_buf; in omap_read_page_bch()
1669 uint8_t *ecc_code = chip->ecc.code_buf; in omap_read_page_bch()
1677 for (eccpg = 0; eccpg < info->neccpg; eccpg++) { in omap_read_page_bch()
1678 /* Enable GPMC ecc engine */ in omap_read_page_bch()
1679 chip->ecc.hwctl(chip, NAND_ECC_READ); in omap_read_page_bch()
1682 ret = nand_change_read_column_op(chip, eccpg * info->eccpg_size, in omap_read_page_bch()
1683 buf + (eccpg * info->eccpg_size), in omap_read_page_bch()
1684 info->eccpg_size, false); in omap_read_page_bch()
1690 mtd->writesize + BBM_LEN + in omap_read_page_bch()
1691 (eccpg * info->eccpg_bytes), in omap_read_page_bch()
1692 chip->oob_poi + BBM_LEN + in omap_read_page_bch()
1693 (eccpg * info->eccpg_bytes), in omap_read_page_bch()
1694 info->eccpg_bytes, false); in omap_read_page_bch()
1698 /* Calculate ecc bytes */ in omap_read_page_bch()
1700 buf + (eccpg * info->eccpg_size), in omap_read_page_bch()
1706 chip->oob_poi, in omap_read_page_bch()
1707 eccpg * info->eccpg_bytes, in omap_read_page_bch()
1708 info->eccpg_bytes); in omap_read_page_bch()
1712 stat = chip->ecc.correct(chip, in omap_read_page_bch()
1713 buf + (eccpg * info->eccpg_size), in omap_read_page_bch()
1716 mtd->ecc_stats.failed++; in omap_read_page_bch()
1718 mtd->ecc_stats.corrected += stat; in omap_read_page_bch()
1727 * is_elm_present - checks for presence of ELM module by scanning DT nodes
1728 * @info: NAND device structure containing platform data
1736 /* check whether elm-id is passed via DT */ in is_elm_present()
1738 dev_err(&info->pdev->dev, "ELM devicetree node not found\n"); in is_elm_present()
1744 dev_err(&info->pdev->dev, "ELM device not found\n"); in is_elm_present()
1748 info->elm_dev = &pdev->dev; in is_elm_present()
1756 switch (info->ecc_opt) { in omap2_nand_ecc_check()
1778 dev_err(&info->pdev->dev, in omap2_nand_ecc_check()
1783 dev_err(&info->pdev->dev, in omap2_nand_ecc_check()
1787 if (ecc_needs_elm && !is_elm_present(info, info->elm_of_node)) { in omap2_nand_ecc_check()
1788 dev_err(&info->pdev->dev, "ELM not available\n"); in omap2_nand_ecc_check()
1796 [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
1798 [NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
1799 [NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
1804 struct device_node *child = dev->of_node; in omap_get_dt_info()
1811 return -EINVAL; in omap_get_dt_info()
1814 info->gpmc_cs = cs; in omap_get_dt_info()
1816 /* detect availability of ELM module. Won't be present pre-OMAP4 */ in omap_get_dt_info()
1817 info->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); in omap_get_dt_info()
1818 if (!info->elm_of_node) { in omap_get_dt_info()
1819 info->elm_of_node = of_parse_phandle(child, "elm_id", 0); in omap_get_dt_info()
1820 if (!info->elm_of_node) in omap_get_dt_info()
1821 dev_dbg(dev, "ti,elm-id not in DT\n"); in omap_get_dt_info()
1824 /* select ecc-scheme for NAND */ in omap_get_dt_info()
1825 if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { in omap_get_dt_info()
1826 dev_err(dev, "ti,nand-ecc-opt not found\n"); in omap_get_dt_info()
1827 return -EINVAL; in omap_get_dt_info()
1831 info->ecc_opt = OMAP_ECC_HAM1_CODE_SW; in omap_get_dt_info()
1833 !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) { in omap_get_dt_info()
1834 info->ecc_opt = OMAP_ECC_HAM1_CODE_HW; in omap_get_dt_info()
1836 if (info->elm_of_node) in omap_get_dt_info()
1837 info->ecc_opt = OMAP_ECC_BCH4_CODE_HW; in omap_get_dt_info()
1839 info->ecc_opt = OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; in omap_get_dt_info()
1841 if (info->elm_of_node) in omap_get_dt_info()
1842 info->ecc_opt = OMAP_ECC_BCH8_CODE_HW; in omap_get_dt_info()
1844 info->ecc_opt = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; in omap_get_dt_info()
1846 info->ecc_opt = OMAP_ECC_BCH16_CODE_HW; in omap_get_dt_info()
1848 dev_err(dev, "unrecognized value for ti,nand-ecc-opt\n"); in omap_get_dt_info()
1849 return -EINVAL; in omap_get_dt_info()
1853 if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) { in omap_get_dt_info()
1856 info->xfer_type = i; in omap_get_dt_info()
1861 dev_err(dev, "unrecognized value for ti,nand-xfer-type\n"); in omap_get_dt_info()
1862 return -EINVAL; in omap_get_dt_info()
1872 struct nand_chip *chip = &info->nand; in omap_ooblayout_ecc()
1875 if (info->ecc_opt == OMAP_ECC_HAM1_CODE_HW && in omap_ooblayout_ecc()
1876 !(chip->options & NAND_BUSWIDTH_16)) in omap_ooblayout_ecc()
1880 return -ERANGE; in omap_ooblayout_ecc()
1882 oobregion->offset = off; in omap_ooblayout_ecc()
1883 oobregion->length = chip->ecc.total; in omap_ooblayout_ecc()
1892 struct nand_chip *chip = &info->nand; in omap_ooblayout_free()
1895 if (info->ecc_opt == OMAP_ECC_HAM1_CODE_HW && in omap_ooblayout_free()
1896 !(chip->options & NAND_BUSWIDTH_16)) in omap_ooblayout_free()
1900 return -ERANGE; in omap_ooblayout_free()
1902 off += chip->ecc.total; in omap_ooblayout_free()
1903 if (off >= mtd->oobsize) in omap_ooblayout_free()
1904 return -ERANGE; in omap_ooblayout_free()
1906 oobregion->offset = off; in omap_ooblayout_free()
1907 oobregion->length = mtd->oobsize - off; in omap_ooblayout_free()
1913 .ecc = omap_ooblayout_ecc,
1920 struct nand_device *nand = mtd_to_nanddev(mtd); in omap_sw_ooblayout_ecc() local
1921 unsigned int nsteps = nanddev_get_ecc_nsteps(nand); in omap_sw_ooblayout_ecc()
1922 unsigned int ecc_bytes = nanddev_get_ecc_bytes_per_step(nand); in omap_sw_ooblayout_ecc()
1926 return -ERANGE; in omap_sw_ooblayout_ecc()
1930 * reserved after each ECC step. in omap_sw_ooblayout_ecc()
1932 oobregion->offset = off + (section * (ecc_bytes + 1)); in omap_sw_ooblayout_ecc()
1933 oobregion->length = ecc_bytes; in omap_sw_ooblayout_ecc()
1941 struct nand_device *nand = mtd_to_nanddev(mtd); in omap_sw_ooblayout_free() local
1942 unsigned int nsteps = nanddev_get_ecc_nsteps(nand); in omap_sw_ooblayout_free()
1943 unsigned int ecc_bytes = nanddev_get_ecc_bytes_per_step(nand); in omap_sw_ooblayout_free()
1947 return -ERANGE; in omap_sw_ooblayout_free()
1951 * reserved after each ECC step. in omap_sw_ooblayout_free()
1954 if (off >= mtd->oobsize) in omap_sw_ooblayout_free()
1955 return -ERANGE; in omap_sw_ooblayout_free()
1957 oobregion->offset = off; in omap_sw_ooblayout_free()
1958 oobregion->length = mtd->oobsize - off; in omap_sw_ooblayout_free()
1964 .ecc = omap_sw_ooblayout_ecc,
1972 struct device *dev = &info->pdev->dev; in omap_nand_attach_chip()
1974 int elm_bch_strength = -1; in omap_nand_attach_chip()
1979 if (chip->bbt_options & NAND_BBT_USE_FLASH) in omap_nand_attach_chip()
1980 chip->bbt_options |= NAND_BBT_NO_OOB; in omap_nand_attach_chip()
1982 chip->options |= NAND_SKIP_BBTSCAN; in omap_nand_attach_chip()
1984 /* Re-populate low-level callbacks based on xfer modes */ in omap_nand_attach_chip()
1985 switch (info->xfer_type) { in omap_nand_attach_chip()
1987 chip->legacy.read_buf = omap_read_buf_pref; in omap_nand_attach_chip()
1988 chip->legacy.write_buf = omap_write_buf_pref; in omap_nand_attach_chip()
1998 info->dma = dma_request_chan(dev->parent, "rxtx"); in omap_nand_attach_chip()
2000 if (IS_ERR(info->dma)) { in omap_nand_attach_chip()
2001 dev_err(dev, "DMA engine request failed\n"); in omap_nand_attach_chip()
2002 return PTR_ERR(info->dma); in omap_nand_attach_chip()
2007 cfg.src_addr = info->phys_base; in omap_nand_attach_chip()
2008 cfg.dst_addr = info->phys_base; in omap_nand_attach_chip()
2013 err = dmaengine_slave_config(info->dma, &cfg); in omap_nand_attach_chip()
2016 "DMA engine slave config failed: %d\n", in omap_nand_attach_chip()
2020 chip->legacy.read_buf = omap_read_buf_dma_pref; in omap_nand_attach_chip()
2021 chip->legacy.write_buf = omap_write_buf_dma_pref; in omap_nand_attach_chip()
2026 info->gpmc_irq_fifo = platform_get_irq(info->pdev, 0); in omap_nand_attach_chip()
2027 if (info->gpmc_irq_fifo <= 0) in omap_nand_attach_chip()
2028 return -ENODEV; in omap_nand_attach_chip()
2029 err = devm_request_irq(dev, info->gpmc_irq_fifo, in omap_nand_attach_chip()
2031 "gpmc-nand-fifo", info); in omap_nand_attach_chip()
2034 info->gpmc_irq_fifo, err); in omap_nand_attach_chip()
2035 info->gpmc_irq_fifo = 0; in omap_nand_attach_chip()
2039 info->gpmc_irq_count = platform_get_irq(info->pdev, 1); in omap_nand_attach_chip()
2040 if (info->gpmc_irq_count <= 0) in omap_nand_attach_chip()
2041 return -ENODEV; in omap_nand_attach_chip()
2042 err = devm_request_irq(dev, info->gpmc_irq_count, in omap_nand_attach_chip()
2044 "gpmc-nand-count", info); in omap_nand_attach_chip()
2047 info->gpmc_irq_count, err); in omap_nand_attach_chip()
2048 info->gpmc_irq_count = 0; in omap_nand_attach_chip()
2052 chip->legacy.read_buf = omap_read_buf_irq_pref; in omap_nand_attach_chip()
2053 chip->legacy.write_buf = omap_write_buf_irq_pref; in omap_nand_attach_chip()
2058 dev_err(dev, "xfer_type %d not supported!\n", info->xfer_type); in omap_nand_attach_chip()
2059 return -EINVAL; in omap_nand_attach_chip()
2063 return -EINVAL; in omap_nand_attach_chip()
2069 if (info->ecc_opt == OMAP_ECC_HAM1_CODE_SW) { in omap_nand_attach_chip()
2070 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in omap_nand_attach_chip()
2071 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in omap_nand_attach_chip()
2075 /* Populate MTD interface based on ECC scheme */ in omap_nand_attach_chip()
2076 switch (info->ecc_opt) { in omap_nand_attach_chip()
2078 dev_info(dev, "nand: using OMAP_ECC_HAM1_CODE_HW\n"); in omap_nand_attach_chip()
2079 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2080 chip->ecc.bytes = 3; in omap_nand_attach_chip()
2081 chip->ecc.size = 512; in omap_nand_attach_chip()
2082 chip->ecc.strength = 1; in omap_nand_attach_chip()
2083 chip->ecc.calculate = omap_calculate_ecc; in omap_nand_attach_chip()
2084 chip->ecc.hwctl = omap_enable_hwecc; in omap_nand_attach_chip()
2085 chip->ecc.correct = omap_correct_data; in omap_nand_attach_chip()
2087 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
2089 if (!(chip->options & NAND_BUSWIDTH_16)) in omap_nand_attach_chip()
2095 pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n"); in omap_nand_attach_chip()
2096 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2097 chip->ecc.size = 512; in omap_nand_attach_chip()
2098 chip->ecc.bytes = 7; in omap_nand_attach_chip()
2099 chip->ecc.strength = 4; in omap_nand_attach_chip()
2100 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2101 chip->ecc.correct = rawnand_sw_bch_correct; in omap_nand_attach_chip()
2102 chip->ecc.calculate = omap_calculate_ecc_bch_sw; in omap_nand_attach_chip()
2105 oobbytes_per_step = chip->ecc.bytes + 1; in omap_nand_attach_chip()
2115 pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n"); in omap_nand_attach_chip()
2116 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2117 chip->ecc.size = 512; in omap_nand_attach_chip()
2118 /* 14th bit is kept reserved for ROM-code compatibility */ in omap_nand_attach_chip()
2119 chip->ecc.bytes = 7 + 1; in omap_nand_attach_chip()
2120 chip->ecc.strength = 4; in omap_nand_attach_chip()
2121 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2122 chip->ecc.correct = omap_elm_correct_data; in omap_nand_attach_chip()
2123 chip->ecc.read_page = omap_read_page_bch; in omap_nand_attach_chip()
2124 chip->ecc.write_page = omap_write_page_bch; in omap_nand_attach_chip()
2125 chip->ecc.write_subpage = omap_write_subpage_bch; in omap_nand_attach_chip()
2127 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
2132 pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); in omap_nand_attach_chip()
2133 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2134 chip->ecc.size = 512; in omap_nand_attach_chip()
2135 chip->ecc.bytes = 13; in omap_nand_attach_chip()
2136 chip->ecc.strength = 8; in omap_nand_attach_chip()
2137 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2138 chip->ecc.correct = rawnand_sw_bch_correct; in omap_nand_attach_chip()
2139 chip->ecc.calculate = omap_calculate_ecc_bch_sw; in omap_nand_attach_chip()
2142 oobbytes_per_step = chip->ecc.bytes + 1; in omap_nand_attach_chip()
2152 pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n"); in omap_nand_attach_chip()
2153 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2154 chip->ecc.size = 512; in omap_nand_attach_chip()
2155 /* 14th bit is kept reserved for ROM-code compatibility */ in omap_nand_attach_chip()
2156 chip->ecc.bytes = 13 + 1; in omap_nand_attach_chip()
2157 chip->ecc.strength = 8; in omap_nand_attach_chip()
2158 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2159 chip->ecc.correct = omap_elm_correct_data; in omap_nand_attach_chip()
2160 chip->ecc.read_page = omap_read_page_bch; in omap_nand_attach_chip()
2161 chip->ecc.write_page = omap_write_page_bch; in omap_nand_attach_chip()
2162 chip->ecc.write_subpage = omap_write_subpage_bch; in omap_nand_attach_chip()
2164 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
2169 pr_info("Using OMAP_ECC_BCH16_CODE_HW ECC scheme\n"); in omap_nand_attach_chip()
2170 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in omap_nand_attach_chip()
2171 chip->ecc.size = 512; in omap_nand_attach_chip()
2172 chip->ecc.bytes = 26; in omap_nand_attach_chip()
2173 chip->ecc.strength = 16; in omap_nand_attach_chip()
2174 chip->ecc.hwctl = omap_enable_hwecc_bch; in omap_nand_attach_chip()
2175 chip->ecc.correct = omap_elm_correct_data; in omap_nand_attach_chip()
2176 chip->ecc.read_page = omap_read_page_bch; in omap_nand_attach_chip()
2177 chip->ecc.write_page = omap_write_page_bch; in omap_nand_attach_chip()
2178 chip->ecc.write_subpage = omap_write_subpage_bch; in omap_nand_attach_chip()
2180 oobbytes_per_step = chip->ecc.bytes; in omap_nand_attach_chip()
2184 dev_err(dev, "Invalid or unsupported ECC scheme\n"); in omap_nand_attach_chip()
2185 return -EINVAL; in omap_nand_attach_chip()
2189 chip->ecc.steps = mtd->writesize / chip->ecc.size; in omap_nand_attach_chip()
2190 info->neccpg = chip->ecc.steps / ERROR_VECTOR_MAX; in omap_nand_attach_chip()
2191 if (info->neccpg) { in omap_nand_attach_chip()
2192 info->nsteps_per_eccpg = ERROR_VECTOR_MAX; in omap_nand_attach_chip()
2194 info->neccpg = 1; in omap_nand_attach_chip()
2195 info->nsteps_per_eccpg = chip->ecc.steps; in omap_nand_attach_chip()
2197 info->eccpg_size = info->nsteps_per_eccpg * chip->ecc.size; in omap_nand_attach_chip()
2198 info->eccpg_bytes = info->nsteps_per_eccpg * chip->ecc.bytes; in omap_nand_attach_chip()
2200 err = elm_config(info->elm_dev, elm_bch_strength, in omap_nand_attach_chip()
2201 info->nsteps_per_eccpg, chip->ecc.size, in omap_nand_attach_chip()
2202 chip->ecc.bytes); in omap_nand_attach_chip()
2207 /* Check if NAND device's OOB is enough to store ECC signatures */ in omap_nand_attach_chip()
2209 (mtd->writesize / chip->ecc.size)); in omap_nand_attach_chip()
2210 if (mtd->oobsize < min_oobbytes) { in omap_nand_attach_chip()
2213 min_oobbytes, mtd->oobsize); in omap_nand_attach_chip()
2214 return -EINVAL; in omap_nand_attach_chip()
2224 /* Shared among all NAND instances to synchronize access to the ECC Engine */
2235 struct device *dev = &pdev->dev; in omap_nand_probe()
2237 info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info), in omap_nand_probe()
2240 return -ENOMEM; in omap_nand_probe()
2242 info->pdev = pdev; in omap_nand_probe()
2248 info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs); in omap_nand_probe()
2249 if (!info->ops) { in omap_nand_probe()
2250 dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n"); in omap_nand_probe()
2251 return -ENODEV; in omap_nand_probe()
2254 nand_chip = &info->nand; in omap_nand_probe()
2256 mtd->dev.parent = &pdev->dev; in omap_nand_probe()
2257 nand_set_flash_node(nand_chip, dev->of_node); in omap_nand_probe()
2259 if (!mtd->name) { in omap_nand_probe()
2260 mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, in omap_nand_probe()
2261 "omap2-nand.%d", info->gpmc_cs); in omap_nand_probe()
2262 if (!mtd->name) { in omap_nand_probe()
2263 dev_err(&pdev->dev, "Failed to set MTD name\n"); in omap_nand_probe()
2264 return -ENOMEM; in omap_nand_probe()
2269 nand_chip->legacy.IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); in omap_nand_probe()
2270 if (IS_ERR(nand_chip->legacy.IO_ADDR_R)) in omap_nand_probe()
2271 return PTR_ERR(nand_chip->legacy.IO_ADDR_R); in omap_nand_probe()
2273 info->phys_base = res->start; in omap_nand_probe()
2281 nand_chip->controller = &omap_gpmc_controller; in omap_nand_probe()
2283 nand_chip->legacy.IO_ADDR_W = nand_chip->legacy.IO_ADDR_R; in omap_nand_probe()
2284 nand_chip->legacy.cmd_ctrl = omap_hwcontrol; in omap_nand_probe()
2286 info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "rb", in omap_nand_probe()
2288 if (IS_ERR(info->ready_gpiod)) { in omap_nand_probe()
2290 return PTR_ERR(info->ready_gpiod); in omap_nand_probe()
2297 * chip delay which is slightly more than tR (AC Timing) of the NAND in omap_nand_probe()
2300 if (info->ready_gpiod) { in omap_nand_probe()
2301 nand_chip->legacy.dev_ready = omap_dev_ready; in omap_nand_probe()
2302 nand_chip->legacy.chip_delay = 0; in omap_nand_probe()
2304 nand_chip->legacy.waitfunc = omap_wait; in omap_nand_probe()
2305 nand_chip->legacy.chip_delay = 50; in omap_nand_probe()
2308 if (info->flash_bbt) in omap_nand_probe()
2309 nand_chip->bbt_options |= NAND_BBT_USE_FLASH; in omap_nand_probe()
2311 /* scan NAND device connected to chip controller */ in omap_nand_probe()
2312 nand_chip->options |= info->devsize & NAND_BUSWIDTH_16; in omap_nand_probe()
2330 if (!IS_ERR_OR_NULL(info->dma)) in omap_nand_probe()
2331 dma_release_channel(info->dma); in omap_nand_probe()
2347 if (info->dma) in omap_nand_remove()
2348 dma_release_channel(info->dma); in omap_nand_remove()
2356 { .compatible = "ti,omap2-nand", },
2374 MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards");