Lines Matching +full:nand +full:- +full:ecc +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * davinci_nand.c - NAND Flash Driver for DaVinci family chips
8 * Sander Huijsen <Shuijsen@optelecom-nkf.com>
24 #include <linux/platform_data/mtd-davinci.h>
25 #include <linux/platform_data/mtd-davinci-aemif.h>
28 * This is a device driver for the NAND flash controller found on the
33 * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC
34 * available on chips like the DM355 and OMAP-L137 and needed with the
35 * more error-prone MLC NAND chips.
37 * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
38 * outputs in a "wire-AND" configuration, with no per-chip signals.
73 return __raw_readl(info->base + offset); in davinci_nand_readl()
79 __raw_writel(value, info->base + offset); in davinci_nand_writel()
82 /*----------------------------------------------------------------------*/
85 * 1-bit hardware ECC ... context maintained for each core chipselect
93 + 4 * info->core_chipsel); in nand_davinci_readecc_1bit()
96 static void nand_davinci_hwctl_1bit(struct nand_chip *chip, int mode) in nand_davinci_hwctl_1bit() argument
104 /* Reset ECC hardware */ in nand_davinci_hwctl_1bit()
109 /* Restart ECC hardware */ in nand_davinci_hwctl_1bit()
111 nandcfr |= BIT(8 + info->core_chipsel); in nand_davinci_hwctl_1bit()
118 * Read hardware ECC value and pack into three bytes
126 /* invert so that erased block ecc is correct */ in nand_davinci_calculate_1bit()
147 if ((diff >> (12 + 3)) < chip->ecc.size) { in nand_davinci_correct_1bit()
151 return -EBADMSG; in nand_davinci_correct_1bit()
153 } else if (!(diff & (diff - 1))) { in nand_davinci_correct_1bit()
154 /* Single bit ECC error in the ECC itself, in nand_davinci_correct_1bit()
159 return -EBADMSG; in nand_davinci_correct_1bit()
166 /*----------------------------------------------------------------------*/
169 * 4-bit hardware ECC ... context maintained over entire AEMIF
174 * Also, and specific to this hardware, it ECC-protects the "prepad"
175 * in the OOB ... while having ECC protection for parts of OOB would
177 * OOB without recomputing ECC.
180 static void nand_davinci_hwctl_4bit(struct nand_chip *chip, int mode) in nand_davinci_hwctl_4bit() argument
186 /* Reset ECC hardware */ in nand_davinci_hwctl_4bit()
191 /* Start 4-bit ECC calculation for read/write */ in nand_davinci_hwctl_4bit()
194 val |= (info->core_chipsel << 4) | BIT(12); in nand_davinci_hwctl_4bit()
197 info->is_readmode = (mode == NAND_ECC_READ); in nand_davinci_hwctl_4bit()
202 /* Read raw ECC code after writing to NAND. */
214 /* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
222 /* After a read, terminate ECC calculation by a dummy read in nand_davinci_calculate_4bit()
223 * of some 4-bit ECC register. ECC covers everything that in nand_davinci_calculate_4bit()
227 if (info->is_readmode) { in nand_davinci_calculate_4bit()
232 /* Pack eight raw 10-bit ecc values into ten bytes, making in nand_davinci_calculate_4bit()
234 * lower halves of two 32-bit words) into five bytes. The in nand_davinci_calculate_4bit()
265 * little-endian, and use type punning for less shifting/masking. in nand_davinci_correct_4bit()
268 return -EINVAL; in nand_davinci_correct_4bit()
280 /* Tell ECC controller about the expected ECC codes. */ in nand_davinci_correct_4bit()
281 for (i = 7; i >= 0; i--) in nand_davinci_correct_4bit()
311 * long as ECC_STATE reads less than 4. After that, ECC HW has entered in nand_davinci_correct_4bit()
330 return -EBADMSG; in nand_davinci_correct_4bit()
363 error_address = (512 + 7) - error_address; in nand_davinci_correct_4bit()
375 * nand_read_page_hwecc_oob_first - hw ecc, read oob first
376 * @chip: nand chip info structure
378 * @oob_required: caller requires OOB data read to chip->oob_poi
381 * Hardware ECC for large page chips, require OOB to be read first. For this
382 * ECC mode, the write_page method is re-used from ECC_HW. These methods
383 * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
384 * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
385 * the data area, by overwriting the NAND manufacturer bad block markings.
392 int i, eccsize = chip->ecc.size, ret; in nand_davinci_read_page_hwecc_oob_first()
393 int eccbytes = chip->ecc.bytes; in nand_davinci_read_page_hwecc_oob_first()
394 int eccsteps = chip->ecc.steps; in nand_davinci_read_page_hwecc_oob_first()
396 uint8_t *ecc_code = chip->ecc.code_buf; in nand_davinci_read_page_hwecc_oob_first()
397 uint8_t *ecc_calc = chip->ecc.calc_buf; in nand_davinci_read_page_hwecc_oob_first()
401 ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); in nand_davinci_read_page_hwecc_oob_first()
409 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, in nand_davinci_read_page_hwecc_oob_first()
410 chip->ecc.total); in nand_davinci_read_page_hwecc_oob_first()
414 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { in nand_davinci_read_page_hwecc_oob_first()
417 chip->ecc.hwctl(chip, NAND_ECC_READ); in nand_davinci_read_page_hwecc_oob_first()
423 chip->ecc.calculate(chip, p, &ecc_calc[i]); in nand_davinci_read_page_hwecc_oob_first()
425 stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); in nand_davinci_read_page_hwecc_oob_first()
426 if (stat == -EBADMSG && in nand_davinci_read_page_hwecc_oob_first()
427 (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { in nand_davinci_read_page_hwecc_oob_first()
432 chip->ecc.strength); in nand_davinci_read_page_hwecc_oob_first()
436 mtd->ecc_stats.failed++; in nand_davinci_read_page_hwecc_oob_first()
438 mtd->ecc_stats.corrected += stat; in nand_davinci_read_page_hwecc_oob_first()
445 /*----------------------------------------------------------------------*/
447 /* An ECC layout for using 4-bit ECC with small-page flash, storing
448 * ten ECC bytes plus the manufacturer's bad block marker byte, and
455 return -ERANGE; in hwecc4_ooblayout_small_ecc()
458 oobregion->offset = 0; in hwecc4_ooblayout_small_ecc()
459 oobregion->length = 5; in hwecc4_ooblayout_small_ecc()
461 oobregion->offset = 6; in hwecc4_ooblayout_small_ecc()
462 oobregion->length = 2; in hwecc4_ooblayout_small_ecc()
464 oobregion->offset = 13; in hwecc4_ooblayout_small_ecc()
465 oobregion->length = 3; in hwecc4_ooblayout_small_ecc()
475 return -ERANGE; in hwecc4_ooblayout_small_free()
478 oobregion->offset = 8; in hwecc4_ooblayout_small_free()
479 oobregion->length = 5; in hwecc4_ooblayout_small_free()
481 oobregion->offset = 16; in hwecc4_ooblayout_small_free()
482 oobregion->length = mtd->oobsize - 16; in hwecc4_ooblayout_small_free()
489 .ecc = hwecc4_ooblayout_small_ecc,
495 {.compatible = "ti,davinci-nand", },
496 {.compatible = "ti,keystone-nand", },
504 if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) { in nand_davinci_get_pdata()
506 const char *mode; in nand_davinci_get_pdata() local
509 pdata = devm_kzalloc(&pdev->dev, in nand_davinci_get_pdata()
512 pdev->dev.platform_data = pdata; in nand_davinci_get_pdata()
514 return ERR_PTR(-ENOMEM); in nand_davinci_get_pdata()
515 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
516 "ti,davinci-chipselect", &prop)) in nand_davinci_get_pdata()
517 pdata->core_chipsel = prop; in nand_davinci_get_pdata()
519 return ERR_PTR(-EINVAL); in nand_davinci_get_pdata()
521 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
522 "ti,davinci-mask-ale", &prop)) in nand_davinci_get_pdata()
523 pdata->mask_ale = prop; in nand_davinci_get_pdata()
524 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
525 "ti,davinci-mask-cle", &prop)) in nand_davinci_get_pdata()
526 pdata->mask_cle = prop; in nand_davinci_get_pdata()
527 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
528 "ti,davinci-mask-chipsel", &prop)) in nand_davinci_get_pdata()
529 pdata->mask_chipsel = prop; in nand_davinci_get_pdata()
530 if (!of_property_read_string(pdev->dev.of_node, in nand_davinci_get_pdata()
531 "ti,davinci-ecc-mode", &mode)) { in nand_davinci_get_pdata()
532 if (!strncmp("none", mode, 4)) in nand_davinci_get_pdata()
533 pdata->engine_type = NAND_ECC_ENGINE_TYPE_NONE; in nand_davinci_get_pdata()
534 if (!strncmp("soft", mode, 4)) in nand_davinci_get_pdata()
535 pdata->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_davinci_get_pdata()
536 if (!strncmp("hw", mode, 2)) in nand_davinci_get_pdata()
537 pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in nand_davinci_get_pdata()
539 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
540 "ti,davinci-ecc-bits", &prop)) in nand_davinci_get_pdata()
541 pdata->ecc_bits = prop; in nand_davinci_get_pdata()
543 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
544 "ti,davinci-nand-buswidth", &prop) && prop == 16) in nand_davinci_get_pdata()
545 pdata->options |= NAND_BUSWIDTH_16; in nand_davinci_get_pdata()
547 if (of_property_read_bool(pdev->dev.of_node, in nand_davinci_get_pdata()
548 "ti,davinci-nand-use-bbt")) in nand_davinci_get_pdata()
549 pdata->bbt_options = NAND_BBT_USE_FLASH; in nand_davinci_get_pdata()
553 * use of 4-bit hardware ECC with subpages and verified on in nand_davinci_get_pdata()
556 * existing UBI partitions, sub-page writes are not being in nand_davinci_get_pdata()
559 * then use "ti,davinci-nand" as the compatible in your in nand_davinci_get_pdata()
560 * device-tree file. in nand_davinci_get_pdata()
562 if (of_device_is_compatible(pdev->dev.of_node, in nand_davinci_get_pdata()
563 "ti,keystone-nand")) { in nand_davinci_get_pdata()
564 pdata->options |= NAND_NO_SUBPAGE_WRITE; in nand_davinci_get_pdata()
568 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
574 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
582 struct davinci_nand_pdata *pdata = nand_davinci_get_pdata(info->pdev); in davinci_nand_attach_chip()
588 /* Use board-specific ECC config */ in davinci_nand_attach_chip()
589 info->chip.ecc.engine_type = pdata->engine_type; in davinci_nand_attach_chip()
590 info->chip.ecc.placement = pdata->ecc_placement; in davinci_nand_attach_chip()
592 switch (info->chip.ecc.engine_type) { in davinci_nand_attach_chip()
594 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
597 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
599 * This driver expects Hamming based ECC when engine_type is set in davinci_nand_attach_chip()
600 * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to in davinci_nand_attach_chip()
601 * NAND_ECC_ALGO_HAMMING to avoid adding an extra ->ecc_algo in davinci_nand_attach_chip()
604 info->chip.ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
607 if (pdata->ecc_bits == 4) { in davinci_nand_attach_chip()
608 int chunks = mtd->writesize / 512; in davinci_nand_attach_chip()
610 if (!chunks || mtd->oobsize < 16) { in davinci_nand_attach_chip()
611 dev_dbg(&info->pdev->dev, "too small\n"); in davinci_nand_attach_chip()
612 return -EINVAL; in davinci_nand_attach_chip()
620 /* No sharing 4-bit hardware between chipselects yet */ in davinci_nand_attach_chip()
623 ret = -EBUSY; in davinci_nand_attach_chip()
628 if (ret == -EBUSY) in davinci_nand_attach_chip()
631 info->chip.ecc.calculate = nand_davinci_calculate_4bit; in davinci_nand_attach_chip()
632 info->chip.ecc.correct = nand_davinci_correct_4bit; in davinci_nand_attach_chip()
633 info->chip.ecc.hwctl = nand_davinci_hwctl_4bit; in davinci_nand_attach_chip()
634 info->chip.ecc.bytes = 10; in davinci_nand_attach_chip()
635 info->chip.ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; in davinci_nand_attach_chip()
636 info->chip.ecc.algo = NAND_ECC_ALGO_BCH; in davinci_nand_attach_chip()
639 * Update ECC layout if needed ... for 1-bit HW ECC, the in davinci_nand_attach_chip()
641 * are needed (for each 512 bytes). For 4-bit HW ECC, in davinci_nand_attach_chip()
654 info->chip.ecc.read_page = nand_davinci_read_page_hwecc_oob_first; in davinci_nand_attach_chip()
656 return -EIO; in davinci_nand_attach_chip()
659 /* 1bit ecc hamming */ in davinci_nand_attach_chip()
660 info->chip.ecc.calculate = nand_davinci_calculate_1bit; in davinci_nand_attach_chip()
661 info->chip.ecc.correct = nand_davinci_correct_1bit; in davinci_nand_attach_chip()
662 info->chip.ecc.hwctl = nand_davinci_hwctl_1bit; in davinci_nand_attach_chip()
663 info->chip.ecc.bytes = 3; in davinci_nand_attach_chip()
664 info->chip.ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
666 info->chip.ecc.size = 512; in davinci_nand_attach_chip()
667 info->chip.ecc.strength = pdata->ecc_bits; in davinci_nand_attach_chip()
670 return -EINVAL; in davinci_nand_attach_chip()
682 ioread8_rep(info->current_cs, buf, len); in nand_davinci_data_in()
684 ioread16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_in()
686 ioread32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_in()
696 iowrite8_rep(info->current_cs, buf, len); in nand_davinci_data_out()
698 iowrite16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_out()
700 iowrite32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_out()
710 switch (instr->type) { in davinci_nand_exec_instr()
712 iowrite8(instr->ctx.cmd.opcode, in davinci_nand_exec_instr()
713 info->current_cs + info->mask_cle); in davinci_nand_exec_instr()
717 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in davinci_nand_exec_instr()
718 iowrite8(instr->ctx.addr.addrs[i], in davinci_nand_exec_instr()
719 info->current_cs + info->mask_ale); in davinci_nand_exec_instr()
724 nand_davinci_data_in(info, instr->ctx.data.buf.in, in davinci_nand_exec_instr()
725 instr->ctx.data.len, in davinci_nand_exec_instr()
726 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
730 nand_davinci_data_out(info, instr->ctx.data.buf.out, in davinci_nand_exec_instr()
731 instr->ctx.data.len, in davinci_nand_exec_instr()
732 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
736 timeout_us = instr->ctx.waitrdy.timeout_ms * 1000; in davinci_nand_exec_instr()
737 ret = readl_relaxed_poll_timeout(info->base + NANDFSR_OFFSET, in davinci_nand_exec_instr()
746 if (instr->delay_ns) in davinci_nand_exec_instr()
747 ndelay(instr->delay_ns); in davinci_nand_exec_instr()
762 info->current_cs = info->vaddr + (op->cs * info->mask_chipsel); in davinci_nand_exec_op()
764 for (i = 0; i < op->ninstrs; i++) { in davinci_nand_exec_op()
767 ret = davinci_nand_exec_instr(info, &op->instrs[i]); in davinci_nand_exec_op()
796 /* insist on board-specific configuration */ in nand_davinci_probe()
798 return -ENODEV; in nand_davinci_probe()
801 if (pdata->core_chipsel < 0 || pdata->core_chipsel > 3) in nand_davinci_probe()
802 return -ENODEV; in nand_davinci_probe()
804 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in nand_davinci_probe()
806 return -ENOMEM; in nand_davinci_probe()
813 dev_err(&pdev->dev, "resource missing\n"); in nand_davinci_probe()
814 return -EINVAL; in nand_davinci_probe()
817 vaddr = devm_ioremap_resource(&pdev->dev, res1); in nand_davinci_probe()
822 * This registers range is used to setup NAND settings. In case with in nand_davinci_probe()
825 * The AEMIF and NAND drivers not use the same registers in this range. in nand_davinci_probe()
827 base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); in nand_davinci_probe()
829 dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); in nand_davinci_probe()
830 return -EADDRNOTAVAIL; in nand_davinci_probe()
833 info->pdev = pdev; in nand_davinci_probe()
834 info->base = base; in nand_davinci_probe()
835 info->vaddr = vaddr; in nand_davinci_probe()
837 mtd = nand_to_mtd(&info->chip); in nand_davinci_probe()
838 mtd->dev.parent = &pdev->dev; in nand_davinci_probe()
839 nand_set_flash_node(&info->chip, pdev->dev.of_node); in nand_davinci_probe()
842 info->chip.bbt_options = pdata->bbt_options; in nand_davinci_probe()
843 /* options such as 16-bit widths */ in nand_davinci_probe()
844 info->chip.options = pdata->options; in nand_davinci_probe()
845 info->chip.bbt_td = pdata->bbt_td; in nand_davinci_probe()
846 info->chip.bbt_md = pdata->bbt_md; in nand_davinci_probe()
847 info->timing = pdata->timing; in nand_davinci_probe()
849 info->current_cs = info->vaddr; in nand_davinci_probe()
850 info->core_chipsel = pdata->core_chipsel; in nand_davinci_probe()
851 info->mask_chipsel = pdata->mask_chipsel; in nand_davinci_probe()
853 /* use nandboot-capable ALE/CLE masks by default */ in nand_davinci_probe()
854 info->mask_ale = pdata->mask_ale ? : MASK_ALE; in nand_davinci_probe()
855 info->mask_cle = pdata->mask_cle ? : MASK_CLE; in nand_davinci_probe()
859 /* put CSxNAND into NAND mode */ in nand_davinci_probe()
861 val |= BIT(info->core_chipsel); in nand_davinci_probe()
867 nand_controller_init(&info->controller); in nand_davinci_probe()
868 info->controller.ops = &davinci_nand_controller_ops; in nand_davinci_probe()
869 info->chip.controller = &info->controller; in nand_davinci_probe()
870 ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1); in nand_davinci_probe()
872 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); in nand_davinci_probe()
876 if (pdata->parts) in nand_davinci_probe()
877 ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); in nand_davinci_probe()
884 dev_info(&pdev->dev, "controller rev. %d.%d\n", in nand_davinci_probe()
890 nand_cleanup(&info->chip); in nand_davinci_probe()
898 struct nand_chip *chip = &info->chip; in nand_davinci_remove()
902 if (info->chip.ecc.placement == NAND_ECC_PLACEMENT_INTERLEAVED) in nand_davinci_remove()
927 MODULE_DESCRIPTION("Davinci NAND flash driver");