Lines Matching +full:nand +full:- +full:ecc +full:- +full:placement
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>
17 #include <linux/memory/ti-aemif.h>
30 /* 4-bit ECC syndrome registers */
42 * for ALE/CLE unless they support booting from NAND.
56 * 0-indexed chip-select number of the asynchronous
57 * interface to which the NAND device has been connected.
59 * So, if you have NAND connected to CS3 of DA850, you
74 * on-die == NAND_ECC_ENGINE_TYPE_ON_DIE
77 * All DaVinci-family chips support 1-bit hardware ECC.
78 * Newer ones also support 4-bit ECC, but are awkward
96 * This is a device driver for the NAND flash controller found on the
101 * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC
102 * available on chips like the DM355 and OMAP-L137 and needed with the
103 * more error-prone MLC NAND chips.
105 * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
106 * outputs in a "wire-AND" configuration, with no per-chip signals.
142 return __raw_readl(info->base + offset); in davinci_nand_readl()
148 __raw_writel(value, info->base + offset); in davinci_nand_writel()
151 /*----------------------------------------------------------------------*/
154 * 1-bit hardware ECC ... context maintained for each core chipselect
162 + 4 * info->core_chipsel); in nand_davinci_readecc_1bit()
173 /* Reset ECC hardware */ in nand_davinci_hwctl_1bit()
178 /* Restart ECC hardware */ in nand_davinci_hwctl_1bit()
180 nandcfr |= BIT(8 + info->core_chipsel); in nand_davinci_hwctl_1bit()
187 * Read hardware ECC value and pack into three bytes
195 /* invert so that erased block ecc is correct */ in nand_davinci_calculate_1bit()
216 if ((diff >> (12 + 3)) < chip->ecc.size) { in nand_davinci_correct_1bit()
220 return -EBADMSG; in nand_davinci_correct_1bit()
222 } else if (!(diff & (diff - 1))) { in nand_davinci_correct_1bit()
223 /* Single bit ECC error in the ECC itself, in nand_davinci_correct_1bit()
228 return -EBADMSG; in nand_davinci_correct_1bit()
235 /*----------------------------------------------------------------------*/
238 * 4-bit hardware ECC ... context maintained over entire AEMIF
243 * Also, and specific to this hardware, it ECC-protects the "prepad"
244 * in the OOB ... while having ECC protection for parts of OOB would
246 * OOB without recomputing ECC.
255 /* Reset ECC hardware */ in nand_davinci_hwctl_4bit()
260 /* Start 4-bit ECC calculation for read/write */ in nand_davinci_hwctl_4bit()
263 val |= (info->core_chipsel << 4) | BIT(12); in nand_davinci_hwctl_4bit()
266 info->is_readmode = (mode == NAND_ECC_READ); in nand_davinci_hwctl_4bit()
271 /* Read raw ECC code after writing to NAND. */
283 /* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
291 /* After a read, terminate ECC calculation by a dummy read in nand_davinci_calculate_4bit()
292 * of some 4-bit ECC register. ECC covers everything that in nand_davinci_calculate_4bit()
296 if (info->is_readmode) { in nand_davinci_calculate_4bit()
301 /* Pack eight raw 10-bit ecc values into ten bytes, making in nand_davinci_calculate_4bit()
303 * lower halves of two 32-bit words) into five bytes. The in nand_davinci_calculate_4bit()
334 * little-endian, and use type punning for less shifting/masking. in nand_davinci_correct_4bit()
337 return -EINVAL; in nand_davinci_correct_4bit()
349 /* Tell ECC controller about the expected ECC codes. */ in nand_davinci_correct_4bit()
350 for (i = 7; i >= 0; i--) in nand_davinci_correct_4bit()
380 * long as ECC_STATE reads less than 4. After that, ECC HW has entered in nand_davinci_correct_4bit()
399 return -EBADMSG; in nand_davinci_correct_4bit()
432 error_address = (512 + 7) - error_address; in nand_davinci_correct_4bit()
443 /*----------------------------------------------------------------------*/
445 /* An ECC layout for using 4-bit ECC with small-page flash, storing
446 * ten ECC bytes plus the manufacturer's bad block marker byte, and
453 return -ERANGE; in hwecc4_ooblayout_small_ecc()
456 oobregion->offset = 0; in hwecc4_ooblayout_small_ecc()
457 oobregion->length = 5; in hwecc4_ooblayout_small_ecc()
459 oobregion->offset = 6; in hwecc4_ooblayout_small_ecc()
460 oobregion->length = 2; in hwecc4_ooblayout_small_ecc()
462 oobregion->offset = 13; in hwecc4_ooblayout_small_ecc()
463 oobregion->length = 3; in hwecc4_ooblayout_small_ecc()
473 return -ERANGE; in hwecc4_ooblayout_small_free()
476 oobregion->offset = 8; in hwecc4_ooblayout_small_free()
477 oobregion->length = 5; in hwecc4_ooblayout_small_free()
479 oobregion->offset = 16; in hwecc4_ooblayout_small_free()
480 oobregion->length = mtd->oobsize - 16; in hwecc4_ooblayout_small_free()
487 .ecc = hwecc4_ooblayout_small_ecc,
494 struct nand_device *nand = mtd_to_nanddev(mtd); in hwecc4_ooblayout_large_ecc() local
495 unsigned int total_ecc_bytes = nand->ecc.ctx.total; in hwecc4_ooblayout_large_ecc()
499 return -ERANGE; in hwecc4_ooblayout_large_ecc()
501 oobregion->offset = (section * 16) + 6; in hwecc4_ooblayout_large_ecc()
502 oobregion->length = 10; in hwecc4_ooblayout_large_ecc()
510 struct nand_device *nand = mtd_to_nanddev(mtd); in hwecc4_ooblayout_large_free() local
511 unsigned int total_ecc_bytes = nand->ecc.ctx.total; in hwecc4_ooblayout_large_free()
515 if (section >= (nregions - 1)) in hwecc4_ooblayout_large_free()
516 return -ERANGE; in hwecc4_ooblayout_large_free()
518 oobregion->offset = ((section + 1) * 16); in hwecc4_ooblayout_large_free()
519 oobregion->length = 6; in hwecc4_ooblayout_large_free()
525 .ecc = hwecc4_ooblayout_large_ecc,
531 {.compatible = "ti,davinci-nand", },
532 {.compatible = "ti,keystone-nand", },
540 if (!dev_get_platdata(&pdev->dev)) { in nand_davinci_get_pdata()
545 pdata = devm_kzalloc(&pdev->dev, in nand_davinci_get_pdata()
548 pdev->dev.platform_data = pdata; in nand_davinci_get_pdata()
550 return ERR_PTR(-ENOMEM); in nand_davinci_get_pdata()
551 if (!device_property_read_u32(&pdev->dev, in nand_davinci_get_pdata()
552 "ti,davinci-chipselect", &prop)) in nand_davinci_get_pdata()
553 pdata->core_chipsel = prop; in nand_davinci_get_pdata()
555 return ERR_PTR(-EINVAL); in nand_davinci_get_pdata()
557 if (!device_property_read_u32(&pdev->dev, in nand_davinci_get_pdata()
558 "ti,davinci-mask-ale", &prop)) in nand_davinci_get_pdata()
559 pdata->mask_ale = prop; in nand_davinci_get_pdata()
560 if (!device_property_read_u32(&pdev->dev, in nand_davinci_get_pdata()
561 "ti,davinci-mask-cle", &prop)) in nand_davinci_get_pdata()
562 pdata->mask_cle = prop; in nand_davinci_get_pdata()
563 if (!device_property_read_u32(&pdev->dev, in nand_davinci_get_pdata()
564 "ti,davinci-mask-chipsel", &prop)) in nand_davinci_get_pdata()
565 pdata->mask_chipsel = prop; in nand_davinci_get_pdata()
566 if (!device_property_read_string(&pdev->dev, in nand_davinci_get_pdata()
567 "ti,davinci-ecc-mode", in nand_davinci_get_pdata()
570 pdata->engine_type = NAND_ECC_ENGINE_TYPE_NONE; in nand_davinci_get_pdata()
572 pdata->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in nand_davinci_get_pdata()
574 pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in nand_davinci_get_pdata()
575 if (!strncmp("on-die", mode, 6)) in nand_davinci_get_pdata()
576 pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_DIE; in nand_davinci_get_pdata()
578 if (!device_property_read_u32(&pdev->dev, in nand_davinci_get_pdata()
579 "ti,davinci-ecc-bits", &prop)) in nand_davinci_get_pdata()
580 pdata->ecc_bits = prop; in nand_davinci_get_pdata()
582 if (!device_property_read_u32(&pdev->dev, in nand_davinci_get_pdata()
583 "ti,davinci-nand-buswidth", in nand_davinci_get_pdata()
585 pdata->options |= NAND_BUSWIDTH_16; in nand_davinci_get_pdata()
587 if (device_property_read_bool(&pdev->dev, in nand_davinci_get_pdata()
588 "ti,davinci-nand-use-bbt")) in nand_davinci_get_pdata()
589 pdata->bbt_options = NAND_BBT_USE_FLASH; in nand_davinci_get_pdata()
593 * use of 4-bit hardware ECC with subpages and verified on in nand_davinci_get_pdata()
596 * existing UBI partitions, sub-page writes are not being in nand_davinci_get_pdata()
599 * then use "ti,davinci-nand" as the compatible in your in nand_davinci_get_pdata()
600 * device-tree file. in nand_davinci_get_pdata()
602 if (device_is_compatible(&pdev->dev, "ti,keystone-nand")) in nand_davinci_get_pdata()
603 pdata->options |= NAND_NO_SUBPAGE_WRITE; in nand_davinci_get_pdata()
606 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
612 return dev_get_platdata(&pdev->dev); in nand_davinci_get_pdata()
620 struct davinci_nand_pdata *pdata = nand_davinci_get_pdata(info->pdev); in davinci_nand_attach_chip()
626 /* Use board-specific ECC config */ in davinci_nand_attach_chip()
627 chip->ecc.engine_type = pdata->engine_type; in davinci_nand_attach_chip()
628 chip->ecc.placement = pdata->ecc_placement; in davinci_nand_attach_chip()
630 switch (chip->ecc.engine_type) { in davinci_nand_attach_chip()
633 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
636 pdata->ecc_bits = 0; in davinci_nand_attach_chip()
638 * This driver expects Hamming based ECC when engine_type is set in davinci_nand_attach_chip()
639 * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to in davinci_nand_attach_chip()
640 * NAND_ECC_ALGO_HAMMING to avoid adding an extra ->ecc_algo in davinci_nand_attach_chip()
643 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
646 if (pdata->ecc_bits == 4) { in davinci_nand_attach_chip()
647 int chunks = mtd->writesize / 512; in davinci_nand_attach_chip()
649 if (!chunks || mtd->oobsize < 16) { in davinci_nand_attach_chip()
650 dev_dbg(&info->pdev->dev, "too small\n"); in davinci_nand_attach_chip()
651 return -EINVAL; in davinci_nand_attach_chip()
659 /* No sharing 4-bit hardware between chipselects yet */ in davinci_nand_attach_chip()
662 ret = -EBUSY; in davinci_nand_attach_chip()
667 if (ret == -EBUSY) in davinci_nand_attach_chip()
670 chip->ecc.calculate = nand_davinci_calculate_4bit; in davinci_nand_attach_chip()
671 chip->ecc.correct = nand_davinci_correct_4bit; in davinci_nand_attach_chip()
672 chip->ecc.hwctl = nand_davinci_hwctl_4bit; in davinci_nand_attach_chip()
673 chip->ecc.bytes = 10; in davinci_nand_attach_chip()
674 chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; in davinci_nand_attach_chip()
675 chip->ecc.algo = NAND_ECC_ALGO_BCH; in davinci_nand_attach_chip()
678 * Update ECC layout if needed ... for 1-bit HW ECC, the in davinci_nand_attach_chip()
680 * are needed (for each 512 bytes). For 4-bit HW ECC, in davinci_nand_attach_chip()
691 chip->ecc.read_page = nand_read_page_hwecc_oob_first; in davinci_nand_attach_chip()
693 if (chip->options & NAND_IS_BOOT_MEDIUM) in davinci_nand_attach_chip()
698 return -EIO; in davinci_nand_attach_chip()
701 /* 1bit ecc hamming */ in davinci_nand_attach_chip()
702 chip->ecc.calculate = nand_davinci_calculate_1bit; in davinci_nand_attach_chip()
703 chip->ecc.correct = nand_davinci_correct_1bit; in davinci_nand_attach_chip()
704 chip->ecc.hwctl = nand_davinci_hwctl_1bit; in davinci_nand_attach_chip()
705 chip->ecc.bytes = 3; in davinci_nand_attach_chip()
706 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in davinci_nand_attach_chip()
708 chip->ecc.size = 512; in davinci_nand_attach_chip()
709 chip->ecc.strength = pdata->ecc_bits; in davinci_nand_attach_chip()
712 return -EINVAL; in davinci_nand_attach_chip()
724 ioread8_rep(info->current_cs, buf, len); in nand_davinci_data_in()
726 ioread16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_in()
728 ioread32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_in()
738 iowrite8_rep(info->current_cs, buf, len); in nand_davinci_data_out()
740 iowrite16_rep(info->current_cs, buf, len >> 1); in nand_davinci_data_out()
742 iowrite32_rep(info->current_cs, buf, len >> 2); in nand_davinci_data_out()
752 switch (instr->type) { in davinci_nand_exec_instr()
754 iowrite8(instr->ctx.cmd.opcode, in davinci_nand_exec_instr()
755 info->current_cs + info->mask_cle); in davinci_nand_exec_instr()
759 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in davinci_nand_exec_instr()
760 iowrite8(instr->ctx.addr.addrs[i], in davinci_nand_exec_instr()
761 info->current_cs + info->mask_ale); in davinci_nand_exec_instr()
766 nand_davinci_data_in(info, instr->ctx.data.buf.in, in davinci_nand_exec_instr()
767 instr->ctx.data.len, in davinci_nand_exec_instr()
768 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
772 nand_davinci_data_out(info, instr->ctx.data.buf.out, in davinci_nand_exec_instr()
773 instr->ctx.data.len, in davinci_nand_exec_instr()
774 instr->ctx.data.force_8bit); in davinci_nand_exec_instr()
778 timeout_us = instr->ctx.waitrdy.timeout_ms * 1000; in davinci_nand_exec_instr()
779 ret = readl_relaxed_poll_timeout(info->base + NANDFSR_OFFSET, in davinci_nand_exec_instr()
788 if (instr->delay_ns) { in davinci_nand_exec_instr()
791 ndelay(instr->delay_ns); in davinci_nand_exec_instr()
807 info->current_cs = info->vaddr + (op->cs * info->mask_chipsel); in davinci_nand_exec_op()
809 for (i = 0; i < op->ninstrs; i++) { in davinci_nand_exec_op()
812 ret = davinci_nand_exec_instr(info, &op->instrs[i]); in davinci_nand_exec_op()
831 cyc_ns = 1000000000 / clk_get_rate(info->clk); in davinci_nand_setup_interface()
837 cfg = TO_CYCLES(sdr->tCLR_min, cyc_ns) - 1; in davinci_nand_setup_interface()
840 cfg = max_t(s32, TO_CYCLES(sdr->tREA_max + MAX_TSU_PS, cyc_ns), in davinci_nand_setup_interface()
841 TO_CYCLES(sdr->tRP_min, cyc_ns)) - 1; in davinci_nand_setup_interface()
844 min = TO_CYCLES(sdr->tCEA_max + MAX_TSU_PS, cyc_ns) - 2; in davinci_nand_setup_interface()
848 cfg = TO_CYCLES((s32)(MAX_TH_PS - sdr->tCHZ_max), cyc_ns) - 1; in davinci_nand_setup_interface()
851 min = TO_CYCLES(sdr->tRC_min, cyc_ns) - 3; in davinci_nand_setup_interface()
855 cfg = TO_CYCLES((s32)(sdr->tRHZ_max - (timings.rhold + 1) * cyc_ns * 1000), cyc_ns); in davinci_nand_setup_interface()
856 cfg = max_t(s32, cfg, TO_CYCLES(sdr->tCHZ_max, cyc_ns)) - 1; in davinci_nand_setup_interface()
859 cfg = TO_CYCLES(sdr->tWP_min, cyc_ns) - 1; in davinci_nand_setup_interface()
862 cfg = max_t(s32, TO_CYCLES(sdr->tCLS_min, cyc_ns), TO_CYCLES(sdr->tALS_min, cyc_ns)); in davinci_nand_setup_interface()
863 cfg = max_t(s32, cfg, TO_CYCLES(sdr->tCS_min, cyc_ns)) - 1; in davinci_nand_setup_interface()
866 min = TO_CYCLES(sdr->tDS_min, cyc_ns) - 2; in davinci_nand_setup_interface()
870 cfg = max_t(s32, TO_CYCLES(sdr->tCLH_min, cyc_ns), TO_CYCLES(sdr->tALH_min, cyc_ns)); in davinci_nand_setup_interface()
871 cfg = max_t(s32, cfg, TO_CYCLES(sdr->tCH_min, cyc_ns)); in davinci_nand_setup_interface()
872 cfg = max_t(s32, cfg, TO_CYCLES(sdr->tDH_min, cyc_ns)) - 1; in davinci_nand_setup_interface()
875 min = TO_CYCLES(sdr->tWC_min, cyc_ns) - 2; in davinci_nand_setup_interface()
879 dev_dbg(&info->pdev->dev, "RSETUP %x RSTROBE %x RHOLD %x\n", in davinci_nand_setup_interface()
881 dev_dbg(&info->pdev->dev, "TA %x\n", timings.ta); in davinci_nand_setup_interface()
882 dev_dbg(&info->pdev->dev, "WSETUP %x WSTROBE %x WHOLD %x\n", in davinci_nand_setup_interface()
889 return aemif_set_cs_timings(info->aemif, info->core_chipsel, &timings); in davinci_nand_setup_interface()
914 /* insist on board-specific configuration */ in nand_davinci_probe()
916 return -ENODEV; in nand_davinci_probe()
919 if (pdata->core_chipsel > 3) in nand_davinci_probe()
920 return -ENODEV; in nand_davinci_probe()
922 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in nand_davinci_probe()
924 return -ENOMEM; in nand_davinci_probe()
931 dev_err(&pdev->dev, "resource missing\n"); in nand_davinci_probe()
932 return -EINVAL; in nand_davinci_probe()
935 vaddr = devm_ioremap_resource(&pdev->dev, res1); in nand_davinci_probe()
940 * This registers range is used to setup NAND settings. In case with in nand_davinci_probe()
943 * The AEMIF and NAND drivers not use the same registers in this range. in nand_davinci_probe()
945 base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); in nand_davinci_probe()
947 dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); in nand_davinci_probe()
948 return -EADDRNOTAVAIL; in nand_davinci_probe()
951 info->clk = devm_clk_get_enabled(&pdev->dev, "aemif"); in nand_davinci_probe()
952 if (IS_ERR(info->clk)) in nand_davinci_probe()
953 return dev_err_probe(&pdev->dev, PTR_ERR(info->clk), "failed to get clock"); in nand_davinci_probe()
955 info->pdev = pdev; in nand_davinci_probe()
956 info->base = base; in nand_davinci_probe()
957 info->vaddr = vaddr; in nand_davinci_probe()
958 info->aemif = dev_get_drvdata(pdev->dev.parent); in nand_davinci_probe()
960 mtd = nand_to_mtd(&info->chip); in nand_davinci_probe()
961 mtd->dev.parent = &pdev->dev; in nand_davinci_probe()
962 nand_set_flash_node(&info->chip, pdev->dev.of_node); in nand_davinci_probe()
965 info->chip.bbt_options = pdata->bbt_options; in nand_davinci_probe()
966 /* options such as 16-bit widths */ in nand_davinci_probe()
967 info->chip.options = pdata->options; in nand_davinci_probe()
968 info->chip.bbt_td = pdata->bbt_td; in nand_davinci_probe()
969 info->chip.bbt_md = pdata->bbt_md; in nand_davinci_probe()
971 info->current_cs = info->vaddr; in nand_davinci_probe()
972 info->core_chipsel = pdata->core_chipsel; in nand_davinci_probe()
973 info->mask_chipsel = pdata->mask_chipsel; in nand_davinci_probe()
975 /* use nandboot-capable ALE/CLE masks by default */ in nand_davinci_probe()
976 info->mask_ale = pdata->mask_ale ? : MASK_ALE; in nand_davinci_probe()
977 info->mask_cle = pdata->mask_cle ? : MASK_CLE; in nand_davinci_probe()
981 /* put CSxNAND into NAND mode */ in nand_davinci_probe()
983 val |= BIT(info->core_chipsel); in nand_davinci_probe()
989 nand_controller_init(&info->controller); in nand_davinci_probe()
990 info->controller.ops = &davinci_nand_controller_ops; in nand_davinci_probe()
991 info->chip.controller = &info->controller; in nand_davinci_probe()
992 ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1); in nand_davinci_probe()
994 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); in nand_davinci_probe()
998 if (pdata->parts) in nand_davinci_probe()
999 ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); in nand_davinci_probe()
1006 dev_info(&pdev->dev, "controller rev. %d.%d\n", in nand_davinci_probe()
1012 nand_cleanup(&info->chip); in nand_davinci_probe()
1020 struct nand_chip *chip = &info->chip; in nand_davinci_remove()
1024 if (chip->ecc.placement == NAND_ECC_PLACEMENT_INTERLEAVED) in nand_davinci_remove()
1047 MODULE_DESCRIPTION("Davinci NAND flash driver");