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>
23 #include <linux/platform_data/mtd-davinci.h>
24 #include <linux/platform_data/mtd-davinci-aemif.h>
27 * This is a device driver for the NAND flash controller found on the
32 * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC
33 * available on chips like the DM355 and OMAP-L137 and needed with the
34 * more error-prone MLC NAND chips.
36 * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
37 * outputs in a "wire-AND" configuration, with no per-chip signals.
72 return __raw_readl(info->base + offset); in davinci_nand_readl()
78 __raw_writel(value, info->base + offset); in davinci_nand_writel()
81 /*----------------------------------------------------------------------*/
84 * 1-bit hardware ECC ... context maintained for each core chipselect
92 + 4 * info->core_chipsel); in nand_davinci_readecc_1bit()
103 /* Reset ECC hardware */ in nand_davinci_hwctl_1bit()
108 /* Restart ECC hardware */ in nand_davinci_hwctl_1bit()
110 nandcfr |= BIT(8 + info->core_chipsel); in nand_davinci_hwctl_1bit()
117 * Read hardware ECC value and pack into three bytes
125 /* invert so that erased block ecc is correct */ in nand_davinci_calculate_1bit()
146 if ((diff >> (12 + 3)) < chip->ecc.size) { in nand_davinci_correct_1bit()
150 return -EBADMSG; in nand_davinci_correct_1bit()
152 } else if (!(diff & (diff - 1))) { in nand_davinci_correct_1bit()
153 /* Single bit ECC error in the ECC itself, in nand_davinci_correct_1bit()
158 return -EBADMSG; in nand_davinci_correct_1bit()
165 /*----------------------------------------------------------------------*/
168 * 4-bit hardware ECC ... context maintained over entire AEMIF
173 * Also, and specific to this hardware, it ECC-protects the "prepad"
174 * in the OOB ... while having ECC protection for parts of OOB would
176 * OOB without recomputing ECC.
185 /* Reset ECC hardware */ in nand_davinci_hwctl_4bit()
190 /* Start 4-bit ECC calculation for read/write */ in nand_davinci_hwctl_4bit()
193 val |= (info->core_chipsel << 4) | BIT(12); in nand_davinci_hwctl_4bit()
196 info->is_readmode = (mode == NAND_ECC_READ); in nand_davinci_hwctl_4bit()
201 /* Read raw ECC code after writing to NAND. */
213 /* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
221 /* After a read, terminate ECC calculation by a dummy read in nand_davinci_calculate_4bit()
222 * of some 4-bit ECC register. ECC covers everything that in nand_davinci_calculate_4bit()
226 if (info->is_readmode) { in nand_davinci_calculate_4bit()
231 /* Pack eight raw 10-bit ecc values into ten bytes, making in nand_davinci_calculate_4bit()
233 * lower halves of two 32-bit words) into five bytes. The in nand_davinci_calculate_4bit()
264 * little-endian, and use type punning for less shifting/masking. in nand_davinci_correct_4bit()
267 return -EINVAL; in nand_davinci_correct_4bit()
279 /* Tell ECC controller about the expected ECC codes. */ in nand_davinci_correct_4bit()
280 for (i = 7; i >= 0; i--) in nand_davinci_correct_4bit()
310 * long as ECC_STATE reads less than 4. After that, ECC HW has entered in nand_davinci_correct_4bit()
329 return -EBADMSG; in nand_davinci_correct_4bit()
362 error_address = (512 + 7) - error_address; in nand_davinci_correct_4bit()
373 /*----------------------------------------------------------------------*/
375 /* An ECC layout for using 4-bit ECC with small-page flash, storing
376 * ten ECC bytes plus the manufacturer's bad block marker byte, and
383 return -ERANGE; in hwecc4_ooblayout_small_ecc()
386 oobregion->offset = 0; in hwecc4_ooblayout_small_ecc()
387 oobregion->length = 5; in hwecc4_ooblayout_small_ecc()
389 oobregion->offset = 6; in hwecc4_ooblayout_small_ecc()
390 oobregion->length = 2; in hwecc4_ooblayout_small_ecc()
392 oobregion->offset = 13; in hwecc4_ooblayout_small_ecc()
393 oobregion->length = 3; in hwecc4_ooblayout_small_ecc()
403 return -ERANGE; in hwecc4_ooblayout_small_free()
406 oobregion->offset = 8; in hwecc4_ooblayout_small_free()
407 oobregion->length = 5; in hwecc4_ooblayout_small_free()
409 oobregion->offset = 16; in hwecc4_ooblayout_small_free()
410 oobregion->length = mtd->oobsize - 16; in hwecc4_ooblayout_small_free()
417 .ecc = hwecc4_ooblayout_small_ecc,
423 {.compatible = "ti,davinci-nand", },
424 {.compatible = "ti,keystone-nand", },
432 if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) { in nand_davinci_get_pdata()
437 pdata = devm_kzalloc(&pdev->dev, in nand_davinci_get_pdata()
440 pdev->dev.platform_data = pdata; in nand_davinci_get_pdata()
442 return ERR_PTR(-ENOMEM); in nand_davinci_get_pdata()
443 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
444 "ti,davinci-chipselect", &prop)) in nand_davinci_get_pdata()
445 pdata->core_chipsel = prop; in nand_davinci_get_pdata()
447 return ERR_PTR(-EINVAL); in nand_davinci_get_pdata()
449 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
450 "ti,davinci-mask-ale", &prop)) in nand_davinci_get_pdata()
451 pdata->mask_ale = prop; in nand_davinci_get_pdata()
452 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
453 "ti,davinci-mask-cle", &prop)) in nand_davinci_get_pdata()
454 pdata->mask_cle = prop; in nand_davinci_get_pdata()
455 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
456 "ti,davinci-mask-chipsel", &prop)) in nand_davinci_get_pdata()
457 pdata->mask_chipsel = prop; in nand_davinci_get_pdata()
458 if (!of_property_read_string(pdev->dev.of_node, in nand_davinci_get_pdata()
459 "ti,davinci-ecc-mode", &mode)) { in nand_davinci_get_pdata()
461 pdata->engine_type = NAND_ECC_ENGINE_TYPE_NONE; in nand_davinci_get_pdata()
463 pdata->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_davinci_get_pdata()
465 pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in nand_davinci_get_pdata()
467 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
468 "ti,davinci-ecc-bits", &prop)) in nand_davinci_get_pdata()
469 pdata->ecc_bits = prop; in nand_davinci_get_pdata()
471 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
472 "ti,davinci-nand-buswidth", &prop) && prop == 16) in nand_davinci_get_pdata()
473 pdata->options |= NAND_BUSWIDTH_16; in nand_davinci_get_pdata()
475 if (of_property_read_bool(pdev->dev.of_node, in nand_davinci_get_pdata()
476 "ti,davinci-nand-use-bbt")) in nand_davinci_get_pdata()
477 pdata->bbt_options = NAND_BBT_USE_FLASH; in nand_davinci_get_pdata()
481 * use of 4-bit hardware ECC with subpages and verified on in nand_davinci_get_pdata()
484 * existing UBI partitions, sub-page writes are not being in nand_davinci_get_pdata()
487 * then use "ti,davinci-nand" as the compatible in your in nand_davinci_get_pdata()
488 * device-tree file. in nand_davinci_get_pdata()
490 if (of_device_is_compatible(pdev->dev.of_node, in nand_davinci_get_pdata()
491 "ti,keystone-nand")) { in nand_davinci_get_pdata()
492 pdata->options |= NAND_NO_SUBPAGE_WRITE; in nand_davinci_get_pdata()
496 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
502 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
510 struct davinci_nand_pdata *pdata = nand_davinci_get_pdata(info->pdev); in davinci_nand_attach_chip()
516 /* Use board-specific ECC config */ in davinci_nand_attach_chip()
517 chip->ecc.engine_type = pdata->engine_type; in davinci_nand_attach_chip()
518 chip->ecc.placement = pdata->ecc_placement; in davinci_nand_attach_chip()
520 switch (chip->ecc.engine_type) { in davinci_nand_attach_chip()
522 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
525 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
527 * This driver expects Hamming based ECC when engine_type is set in davinci_nand_attach_chip()
528 * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to in davinci_nand_attach_chip()
529 * NAND_ECC_ALGO_HAMMING to avoid adding an extra ->ecc_algo in davinci_nand_attach_chip()
532 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
535 if (pdata->ecc_bits == 4) { in davinci_nand_attach_chip()
536 int chunks = mtd->writesize / 512; in davinci_nand_attach_chip()
538 if (!chunks || mtd->oobsize < 16) { in davinci_nand_attach_chip()
539 dev_dbg(&info->pdev->dev, "too small\n"); in davinci_nand_attach_chip()
540 return -EINVAL; in davinci_nand_attach_chip()
548 /* No sharing 4-bit hardware between chipselects yet */ in davinci_nand_attach_chip()
551 ret = -EBUSY; in davinci_nand_attach_chip()
556 if (ret == -EBUSY) in davinci_nand_attach_chip()
559 chip->ecc.calculate = nand_davinci_calculate_4bit; in davinci_nand_attach_chip()
560 chip->ecc.correct = nand_davinci_correct_4bit; in davinci_nand_attach_chip()
561 chip->ecc.hwctl = nand_davinci_hwctl_4bit; in davinci_nand_attach_chip()
562 chip->ecc.bytes = 10; in davinci_nand_attach_chip()
563 chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; in davinci_nand_attach_chip()
564 chip->ecc.algo = NAND_ECC_ALGO_BCH; in davinci_nand_attach_chip()
567 * Update ECC layout if needed ... for 1-bit HW ECC, the in davinci_nand_attach_chip()
569 * are needed (for each 512 bytes). For 4-bit HW ECC, in davinci_nand_attach_chip()
582 chip->ecc.read_page = nand_read_page_hwecc_oob_first; in davinci_nand_attach_chip()
584 return -EIO; in davinci_nand_attach_chip()
587 /* 1bit ecc hamming */ in davinci_nand_attach_chip()
588 chip->ecc.calculate = nand_davinci_calculate_1bit; in davinci_nand_attach_chip()
589 chip->ecc.correct = nand_davinci_correct_1bit; in davinci_nand_attach_chip()
590 chip->ecc.hwctl = nand_davinci_hwctl_1bit; in davinci_nand_attach_chip()
591 chip->ecc.bytes = 3; in davinci_nand_attach_chip()
592 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
594 chip->ecc.size = 512; in davinci_nand_attach_chip()
595 chip->ecc.strength = pdata->ecc_bits; in davinci_nand_attach_chip()
598 return -EINVAL; in davinci_nand_attach_chip()
610 ioread8_rep(info->current_cs, buf, len); in nand_davinci_data_in()
612 ioread16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_in()
614 ioread32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_in()
624 iowrite8_rep(info->current_cs, buf, len); in nand_davinci_data_out()
626 iowrite16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_out()
628 iowrite32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_out()
638 switch (instr->type) { in davinci_nand_exec_instr()
640 iowrite8(instr->ctx.cmd.opcode, in davinci_nand_exec_instr()
641 info->current_cs + info->mask_cle); in davinci_nand_exec_instr()
645 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in davinci_nand_exec_instr()
646 iowrite8(instr->ctx.addr.addrs[i], in davinci_nand_exec_instr()
647 info->current_cs + info->mask_ale); in davinci_nand_exec_instr()
652 nand_davinci_data_in(info, instr->ctx.data.buf.in, in davinci_nand_exec_instr()
653 instr->ctx.data.len, in davinci_nand_exec_instr()
654 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
658 nand_davinci_data_out(info, instr->ctx.data.buf.out, in davinci_nand_exec_instr()
659 instr->ctx.data.len, in davinci_nand_exec_instr()
660 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
664 timeout_us = instr->ctx.waitrdy.timeout_ms * 1000; in davinci_nand_exec_instr()
665 ret = readl_relaxed_poll_timeout(info->base + NANDFSR_OFFSET, in davinci_nand_exec_instr()
674 if (instr->delay_ns) in davinci_nand_exec_instr()
675 ndelay(instr->delay_ns); in davinci_nand_exec_instr()
690 info->current_cs = info->vaddr + (op->cs * info->mask_chipsel); in davinci_nand_exec_op()
692 for (i = 0; i < op->ninstrs; i++) { in davinci_nand_exec_op()
695 ret = davinci_nand_exec_instr(info, &op->instrs[i]); in davinci_nand_exec_op()
724 /* insist on board-specific configuration */ in nand_davinci_probe()
726 return -ENODEV; in nand_davinci_probe()
729 if (pdata->core_chipsel > 3) in nand_davinci_probe()
730 return -ENODEV; in nand_davinci_probe()
732 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in nand_davinci_probe()
734 return -ENOMEM; in nand_davinci_probe()
741 dev_err(&pdev->dev, "resource missing\n"); in nand_davinci_probe()
742 return -EINVAL; in nand_davinci_probe()
745 vaddr = devm_ioremap_resource(&pdev->dev, res1); in nand_davinci_probe()
750 * This registers range is used to setup NAND settings. In case with in nand_davinci_probe()
753 * The AEMIF and NAND drivers not use the same registers in this range. in nand_davinci_probe()
755 base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); in nand_davinci_probe()
757 dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); in nand_davinci_probe()
758 return -EADDRNOTAVAIL; in nand_davinci_probe()
761 info->pdev = pdev; in nand_davinci_probe()
762 info->base = base; in nand_davinci_probe()
763 info->vaddr = vaddr; in nand_davinci_probe()
765 mtd = nand_to_mtd(&info->chip); in nand_davinci_probe()
766 mtd->dev.parent = &pdev->dev; in nand_davinci_probe()
767 nand_set_flash_node(&info->chip, pdev->dev.of_node); in nand_davinci_probe()
770 info->chip.bbt_options = pdata->bbt_options; in nand_davinci_probe()
771 /* options such as 16-bit widths */ in nand_davinci_probe()
772 info->chip.options = pdata->options; in nand_davinci_probe()
773 info->chip.bbt_td = pdata->bbt_td; in nand_davinci_probe()
774 info->chip.bbt_md = pdata->bbt_md; in nand_davinci_probe()
775 info->timing = pdata->timing; in nand_davinci_probe()
777 info->current_cs = info->vaddr; in nand_davinci_probe()
778 info->core_chipsel = pdata->core_chipsel; in nand_davinci_probe()
779 info->mask_chipsel = pdata->mask_chipsel; in nand_davinci_probe()
781 /* use nandboot-capable ALE/CLE masks by default */ in nand_davinci_probe()
782 info->mask_ale = pdata->mask_ale ? : MASK_ALE; in nand_davinci_probe()
783 info->mask_cle = pdata->mask_cle ? : MASK_CLE; in nand_davinci_probe()
787 /* put CSxNAND into NAND mode */ in nand_davinci_probe()
789 val |= BIT(info->core_chipsel); in nand_davinci_probe()
795 nand_controller_init(&info->controller); in nand_davinci_probe()
796 info->controller.ops = &davinci_nand_controller_ops; in nand_davinci_probe()
797 info->chip.controller = &info->controller; in nand_davinci_probe()
798 ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1); in nand_davinci_probe()
800 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); in nand_davinci_probe()
804 if (pdata->parts) in nand_davinci_probe()
805 ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); in nand_davinci_probe()
812 dev_info(&pdev->dev, "controller rev. %d.%d\n", in nand_davinci_probe()
818 nand_cleanup(&info->chip); in nand_davinci_probe()
826 struct nand_chip *chip = &info->chip; in nand_davinci_remove()
830 if (chip->ecc.placement == NAND_ECC_PLACEMENT_INTERLEAVED) in nand_davinci_remove()
853 MODULE_DESCRIPTION("Davinci NAND flash driver");