Lines Matching +full:nand +full:- +full:ecc +full:- +full:algo
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()
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.
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()
374 /*----------------------------------------------------------------------*/
376 /* An ECC layout for using 4-bit ECC with small-page flash, storing
377 * ten ECC bytes plus the manufacturer's bad block marker byte, and
384 return -ERANGE; in hwecc4_ooblayout_small_ecc()
387 oobregion->offset = 0; in hwecc4_ooblayout_small_ecc()
388 oobregion->length = 5; in hwecc4_ooblayout_small_ecc()
390 oobregion->offset = 6; in hwecc4_ooblayout_small_ecc()
391 oobregion->length = 2; in hwecc4_ooblayout_small_ecc()
393 oobregion->offset = 13; in hwecc4_ooblayout_small_ecc()
394 oobregion->length = 3; in hwecc4_ooblayout_small_ecc()
404 return -ERANGE; in hwecc4_ooblayout_small_free()
407 oobregion->offset = 8; in hwecc4_ooblayout_small_free()
408 oobregion->length = 5; in hwecc4_ooblayout_small_free()
410 oobregion->offset = 16; in hwecc4_ooblayout_small_free()
411 oobregion->length = mtd->oobsize - 16; in hwecc4_ooblayout_small_free()
418 .ecc = hwecc4_ooblayout_small_ecc,
424 {.compatible = "ti,davinci-nand", },
425 {.compatible = "ti,keystone-nand", },
433 if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) { in nand_davinci_get_pdata()
438 pdata = devm_kzalloc(&pdev->dev, in nand_davinci_get_pdata()
441 pdev->dev.platform_data = pdata; in nand_davinci_get_pdata()
443 return ERR_PTR(-ENOMEM); in nand_davinci_get_pdata()
444 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
445 "ti,davinci-chipselect", &prop)) in nand_davinci_get_pdata()
446 pdata->core_chipsel = prop; in nand_davinci_get_pdata()
448 return ERR_PTR(-EINVAL); in nand_davinci_get_pdata()
450 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
451 "ti,davinci-mask-ale", &prop)) in nand_davinci_get_pdata()
452 pdata->mask_ale = prop; in nand_davinci_get_pdata()
453 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
454 "ti,davinci-mask-cle", &prop)) in nand_davinci_get_pdata()
455 pdata->mask_cle = prop; in nand_davinci_get_pdata()
456 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
457 "ti,davinci-mask-chipsel", &prop)) in nand_davinci_get_pdata()
458 pdata->mask_chipsel = prop; in nand_davinci_get_pdata()
459 if (!of_property_read_string(pdev->dev.of_node, in nand_davinci_get_pdata()
460 "ti,davinci-ecc-mode", &mode)) { in nand_davinci_get_pdata()
462 pdata->engine_type = NAND_ECC_ENGINE_TYPE_NONE; in nand_davinci_get_pdata()
464 pdata->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_davinci_get_pdata()
466 pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in nand_davinci_get_pdata()
468 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
469 "ti,davinci-ecc-bits", &prop)) in nand_davinci_get_pdata()
470 pdata->ecc_bits = prop; in nand_davinci_get_pdata()
472 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
473 "ti,davinci-nand-buswidth", &prop) && prop == 16) in nand_davinci_get_pdata()
474 pdata->options |= NAND_BUSWIDTH_16; in nand_davinci_get_pdata()
476 if (of_property_read_bool(pdev->dev.of_node, in nand_davinci_get_pdata()
477 "ti,davinci-nand-use-bbt")) in nand_davinci_get_pdata()
478 pdata->bbt_options = NAND_BBT_USE_FLASH; in nand_davinci_get_pdata()
482 * use of 4-bit hardware ECC with subpages and verified on in nand_davinci_get_pdata()
485 * existing UBI partitions, sub-page writes are not being in nand_davinci_get_pdata()
488 * then use "ti,davinci-nand" as the compatible in your in nand_davinci_get_pdata()
489 * device-tree file. in nand_davinci_get_pdata()
491 if (of_device_is_compatible(pdev->dev.of_node, in nand_davinci_get_pdata()
492 "ti,keystone-nand")) { in nand_davinci_get_pdata()
493 pdata->options |= NAND_NO_SUBPAGE_WRITE; in nand_davinci_get_pdata()
497 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
503 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
511 struct davinci_nand_pdata *pdata = nand_davinci_get_pdata(info->pdev); in davinci_nand_attach_chip()
517 /* Use board-specific ECC config */ in davinci_nand_attach_chip()
518 chip->ecc.engine_type = pdata->engine_type; in davinci_nand_attach_chip()
519 chip->ecc.placement = pdata->ecc_placement; in davinci_nand_attach_chip()
521 switch (chip->ecc.engine_type) { in davinci_nand_attach_chip()
523 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
526 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
528 * This driver expects Hamming based ECC when engine_type is set in davinci_nand_attach_chip()
529 * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to in davinci_nand_attach_chip()
530 * NAND_ECC_ALGO_HAMMING to avoid adding an extra ->ecc_algo in davinci_nand_attach_chip()
533 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
536 if (pdata->ecc_bits == 4) { in davinci_nand_attach_chip()
537 int chunks = mtd->writesize / 512; in davinci_nand_attach_chip()
539 if (!chunks || mtd->oobsize < 16) { in davinci_nand_attach_chip()
540 dev_dbg(&info->pdev->dev, "too small\n"); in davinci_nand_attach_chip()
541 return -EINVAL; in davinci_nand_attach_chip()
549 /* No sharing 4-bit hardware between chipselects yet */ in davinci_nand_attach_chip()
552 ret = -EBUSY; in davinci_nand_attach_chip()
557 if (ret == -EBUSY) in davinci_nand_attach_chip()
560 chip->ecc.calculate = nand_davinci_calculate_4bit; in davinci_nand_attach_chip()
561 chip->ecc.correct = nand_davinci_correct_4bit; in davinci_nand_attach_chip()
562 chip->ecc.hwctl = nand_davinci_hwctl_4bit; in davinci_nand_attach_chip()
563 chip->ecc.bytes = 10; in davinci_nand_attach_chip()
564 chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; in davinci_nand_attach_chip()
565 chip->ecc.algo = NAND_ECC_ALGO_BCH; in davinci_nand_attach_chip()
568 * Update ECC layout if needed ... for 1-bit HW ECC, the in davinci_nand_attach_chip()
570 * are needed (for each 512 bytes). For 4-bit HW ECC, in davinci_nand_attach_chip()
583 chip->ecc.read_page = nand_read_page_hwecc_oob_first; in davinci_nand_attach_chip()
585 return -EIO; in davinci_nand_attach_chip()
588 /* 1bit ecc hamming */ in davinci_nand_attach_chip()
589 chip->ecc.calculate = nand_davinci_calculate_1bit; in davinci_nand_attach_chip()
590 chip->ecc.correct = nand_davinci_correct_1bit; in davinci_nand_attach_chip()
591 chip->ecc.hwctl = nand_davinci_hwctl_1bit; in davinci_nand_attach_chip()
592 chip->ecc.bytes = 3; in davinci_nand_attach_chip()
593 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
595 chip->ecc.size = 512; in davinci_nand_attach_chip()
596 chip->ecc.strength = pdata->ecc_bits; in davinci_nand_attach_chip()
599 return -EINVAL; in davinci_nand_attach_chip()
611 ioread8_rep(info->current_cs, buf, len); in nand_davinci_data_in()
613 ioread16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_in()
615 ioread32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_in()
625 iowrite8_rep(info->current_cs, buf, len); in nand_davinci_data_out()
627 iowrite16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_out()
629 iowrite32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_out()
639 switch (instr->type) { in davinci_nand_exec_instr()
641 iowrite8(instr->ctx.cmd.opcode, in davinci_nand_exec_instr()
642 info->current_cs + info->mask_cle); in davinci_nand_exec_instr()
646 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in davinci_nand_exec_instr()
647 iowrite8(instr->ctx.addr.addrs[i], in davinci_nand_exec_instr()
648 info->current_cs + info->mask_ale); in davinci_nand_exec_instr()
653 nand_davinci_data_in(info, instr->ctx.data.buf.in, in davinci_nand_exec_instr()
654 instr->ctx.data.len, in davinci_nand_exec_instr()
655 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
659 nand_davinci_data_out(info, instr->ctx.data.buf.out, in davinci_nand_exec_instr()
660 instr->ctx.data.len, in davinci_nand_exec_instr()
661 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
665 timeout_us = instr->ctx.waitrdy.timeout_ms * 1000; in davinci_nand_exec_instr()
666 ret = readl_relaxed_poll_timeout(info->base + NANDFSR_OFFSET, in davinci_nand_exec_instr()
675 if (instr->delay_ns) in davinci_nand_exec_instr()
676 ndelay(instr->delay_ns); in davinci_nand_exec_instr()
691 info->current_cs = info->vaddr + (op->cs * info->mask_chipsel); in davinci_nand_exec_op()
693 for (i = 0; i < op->ninstrs; i++) { in davinci_nand_exec_op()
696 ret = davinci_nand_exec_instr(info, &op->instrs[i]); in davinci_nand_exec_op()
725 /* insist on board-specific configuration */ in nand_davinci_probe()
727 return -ENODEV; in nand_davinci_probe()
730 if (pdata->core_chipsel > 3) in nand_davinci_probe()
731 return -ENODEV; in nand_davinci_probe()
733 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in nand_davinci_probe()
735 return -ENOMEM; in nand_davinci_probe()
742 dev_err(&pdev->dev, "resource missing\n"); in nand_davinci_probe()
743 return -EINVAL; in nand_davinci_probe()
746 vaddr = devm_ioremap_resource(&pdev->dev, res1); in nand_davinci_probe()
751 * This registers range is used to setup NAND settings. In case with in nand_davinci_probe()
754 * The AEMIF and NAND drivers not use the same registers in this range. in nand_davinci_probe()
756 base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); in nand_davinci_probe()
758 dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); in nand_davinci_probe()
759 return -EADDRNOTAVAIL; in nand_davinci_probe()
762 info->pdev = pdev; in nand_davinci_probe()
763 info->base = base; in nand_davinci_probe()
764 info->vaddr = vaddr; in nand_davinci_probe()
766 mtd = nand_to_mtd(&info->chip); in nand_davinci_probe()
767 mtd->dev.parent = &pdev->dev; in nand_davinci_probe()
768 nand_set_flash_node(&info->chip, pdev->dev.of_node); in nand_davinci_probe()
771 info->chip.bbt_options = pdata->bbt_options; in nand_davinci_probe()
772 /* options such as 16-bit widths */ in nand_davinci_probe()
773 info->chip.options = pdata->options; in nand_davinci_probe()
774 info->chip.bbt_td = pdata->bbt_td; in nand_davinci_probe()
775 info->chip.bbt_md = pdata->bbt_md; in nand_davinci_probe()
776 info->timing = pdata->timing; in nand_davinci_probe()
778 info->current_cs = info->vaddr; in nand_davinci_probe()
779 info->core_chipsel = pdata->core_chipsel; in nand_davinci_probe()
780 info->mask_chipsel = pdata->mask_chipsel; in nand_davinci_probe()
782 /* use nandboot-capable ALE/CLE masks by default */ in nand_davinci_probe()
783 info->mask_ale = pdata->mask_ale ? : MASK_ALE; in nand_davinci_probe()
784 info->mask_cle = pdata->mask_cle ? : MASK_CLE; in nand_davinci_probe()
788 /* put CSxNAND into NAND mode */ in nand_davinci_probe()
790 val |= BIT(info->core_chipsel); in nand_davinci_probe()
796 nand_controller_init(&info->controller); in nand_davinci_probe()
797 info->controller.ops = &davinci_nand_controller_ops; in nand_davinci_probe()
798 info->chip.controller = &info->controller; in nand_davinci_probe()
799 ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1); in nand_davinci_probe()
801 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); in nand_davinci_probe()
805 if (pdata->parts) in nand_davinci_probe()
806 ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); in nand_davinci_probe()
813 dev_info(&pdev->dev, "controller rev. %d.%d\n", in nand_davinci_probe()
819 nand_cleanup(&info->chip); in nand_davinci_probe()
827 struct nand_chip *chip = &info->chip; in nand_davinci_remove()
831 if (chip->ecc.placement == NAND_ECC_PLACEMENT_INTERLEAVED) in nand_davinci_remove()
856 MODULE_DESCRIPTION("Davinci NAND flash driver");