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.
72 return __raw_readl(info->base + offset); in davinci_nand_readl()
78 __raw_writel(value, info->base + offset); in davinci_nand_writel()
81 /*----------------------------------------------------------------------*/
87 static void nand_davinci_hwcontrol(struct nand_chip *nand, int cmd, in nand_davinci_hwcontrol() argument
90 struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(nand)); in nand_davinci_hwcontrol()
91 void __iomem *addr = info->current_cs; in nand_davinci_hwcontrol()
96 addr += info->mask_cle; in nand_davinci_hwcontrol()
98 addr += info->mask_ale; in nand_davinci_hwcontrol()
100 nand->legacy.IO_ADDR_W = addr; in nand_davinci_hwcontrol()
104 iowrite8(cmd, nand->legacy.IO_ADDR_W); in nand_davinci_hwcontrol()
107 static void nand_davinci_select_chip(struct nand_chip *nand, int chip) in nand_davinci_select_chip() argument
109 struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(nand)); in nand_davinci_select_chip()
111 info->current_cs = info->vaddr; in nand_davinci_select_chip()
115 info->current_cs += info->mask_chipsel; in nand_davinci_select_chip()
117 info->chip.legacy.IO_ADDR_W = info->current_cs; in nand_davinci_select_chip()
118 info->chip.legacy.IO_ADDR_R = info->chip.legacy.IO_ADDR_W; in nand_davinci_select_chip()
121 /*----------------------------------------------------------------------*/
124 * 1-bit hardware ECC ... context maintained for each core chipselect
132 + 4 * info->core_chipsel); in nand_davinci_readecc_1bit()
135 static void nand_davinci_hwctl_1bit(struct nand_chip *chip, int mode) in nand_davinci_hwctl_1bit() argument
143 /* Reset ECC hardware */ in nand_davinci_hwctl_1bit()
148 /* Restart ECC hardware */ in nand_davinci_hwctl_1bit()
150 nandcfr |= BIT(8 + info->core_chipsel); in nand_davinci_hwctl_1bit()
157 * Read hardware ECC value and pack into three bytes
165 /* invert so that erased block ecc is correct */ in nand_davinci_calculate_1bit()
186 if ((diff >> (12 + 3)) < chip->ecc.size) { in nand_davinci_correct_1bit()
190 return -EBADMSG; in nand_davinci_correct_1bit()
192 } else if (!(diff & (diff - 1))) { in nand_davinci_correct_1bit()
193 /* Single bit ECC error in the ECC itself, in nand_davinci_correct_1bit()
198 return -EBADMSG; in nand_davinci_correct_1bit()
205 /*----------------------------------------------------------------------*/
208 * 4-bit hardware ECC ... context maintained over entire AEMIF
213 * Also, and specific to this hardware, it ECC-protects the "prepad"
214 * in the OOB ... while having ECC protection for parts of OOB would
216 * OOB without recomputing ECC.
219 static void nand_davinci_hwctl_4bit(struct nand_chip *chip, int mode) in nand_davinci_hwctl_4bit() argument
225 /* Reset ECC hardware */ in nand_davinci_hwctl_4bit()
230 /* Start 4-bit ECC calculation for read/write */ in nand_davinci_hwctl_4bit()
233 val |= (info->core_chipsel << 4) | BIT(12); in nand_davinci_hwctl_4bit()
236 info->is_readmode = (mode == NAND_ECC_READ); in nand_davinci_hwctl_4bit()
241 /* Read raw ECC code after writing to NAND. */
253 /* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
261 /* After a read, terminate ECC calculation by a dummy read in nand_davinci_calculate_4bit()
262 * of some 4-bit ECC register. ECC covers everything that in nand_davinci_calculate_4bit()
266 if (info->is_readmode) { in nand_davinci_calculate_4bit()
271 /* Pack eight raw 10-bit ecc values into ten bytes, making in nand_davinci_calculate_4bit()
273 * lower halves of two 32-bit words) into five bytes. The in nand_davinci_calculate_4bit()
304 * little-endian, and use type punning for less shifting/masking. in nand_davinci_correct_4bit()
307 return -EINVAL; in nand_davinci_correct_4bit()
319 /* Tell ECC controller about the expected ECC codes. */ in nand_davinci_correct_4bit()
320 for (i = 7; i >= 0; i--) in nand_davinci_correct_4bit()
350 * long as ECC_STATE reads less than 4. After that, ECC HW has entered in nand_davinci_correct_4bit()
369 return -EBADMSG; in nand_davinci_correct_4bit()
402 error_address = (512 + 7) - error_address; in nand_davinci_correct_4bit()
413 /*----------------------------------------------------------------------*/
416 * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
421 * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
422 * and have that transparently morphed into multiple NAND operations.
428 ioread32_rep(chip->legacy.IO_ADDR_R, buf, len >> 2); in nand_davinci_read_buf()
430 ioread16_rep(chip->legacy.IO_ADDR_R, buf, len >> 1); in nand_davinci_read_buf()
432 ioread8_rep(chip->legacy.IO_ADDR_R, buf, len); in nand_davinci_read_buf()
439 iowrite32_rep(chip->legacy.IO_ADDR_R, buf, len >> 2); in nand_davinci_write_buf()
441 iowrite16_rep(chip->legacy.IO_ADDR_R, buf, len >> 1); in nand_davinci_write_buf()
443 iowrite8_rep(chip->legacy.IO_ADDR_R, buf, len); in nand_davinci_write_buf()
457 /*----------------------------------------------------------------------*/
459 /* An ECC layout for using 4-bit ECC with small-page flash, storing
460 * ten ECC bytes plus the manufacturer's bad block marker byte, and
467 return -ERANGE; in hwecc4_ooblayout_small_ecc()
470 oobregion->offset = 0; in hwecc4_ooblayout_small_ecc()
471 oobregion->length = 5; in hwecc4_ooblayout_small_ecc()
473 oobregion->offset = 6; in hwecc4_ooblayout_small_ecc()
474 oobregion->length = 2; in hwecc4_ooblayout_small_ecc()
476 oobregion->offset = 13; in hwecc4_ooblayout_small_ecc()
477 oobregion->length = 3; in hwecc4_ooblayout_small_ecc()
487 return -ERANGE; in hwecc4_ooblayout_small_free()
490 oobregion->offset = 8; in hwecc4_ooblayout_small_free()
491 oobregion->length = 5; in hwecc4_ooblayout_small_free()
493 oobregion->offset = 16; in hwecc4_ooblayout_small_free()
494 oobregion->length = mtd->oobsize - 16; in hwecc4_ooblayout_small_free()
501 .ecc = hwecc4_ooblayout_small_ecc,
507 {.compatible = "ti,davinci-nand", },
508 {.compatible = "ti,keystone-nand", },
516 if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) { in nand_davinci_get_pdata()
518 const char *mode; in nand_davinci_get_pdata() local
521 pdata = devm_kzalloc(&pdev->dev, in nand_davinci_get_pdata()
524 pdev->dev.platform_data = pdata; in nand_davinci_get_pdata()
526 return ERR_PTR(-ENOMEM); in nand_davinci_get_pdata()
527 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
528 "ti,davinci-chipselect", &prop)) in nand_davinci_get_pdata()
529 pdata->core_chipsel = prop; in nand_davinci_get_pdata()
531 return ERR_PTR(-EINVAL); in nand_davinci_get_pdata()
533 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
534 "ti,davinci-mask-ale", &prop)) in nand_davinci_get_pdata()
535 pdata->mask_ale = prop; in nand_davinci_get_pdata()
536 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
537 "ti,davinci-mask-cle", &prop)) in nand_davinci_get_pdata()
538 pdata->mask_cle = prop; in nand_davinci_get_pdata()
539 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
540 "ti,davinci-mask-chipsel", &prop)) in nand_davinci_get_pdata()
541 pdata->mask_chipsel = prop; in nand_davinci_get_pdata()
542 if (!of_property_read_string(pdev->dev.of_node, in nand_davinci_get_pdata()
543 "ti,davinci-ecc-mode", &mode)) { in nand_davinci_get_pdata()
544 if (!strncmp("none", mode, 4)) in nand_davinci_get_pdata()
545 pdata->ecc_mode = NAND_ECC_NONE; in nand_davinci_get_pdata()
546 if (!strncmp("soft", mode, 4)) in nand_davinci_get_pdata()
547 pdata->ecc_mode = NAND_ECC_SOFT; in nand_davinci_get_pdata()
548 if (!strncmp("hw", mode, 2)) in nand_davinci_get_pdata()
549 pdata->ecc_mode = NAND_ECC_HW; in nand_davinci_get_pdata()
551 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
552 "ti,davinci-ecc-bits", &prop)) in nand_davinci_get_pdata()
553 pdata->ecc_bits = prop; in nand_davinci_get_pdata()
555 if (!of_property_read_u32(pdev->dev.of_node, in nand_davinci_get_pdata()
556 "ti,davinci-nand-buswidth", &prop) && prop == 16) in nand_davinci_get_pdata()
557 pdata->options |= NAND_BUSWIDTH_16; in nand_davinci_get_pdata()
559 if (of_property_read_bool(pdev->dev.of_node, in nand_davinci_get_pdata()
560 "ti,davinci-nand-use-bbt")) in nand_davinci_get_pdata()
561 pdata->bbt_options = NAND_BBT_USE_FLASH; in nand_davinci_get_pdata()
565 * use of 4-bit hardware ECC with subpages and verified on in nand_davinci_get_pdata()
568 * existing UBI partitions, sub-page writes are not being in nand_davinci_get_pdata()
571 * then use "ti,davinci-nand" as the compatible in your in nand_davinci_get_pdata()
572 * device-tree file. in nand_davinci_get_pdata()
574 if (of_device_is_compatible(pdev->dev.of_node, in nand_davinci_get_pdata()
575 "ti,keystone-nand")) { in nand_davinci_get_pdata()
576 pdata->options |= NAND_NO_SUBPAGE_WRITE; in nand_davinci_get_pdata()
580 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
586 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
594 struct davinci_nand_pdata *pdata = nand_davinci_get_pdata(info->pdev); in davinci_nand_attach_chip()
600 switch (info->chip.ecc.mode) { in davinci_nand_attach_chip()
602 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
605 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
607 * This driver expects Hamming based ECC when ecc_mode is set in davinci_nand_attach_chip()
608 * to NAND_ECC_SOFT. Force ecc.algo to NAND_ECC_HAMMING to in davinci_nand_attach_chip()
609 * avoid adding an extra ->ecc_algo field to in davinci_nand_attach_chip()
612 info->chip.ecc.algo = NAND_ECC_HAMMING; in davinci_nand_attach_chip()
615 if (pdata->ecc_bits == 4) { in davinci_nand_attach_chip()
621 /* No sharing 4-bit hardware between chipselects yet */ in davinci_nand_attach_chip()
624 ret = -EBUSY; in davinci_nand_attach_chip()
629 if (ret == -EBUSY) in davinci_nand_attach_chip()
632 info->chip.ecc.calculate = nand_davinci_calculate_4bit; in davinci_nand_attach_chip()
633 info->chip.ecc.correct = nand_davinci_correct_4bit; in davinci_nand_attach_chip()
634 info->chip.ecc.hwctl = nand_davinci_hwctl_4bit; in davinci_nand_attach_chip()
635 info->chip.ecc.bytes = 10; in davinci_nand_attach_chip()
636 info->chip.ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; in davinci_nand_attach_chip()
637 info->chip.ecc.algo = NAND_ECC_BCH; in davinci_nand_attach_chip()
639 /* 1bit ecc hamming */ in davinci_nand_attach_chip()
640 info->chip.ecc.calculate = nand_davinci_calculate_1bit; in davinci_nand_attach_chip()
641 info->chip.ecc.correct = nand_davinci_correct_1bit; in davinci_nand_attach_chip()
642 info->chip.ecc.hwctl = nand_davinci_hwctl_1bit; in davinci_nand_attach_chip()
643 info->chip.ecc.bytes = 3; in davinci_nand_attach_chip()
644 info->chip.ecc.algo = NAND_ECC_HAMMING; in davinci_nand_attach_chip()
646 info->chip.ecc.size = 512; in davinci_nand_attach_chip()
647 info->chip.ecc.strength = pdata->ecc_bits; in davinci_nand_attach_chip()
650 return -EINVAL; in davinci_nand_attach_chip()
654 * Update ECC layout if needed ... for 1-bit HW ECC, the default in davinci_nand_attach_chip()
656 * each 512 bytes). For the 4-bit HW ECC, that default is not in davinci_nand_attach_chip()
659 if (pdata->ecc_bits == 4) { in davinci_nand_attach_chip()
660 int chunks = mtd->writesize / 512; in davinci_nand_attach_chip()
662 if (!chunks || mtd->oobsize < 16) { in davinci_nand_attach_chip()
663 dev_dbg(&info->pdev->dev, "too small\n"); in davinci_nand_attach_chip()
664 return -EINVAL; in davinci_nand_attach_chip()
675 info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; in davinci_nand_attach_chip()
677 return -EIO; in davinci_nand_attach_chip()
704 /* insist on board-specific configuration */ in nand_davinci_probe()
706 return -ENODEV; in nand_davinci_probe()
709 if (pdata->core_chipsel < 0 || pdata->core_chipsel > 3) in nand_davinci_probe()
710 return -ENODEV; in nand_davinci_probe()
712 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in nand_davinci_probe()
714 return -ENOMEM; in nand_davinci_probe()
721 dev_err(&pdev->dev, "resource missing\n"); in nand_davinci_probe()
722 return -EINVAL; in nand_davinci_probe()
725 vaddr = devm_ioremap_resource(&pdev->dev, res1); in nand_davinci_probe()
730 * This registers range is used to setup NAND settings. In case with in nand_davinci_probe()
733 * The AEMIF and NAND drivers not use the same registers in this range. in nand_davinci_probe()
735 base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); in nand_davinci_probe()
737 dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); in nand_davinci_probe()
738 return -EADDRNOTAVAIL; in nand_davinci_probe()
741 info->pdev = pdev; in nand_davinci_probe()
742 info->base = base; in nand_davinci_probe()
743 info->vaddr = vaddr; in nand_davinci_probe()
745 mtd = nand_to_mtd(&info->chip); in nand_davinci_probe()
746 mtd->dev.parent = &pdev->dev; in nand_davinci_probe()
747 nand_set_flash_node(&info->chip, pdev->dev.of_node); in nand_davinci_probe()
749 info->chip.legacy.IO_ADDR_R = vaddr; in nand_davinci_probe()
750 info->chip.legacy.IO_ADDR_W = vaddr; in nand_davinci_probe()
751 info->chip.legacy.chip_delay = 0; in nand_davinci_probe()
752 info->chip.legacy.select_chip = nand_davinci_select_chip; in nand_davinci_probe()
755 info->chip.bbt_options = pdata->bbt_options; in nand_davinci_probe()
756 /* options such as 16-bit widths */ in nand_davinci_probe()
757 info->chip.options = pdata->options; in nand_davinci_probe()
758 info->chip.bbt_td = pdata->bbt_td; in nand_davinci_probe()
759 info->chip.bbt_md = pdata->bbt_md; in nand_davinci_probe()
760 info->timing = pdata->timing; in nand_davinci_probe()
762 info->current_cs = info->vaddr; in nand_davinci_probe()
763 info->core_chipsel = pdata->core_chipsel; in nand_davinci_probe()
764 info->mask_chipsel = pdata->mask_chipsel; in nand_davinci_probe()
766 /* use nandboot-capable ALE/CLE masks by default */ in nand_davinci_probe()
767 info->mask_ale = pdata->mask_ale ? : MASK_ALE; in nand_davinci_probe()
768 info->mask_cle = pdata->mask_cle ? : MASK_CLE; in nand_davinci_probe()
771 info->chip.legacy.cmd_ctrl = nand_davinci_hwcontrol; in nand_davinci_probe()
772 info->chip.legacy.dev_ready = nand_davinci_dev_ready; in nand_davinci_probe()
775 info->chip.legacy.read_buf = nand_davinci_read_buf; in nand_davinci_probe()
776 info->chip.legacy.write_buf = nand_davinci_write_buf; in nand_davinci_probe()
778 /* Use board-specific ECC config */ in nand_davinci_probe()
779 info->chip.ecc.mode = pdata->ecc_mode; in nand_davinci_probe()
783 /* put CSxNAND into NAND mode */ in nand_davinci_probe()
785 val |= BIT(info->core_chipsel); in nand_davinci_probe()
791 info->chip.legacy.dummy_controller.ops = &davinci_nand_controller_ops; in nand_davinci_probe()
792 ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1); in nand_davinci_probe()
794 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); in nand_davinci_probe()
798 if (pdata->parts) in nand_davinci_probe()
799 ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); in nand_davinci_probe()
806 dev_info(&pdev->dev, "controller rev. %d.%d\n", in nand_davinci_probe()
812 nand_cleanup(&info->chip); in nand_davinci_probe()
822 if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME) in nand_davinci_remove()
826 nand_release(&info->chip); in nand_davinci_remove()
845 MODULE_DESCRIPTION("Davinci NAND flash driver");