Lines Matching +full:use +full:- +full:minimum +full:- +full:ecc

1 // SPDX-License-Identifier: GPL-2.0
33 #define PL35X_NANDC_DRIVER_NAME "pl35x-nand-controller"
60 /* SMC ECC status register (RO) */
63 /* SMC ECC configuration register */
70 /* SMC ECC command 1 register */
76 /* SMC ECC command 2 register */
82 /* SMC ECC value registers (RO) */
128 * struct pl35x_nandc - NAND flash controller driver structure
136 * @ecc_buf: Temporary buffer to extract ECC bytes
164 if (section >= chip->ecc.steps) in pl35x_ecc_ooblayout16_ecc()
165 return -ERANGE; in pl35x_ecc_ooblayout16_ecc()
167 oobregion->offset = (section * chip->ecc.bytes); in pl35x_ecc_ooblayout16_ecc()
168 oobregion->length = chip->ecc.bytes; in pl35x_ecc_ooblayout16_ecc()
178 if (section >= chip->ecc.steps) in pl35x_ecc_ooblayout16_free()
179 return -ERANGE; in pl35x_ecc_ooblayout16_free()
181 oobregion->offset = (section * chip->ecc.bytes) + 8; in pl35x_ecc_ooblayout16_free()
182 oobregion->length = 8; in pl35x_ecc_ooblayout16_free()
188 .ecc = pl35x_ecc_ooblayout16_ecc,
220 nfc->conf_regs + PL35X_SMC_DIRECT_CMD); in pl35x_smc_update_regs()
226 return -EINVAL; in pl35x_smc_set_buswidth()
228 writel(bw, nfc->conf_regs + PL35X_SMC_OPMODE); in pl35x_smc_set_buswidth()
237 nfc->conf_regs + PL35X_SMC_MEMC_CFG_CLR); in pl35x_smc_clear_irq()
245 ret = readl_poll_timeout(nfc->conf_regs + PL35X_SMC_MEMC_STATUS, reg, in pl35x_smc_wait_for_irq()
249 dev_err(nfc->dev, in pl35x_smc_wait_for_irq()
263 ret = readl_poll_timeout(nfc->conf_regs + PL35X_SMC_ECC_STATUS, reg, in pl35x_smc_wait_for_ecc_done()
267 dev_err(nfc->dev, in pl35x_smc_wait_for_ecc_done()
268 "Timeout polling on ECC controller interrupt\n"); in pl35x_smc_wait_for_ecc_done()
280 ecc_cfg = readl(nfc->conf_regs + PL35X_SMC_ECC_CFG); in pl35x_smc_set_ecc_mode()
283 writel(ecc_cfg, nfc->conf_regs + PL35X_SMC_ECC_CFG); in pl35x_smc_set_ecc_mode()
287 plnand->ecc_cfg = ecc_cfg; in pl35x_smc_set_ecc_mode()
299 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_smc_force_byte_access()
302 if (!(chip->options & NAND_BUSWIDTH_16)) in pl35x_smc_force_byte_access()
311 dev_err(nfc->dev, "Error in Buswidth\n"); in pl35x_smc_force_byte_access()
317 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_select_target()
320 if (chip == nfc->selected_chip) in pl35x_nand_select_target()
324 writel(plnand->timings, nfc->conf_regs + PL35X_SMC_CYCLES); in pl35x_nand_select_target()
327 /* Configure the ECC engine */ in pl35x_nand_select_target()
328 writel(plnand->ecc_cfg, nfc->conf_regs + PL35X_SMC_ECC_CFG); in pl35x_nand_select_target()
330 nfc->selected_chip = chip; in pl35x_nand_select_target()
337 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_read_data_op()
353 buf32[i] = readl(nfc->io_regs + data_phase_addr); in pl35x_nand_read_data_op()
358 buf8[i] = readb(nfc->io_regs + PL35X_SMC_DATA_PHASE); in pl35x_nand_read_data_op()
369 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_write_data_op()
385 writel(buf32[i], nfc->io_regs + data_phase_addr); in pl35x_nand_write_data_op()
390 writeb(buf8[i], nfc->io_regs + PL35X_SMC_DATA_PHASE); in pl35x_nand_write_data_op()
433 /* One error in the ECC data; no action needed */ in pl35x_nand_correct_data()
437 return -EBADMSG; in pl35x_nand_correct_data()
446 for (ecc_byte = 0; ecc_byte < chip->ecc.bytes; ecc_byte++) in pl35x_nand_ecc_reg_to_array()
456 for (chunk = 0; chunk < chip->ecc.steps; in pl35x_nand_read_eccbytes()
457 chunk++, read_ecc += chip->ecc.bytes) { in pl35x_nand_read_eccbytes()
458 ecc_value = readl(nfc->conf_regs + PL35X_SMC_ECC_VALUE(chunk)); in pl35x_nand_read_eccbytes()
460 return -EINVAL; in pl35x_nand_read_eccbytes()
478 for (chunk = 0; chunk < chip->ecc.steps; in pl35x_nand_recover_data_hwecc()
479 chunk++, data += chip->ecc.size, read_ecc += chip->ecc.bytes) { in pl35x_nand_recover_data_hwecc()
480 /* Read ECC value for each chunk */ in pl35x_nand_recover_data_hwecc()
481 ecc_value = readl(nfc->conf_regs + PL35X_SMC_ECC_VALUE(chunk)); in pl35x_nand_recover_data_hwecc()
484 return -EINVAL; in pl35x_nand_recover_data_hwecc()
487 mtd->ecc_stats.failed++; in pl35x_nand_recover_data_hwecc()
494 mtd->ecc_stats.failed++; in pl35x_nand_recover_data_hwecc()
496 mtd->ecc_stats.corrected += stats; in pl35x_nand_recover_data_hwecc()
508 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_write_page_hwecc()
511 unsigned int first_row = (mtd->writesize <= 512) ? 1 : 2; in pl35x_nand_write_page_hwecc()
512 unsigned int nrows = plnand->addr_cycles; in pl35x_nand_write_page_hwecc()
522 PL35X_SMC_CMD_PHASE_NADDRS(plnand->addr_cycles) | in pl35x_nand_write_page_hwecc()
531 addr2 |= PL35X_SMC_CMD_PHASE_ADDR(row - 4, addr); in pl35x_nand_write_page_hwecc()
535 writel(addr1, nfc->io_regs + cmd_addr); in pl35x_nand_write_page_hwecc()
536 if (plnand->addr_cycles > 4) in pl35x_nand_write_page_hwecc()
537 writel(addr2, nfc->io_regs + cmd_addr); in pl35x_nand_write_page_hwecc()
540 pl35x_nand_write_data_op(chip, buf, mtd->writesize, false, in pl35x_nand_write_page_hwecc()
546 /* Copy the HW calculated ECC bytes in the OOB buffer */ in pl35x_nand_write_page_hwecc()
547 ret = pl35x_nand_read_eccbytes(nfc, chip, nfc->ecc_buf); in pl35x_nand_write_page_hwecc()
552 memset(chip->oob_poi, 0xFF, mtd->oobsize); in pl35x_nand_write_page_hwecc()
554 ret = mtd_ooblayout_set_eccbytes(mtd, nfc->ecc_buf, chip->oob_poi, in pl35x_nand_write_page_hwecc()
555 0, chip->ecc.total); in pl35x_nand_write_page_hwecc()
559 /* Write the spare area with ECC bytes */ in pl35x_nand_write_page_hwecc()
560 pl35x_nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false, 0, in pl35x_nand_write_page_hwecc()
576 * generated ECC values and read ECC values from spare area.
579 * last data access to tell the ECC engine not to expect any further data.
581 * and doing a last 4-byte transfer with the additional bit set. The last block
582 * should be aligned with the end of an ECC block. Because of this limitation,
583 * it is not possible to use the core routines.
590 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_read_page_hwecc()
593 unsigned int first_row = (mtd->writesize <= 512) ? 1 : 2; in pl35x_nand_read_page_hwecc()
594 unsigned int nrows = plnand->addr_cycles; in pl35x_nand_read_page_hwecc()
604 PL35X_SMC_CMD_PHASE_NADDRS(plnand->addr_cycles) | in pl35x_nand_read_page_hwecc()
615 addr2 |= PL35X_SMC_CMD_PHASE_ADDR(row - 4, addr); in pl35x_nand_read_page_hwecc()
619 writel(addr1, nfc->io_regs + cmd_addr); in pl35x_nand_read_page_hwecc()
620 if (plnand->addr_cycles > 4) in pl35x_nand_read_page_hwecc()
621 writel(addr2, nfc->io_regs + cmd_addr); in pl35x_nand_read_page_hwecc()
624 ndelay(PSEC_TO_NSEC(sdr->tRR_min)); in pl35x_nand_read_page_hwecc()
630 pl35x_nand_read_data_op(chip, buf, mtd->writesize, false, in pl35x_nand_read_page_hwecc()
636 /* Retrieve the stored ECC bytes */ in pl35x_nand_read_page_hwecc()
637 pl35x_nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false, in pl35x_nand_read_page_hwecc()
639 ret = mtd_ooblayout_get_eccbytes(mtd, nfc->ecc_buf, chip->oob_poi, 0, in pl35x_nand_read_page_hwecc()
640 chip->ecc.total); in pl35x_nand_read_page_hwecc()
647 return pl35x_nand_recover_data_hwecc(nfc, chip, buf, nfc->ecc_buf); in pl35x_nand_read_page_hwecc()
658 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_exec_op()
663 int last_instr_type = -1; in pl35x_nand_exec_op()
668 for (op_id = 0; op_id < subop->ninstrs; op_id++) { in pl35x_nand_exec_op()
669 instr = &subop->instrs[op_id]; in pl35x_nand_exec_op()
671 switch (instr->type) { in pl35x_nand_exec_op()
674 cmd0 = PL35X_SMC_CMD_PHASE_CMD0(instr->ctx.cmd.opcode); in pl35x_nand_exec_op()
676 cmd1 = PL35X_SMC_CMD_PHASE_CMD1(instr->ctx.cmd.opcode); in pl35x_nand_exec_op()
686 addrs = &instr->ctx.addr.addrs[offset]; in pl35x_nand_exec_op()
693 addr2 |= PL35X_SMC_CMD_PHASE_ADDR(i - 4, addrs[i]); in pl35x_nand_exec_op()
704 rdy_tim_ms = instr->ctx.waitrdy.timeout_ms; in pl35x_nand_exec_op()
705 rdy_del_ns = instr->delay_ns; in pl35x_nand_exec_op()
709 last_instr_type = instr->type; in pl35x_nand_exec_op()
715 writel(addr1, nfc->io_regs + cmd_addr); in pl35x_nand_exec_op()
717 writel(addr2, nfc->io_regs + cmd_addr); in pl35x_nand_exec_op()
720 if (data_instr && data_instr->type == NAND_OP_DATA_OUT_INSTR) { in pl35x_nand_exec_op()
725 pl35x_nand_write_data_op(chip, data_instr->ctx.data.buf.out, in pl35x_nand_exec_op()
726 len, data_instr->ctx.data.force_8bit, in pl35x_nand_exec_op()
737 if (data_instr && data_instr->type == NAND_OP_DATA_IN_INSTR) in pl35x_nand_exec_op()
738 pl35x_nand_read_data_op(chip, data_instr->ctx.data.buf.in, in pl35x_nand_exec_op()
739 len, data_instr->ctx.data.force_8bit, in pl35x_nand_exec_op()
771 pl35x_nand_select_target(chip, op->cs); in pl35x_nfc_exec_op()
780 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nfc_setup_interface()
791 mclk = of_clk_get_by_name(nfc->dev->parent->of_node, "memclk"); in pl35x_nfc_setup_interface()
793 dev_err(nfc->dev, "Failed to retrieve SMC memclk\n"); in pl35x_nfc_setup_interface()
798 * SDR timings are given in pico-seconds while NFC timings must be in pl35x_nfc_setup_interface()
799 * expressed in NAND controller clock cycles. We use the TO_CYCLE() in pl35x_nfc_setup_interface()
808 val = TO_CYCLES(sdr->tRC_min, period_ns); in pl35x_nfc_setup_interface()
809 if (sdr->tRC_min <= 20000) in pl35x_nfc_setup_interface()
814 return -EINVAL; in pl35x_nfc_setup_interface()
816 val = TO_CYCLES(sdr->tWC_min, period_ns); in pl35x_nfc_setup_interface()
819 return -EINVAL; in pl35x_nfc_setup_interface()
827 val = TO_CYCLES(sdr->tWP_min, period_ns); in pl35x_nfc_setup_interface()
830 return -EINVAL; in pl35x_nfc_setup_interface()
832 val = TO_CYCLES(sdr->tCLR_min, period_ns); in pl35x_nfc_setup_interface()
835 return -EINVAL; in pl35x_nfc_setup_interface()
837 val = TO_CYCLES(sdr->tAR_min, period_ns); in pl35x_nfc_setup_interface()
840 return -EINVAL; in pl35x_nfc_setup_interface()
842 val = TO_CYCLES(sdr->tRR_min, period_ns); in pl35x_nfc_setup_interface()
845 return -EINVAL; in pl35x_nfc_setup_interface()
850 plnand->timings = PL35X_SMC_NAND_TRC_CYCLES(tmgs.t_rc) | in pl35x_nfc_setup_interface()
883 plnand->ecc_cfg = readl(nfc->conf_regs + PL35X_SMC_ECC_CFG); in pl35x_smc_set_ecc_pg_size()
884 plnand->ecc_cfg &= ~PL35X_SMC_ECC_CFG_PGSIZE_MASK; in pl35x_smc_set_ecc_pg_size()
885 plnand->ecc_cfg |= sz; in pl35x_smc_set_ecc_pg_size()
886 writel(plnand->ecc_cfg, nfc->conf_regs + PL35X_SMC_ECC_CFG); in pl35x_smc_set_ecc_pg_size()
895 if (mtd->writesize < SZ_512 || mtd->writesize > SZ_2K) { in pl35x_nand_init_hw_ecc_controller()
896 dev_err(nfc->dev, in pl35x_nand_init_hw_ecc_controller()
897 "The hardware ECC engine is limited to pages up to 2kiB\n"); in pl35x_nand_init_hw_ecc_controller()
898 return -EOPNOTSUPP; in pl35x_nand_init_hw_ecc_controller()
901 chip->ecc.strength = 1; in pl35x_nand_init_hw_ecc_controller()
902 chip->ecc.bytes = 3; in pl35x_nand_init_hw_ecc_controller()
903 chip->ecc.size = SZ_512; in pl35x_nand_init_hw_ecc_controller()
904 chip->ecc.steps = mtd->writesize / chip->ecc.size; in pl35x_nand_init_hw_ecc_controller()
905 chip->ecc.read_page = pl35x_nand_read_page_hwecc; in pl35x_nand_init_hw_ecc_controller()
906 chip->ecc.write_page = pl35x_nand_write_page_hwecc; in pl35x_nand_init_hw_ecc_controller()
907 chip->ecc.write_page_raw = nand_monolithic_write_page_raw; in pl35x_nand_init_hw_ecc_controller()
908 pl35x_smc_set_ecc_pg_size(nfc, chip, mtd->writesize); in pl35x_nand_init_hw_ecc_controller()
910 nfc->ecc_buf = devm_kmalloc(nfc->dev, chip->ecc.bytes * chip->ecc.steps, in pl35x_nand_init_hw_ecc_controller()
912 if (!nfc->ecc_buf) in pl35x_nand_init_hw_ecc_controller()
913 return -ENOMEM; in pl35x_nand_init_hw_ecc_controller()
915 switch (mtd->oobsize) { in pl35x_nand_init_hw_ecc_controller()
919 chip->bbt_options |= NAND_BBT_NO_OOB_BBM; in pl35x_nand_init_hw_ecc_controller()
925 dev_err(nfc->dev, "Unsupported OOB size\n"); in pl35x_nand_init_hw_ecc_controller()
926 return -EOPNOTSUPP; in pl35x_nand_init_hw_ecc_controller()
935 nanddev_get_ecc_requirements(&chip->base); in pl35x_nand_attach_chip()
936 struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); in pl35x_nand_attach_chip()
941 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_NONE && in pl35x_nand_attach_chip()
942 (!chip->ecc.size || !chip->ecc.strength)) { in pl35x_nand_attach_chip()
943 if (requirements->step_size && requirements->strength) { in pl35x_nand_attach_chip()
944 chip->ecc.size = requirements->step_size; in pl35x_nand_attach_chip()
945 chip->ecc.strength = requirements->strength; in pl35x_nand_attach_chip()
947 dev_info(nfc->dev, in pl35x_nand_attach_chip()
948 "No minimum ECC strength, using 1b/512B\n"); in pl35x_nand_attach_chip()
949 chip->ecc.size = 512; in pl35x_nand_attach_chip()
950 chip->ecc.strength = 1; in pl35x_nand_attach_chip()
954 if (mtd->writesize <= SZ_512) in pl35x_nand_attach_chip()
955 plnand->addr_cycles = 1; in pl35x_nand_attach_chip()
957 plnand->addr_cycles = 2; in pl35x_nand_attach_chip()
959 if (chip->options & NAND_ROW_ADDR_3) in pl35x_nand_attach_chip()
960 plnand->addr_cycles += 3; in pl35x_nand_attach_chip()
962 plnand->addr_cycles += 2; in pl35x_nand_attach_chip()
964 switch (chip->ecc.engine_type) { in pl35x_nand_attach_chip()
967 chip->bbt_td = &bbt_main_descr; in pl35x_nand_attach_chip()
968 chip->bbt_md = &bbt_mirror_descr; in pl35x_nand_attach_chip()
979 dev_err(nfc->dev, "Unsupported ECC mode: %d\n", in pl35x_nand_attach_chip()
980 chip->ecc.engine_type); in pl35x_nand_attach_chip()
981 return -EINVAL; in pl35x_nand_attach_chip()
1001 nfc->conf_regs + PL35X_SMC_MEMC_CFG_CLR); in pl35x_nand_reset_state()
1003 /* Set default bus width to 8-bit */ in pl35x_nand_reset_state()
1008 /* Ensure the ECC controller is bypassed by default */ in pl35x_nand_reset_state()
1014 * Configure the commands that the ECC block uses to detect the in pl35x_nand_reset_state()
1021 nfc->conf_regs + PL35X_SMC_ECC_CMD1); in pl35x_nand_reset_state()
1026 nfc->conf_regs + PL35X_SMC_ECC_CMD2); in pl35x_nand_reset_state()
1039 plnand = devm_kzalloc(nfc->dev, sizeof(*plnand), GFP_KERNEL); in pl35x_nand_chip_init()
1041 return -ENOMEM; in pl35x_nand_chip_init()
1048 dev_err(nfc->dev, "Wrong CS %d\n", cs); in pl35x_nand_chip_init()
1049 return -EINVAL; in pl35x_nand_chip_init()
1052 if (test_and_set_bit(cs, &nfc->assigned_cs)) { in pl35x_nand_chip_init()
1053 dev_err(nfc->dev, "Already assigned CS %d\n", cs); in pl35x_nand_chip_init()
1054 return -EINVAL; in pl35x_nand_chip_init()
1057 plnand->cs = cs; in pl35x_nand_chip_init()
1059 chip = &plnand->chip; in pl35x_nand_chip_init()
1060 chip->options = NAND_BUSWIDTH_AUTO | NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE; in pl35x_nand_chip_init()
1061 chip->bbt_options = NAND_BBT_USE_FLASH; in pl35x_nand_chip_init()
1062 chip->controller = &nfc->controller; in pl35x_nand_chip_init()
1064 mtd->dev.parent = nfc->dev; in pl35x_nand_chip_init()
1066 if (!mtd->name) { in pl35x_nand_chip_init()
1067 mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL, in pl35x_nand_chip_init()
1069 if (!mtd->name) { in pl35x_nand_chip_init()
1070 dev_err(nfc->dev, "Failed to allocate mtd->name\n"); in pl35x_nand_chip_init()
1071 return -ENOMEM; in pl35x_nand_chip_init()
1085 list_add_tail(&plnand->node, &nfc->chips); in pl35x_nand_chip_init()
1096 list_for_each_entry_safe(plnand, tmp, &nfc->chips, node) { in pl35x_nand_chips_cleanup()
1097 chip = &plnand->chip; in pl35x_nand_chips_cleanup()
1101 list_del(&plnand->node); in pl35x_nand_chips_cleanup()
1107 struct device_node *np = nfc->dev->of_node, *nand_np; in pl35x_nand_chips_init()
1112 dev_err(nfc->dev, "Incorrect number of NAND chips (%d)\n", in pl35x_nand_chips_init()
1114 return -EINVAL; in pl35x_nand_chips_init()
1131 struct device *smc_dev = pdev->dev.parent; in pl35x_nand_probe()
1136 nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL); in pl35x_nand_probe()
1138 return -ENOMEM; in pl35x_nand_probe()
1140 nfc->dev = &pdev->dev; in pl35x_nand_probe()
1141 nand_controller_init(&nfc->controller); in pl35x_nand_probe()
1142 nfc->controller.ops = &pl35x_nandc_ops; in pl35x_nand_probe()
1143 INIT_LIST_HEAD(&nfc->chips); in pl35x_nand_probe()
1145 nfc->conf_regs = devm_ioremap_resource(&smc_amba->dev, &smc_amba->res); in pl35x_nand_probe()
1146 if (IS_ERR(nfc->conf_regs)) in pl35x_nand_probe()
1147 return PTR_ERR(nfc->conf_regs); in pl35x_nand_probe()
1149 nfc->io_regs = devm_platform_ioremap_resource(pdev, 0); in pl35x_nand_probe()
1150 if (IS_ERR(nfc->io_regs)) in pl35x_nand_probe()
1151 return PTR_ERR(nfc->io_regs); in pl35x_nand_probe()
1176 { .compatible = "arm,pl353-nand-r2p1" },