Lines Matching +full:codeword +full:- +full:by +full:- +full:codeword
1 // SPDX-License-Identifier: GPL-2.0-only
9 #include <linux/dma-mapping.h>
56 /* dummy register offsets, used by write_reg_dma */
173 * the driver calls the chunks 'step' or 'codeword' interchangeably
183 /* we read at most 3 registers per codeword scan */
186 /* ECC modes supported by the controller */
207 #define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
210 #define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset))
214 ((chip)->reg_read_dma + \
215 ((u8 *)(vaddr) - (u8 *)(chip)->reg_read_buf))
234 * Erased codeword status is being used two times in single transfer so this
235 * flag will determine the current value of erased codeword status register
244 * @bam_ce - the array of BAM command elements
245 * @cmd_sgl - sgl for NAND BAM command pipe
246 * @data_sgl - sgl for NAND BAM consumer/producer pipe
247 * @last_data_desc - last DMA desc in data channel (tx/rx).
248 * @last_cmd_desc - last DMA desc in command channel.
249 * @txn_done - completion for NAND transfer.
250 * @bam_ce_pos - the index in bam_ce which is available for next sgl
251 * @bam_ce_start - the index in bam_ce which marks the start position ce
254 * @cmd_sgl_pos - current index in command sgl.
255 * @cmd_sgl_start - start index in command sgl.
256 * @tx_sgl_pos - current index in data sgl for tx.
257 * @tx_sgl_start - start index in data sgl for tx.
258 * @rx_sgl_pos - current index in data sgl for rx.
259 * @rx_sgl_start - start index in data sgl for rx.
260 * @wait_second_completion - wait for second DMA desc completion before making
283 * @dma_desc - low level DMA engine descriptor
284 * @list - list for desc_info
286 * @adm_sgl - sgl which will be used for single sgl dma descriptor. Only used by
288 * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM
289 * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM
290 * @dir - DMA transfer direction
373 * by upper layers directly
380 * @buf_size/count/start: markers for chip->legacy.read_buf/write_buf
409 /* will be used only by QPIC for BAM DMA */
416 /* will be used only by EBI2 for ADM DMA */
448 * by ECC (value in pages)
450 * by ECC (value in pages)
491 * protected by ECC
494 * @cw_size: the number of bytes in a single step/codeword
497 * @cw_data: the number of bytes within a codeword protected
498 * by ECC
499 * @ecc_bytes_hw: ECC bytes used by controller hardware for this
506 * ecc/non-ecc mode for the current nand flash
511 * @codeword_fixup: keep track of the current layout used by
550 * @ecc_modes - ecc mode for NAND
551 * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset
552 * @is_bam - whether NAND controller is using BAM
553 * @is_qpic - whether NAND CTRL is part of qpic IP
554 * @qpic_v2 - flag to indicate QPIC IP version 2
555 * @use_codeword_fixup - whether NAND has different layout for boot partitions
569 struct bam_transaction *bam_txn = nandc->bam_txn; in free_bam_transaction()
571 devm_kfree(nandc->dev, bam_txn); in free_bam_transaction()
580 unsigned int num_cw = nandc->max_cwperpage; in alloc_bam_transaction()
585 ((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) + in alloc_bam_transaction()
586 (sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) + in alloc_bam_transaction()
587 (sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL)); in alloc_bam_transaction()
589 bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL); in alloc_bam_transaction()
596 bam_txn->bam_ce = bam_txn_buf; in alloc_bam_transaction()
598 sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw; in alloc_bam_transaction()
600 bam_txn->cmd_sgl = bam_txn_buf; in alloc_bam_transaction()
602 sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw; in alloc_bam_transaction()
604 bam_txn->data_sgl = bam_txn_buf; in alloc_bam_transaction()
606 init_completion(&bam_txn->txn_done); in alloc_bam_transaction()
614 struct bam_transaction *bam_txn = nandc->bam_txn; in clear_bam_transaction()
616 if (!nandc->props->is_bam) in clear_bam_transaction()
619 bam_txn->bam_ce_pos = 0; in clear_bam_transaction()
620 bam_txn->bam_ce_start = 0; in clear_bam_transaction()
621 bam_txn->cmd_sgl_pos = 0; in clear_bam_transaction()
622 bam_txn->cmd_sgl_start = 0; in clear_bam_transaction()
623 bam_txn->tx_sgl_pos = 0; in clear_bam_transaction()
624 bam_txn->tx_sgl_start = 0; in clear_bam_transaction()
625 bam_txn->rx_sgl_pos = 0; in clear_bam_transaction()
626 bam_txn->rx_sgl_start = 0; in clear_bam_transaction()
627 bam_txn->last_data_desc = NULL; in clear_bam_transaction()
628 bam_txn->wait_second_completion = false; in clear_bam_transaction()
630 sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * in clear_bam_transaction()
632 sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage * in clear_bam_transaction()
635 reinit_completion(&bam_txn->txn_done); in clear_bam_transaction()
650 if (bam_txn->wait_second_completion) in qpic_bam_dma_done()
651 bam_txn->wait_second_completion = false; in qpic_bam_dma_done()
653 complete(&bam_txn->txn_done); in qpic_bam_dma_done()
664 return container_of(chip->controller, struct qcom_nand_controller, in get_qcom_nand_controller()
670 return ioread32(nandc->base + offset); in nandc_read()
676 iowrite32(val, nandc->base + offset); in nandc_write()
682 if (!nandc->props->is_bam) in nandc_read_buffer_sync()
686 dma_sync_single_for_cpu(nandc->dev, nandc->reg_read_dma, in nandc_read_buffer_sync()
688 sizeof(*nandc->reg_read_buf), in nandc_read_buffer_sync()
691 dma_sync_single_for_device(nandc->dev, nandc->reg_read_dma, in nandc_read_buffer_sync()
693 sizeof(*nandc->reg_read_buf), in nandc_read_buffer_sync()
701 return ®s->cmd; in offset_to_nandc_reg()
703 return ®s->addr0; in offset_to_nandc_reg()
705 return ®s->addr1; in offset_to_nandc_reg()
707 return ®s->chip_sel; in offset_to_nandc_reg()
709 return ®s->exec; in offset_to_nandc_reg()
711 return ®s->clrflashstatus; in offset_to_nandc_reg()
713 return ®s->cfg0; in offset_to_nandc_reg()
715 return ®s->cfg1; in offset_to_nandc_reg()
717 return ®s->ecc_bch_cfg; in offset_to_nandc_reg()
719 return ®s->clrreadstatus; in offset_to_nandc_reg()
721 return ®s->cmd1; in offset_to_nandc_reg()
723 return ®s->orig_cmd1; in offset_to_nandc_reg()
725 return ®s->vld; in offset_to_nandc_reg()
727 return ®s->orig_vld; in offset_to_nandc_reg()
729 return ®s->ecc_buf_cfg; in offset_to_nandc_reg()
731 return ®s->read_location0; in offset_to_nandc_reg()
733 return ®s->read_location1; in offset_to_nandc_reg()
735 return ®s->read_location2; in offset_to_nandc_reg()
737 return ®s->read_location3; in offset_to_nandc_reg()
739 return ®s->read_location_last0; in offset_to_nandc_reg()
741 return ®s->read_location_last1; in offset_to_nandc_reg()
743 return ®s->read_location_last2; in offset_to_nandc_reg()
745 return ®s->read_location_last3; in offset_to_nandc_reg()
755 struct nandc_regs *regs = nandc->regs; in nandc_set_reg()
767 return cw == (ecc->steps - 1); in qcom_nandc_is_last_cw()
775 struct nand_ecc_ctrl *ecc = &chip->ecc; in nandc_set_read_loc()
778 if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) in nandc_set_read_loc()
783 if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) in nandc_set_read_loc()
794 struct nand_chip *chip = &host->chip; in set_address()
796 if (chip->options & NAND_BUSWIDTH_16) in set_address()
813 struct nand_chip *chip = &host->chip; in update_rw_regs()
818 if (host->use_ecc) in update_rw_regs()
826 if (host->use_ecc) { in update_rw_regs()
827 cfg0 = (host->cfg0 & ~(7U << CW_PER_PAGE)) | in update_rw_regs()
828 (num_cw - 1) << CW_PER_PAGE; in update_rw_regs()
830 cfg1 = host->cfg1; in update_rw_regs()
831 ecc_bch_cfg = host->ecc_bch_cfg; in update_rw_regs()
833 cfg0 = (host->cfg0_raw & ~(7U << CW_PER_PAGE)) | in update_rw_regs()
834 (num_cw - 1) << CW_PER_PAGE; in update_rw_regs()
836 cfg1 = host->cfg1_raw; in update_rw_regs()
844 if (!nandc->props->qpic_v2) in update_rw_regs()
845 nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg); in update_rw_regs()
846 nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus); in update_rw_regs()
847 nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus); in update_rw_regs()
851 nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ? in update_rw_regs()
852 host->cw_data : host->cw_size, 1); in update_rw_regs()
868 struct bam_transaction *bam_txn = nandc->bam_txn; in prepare_bam_async_desc()
874 return -ENOMEM; in prepare_bam_async_desc()
876 if (chan == nandc->cmd_chan) { in prepare_bam_async_desc()
877 sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start]; in prepare_bam_async_desc()
878 sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start; in prepare_bam_async_desc()
879 bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos; in prepare_bam_async_desc()
881 desc->dir = DMA_TO_DEVICE; in prepare_bam_async_desc()
882 } else if (chan == nandc->tx_chan) { in prepare_bam_async_desc()
883 sgl = &bam_txn->data_sgl[bam_txn->tx_sgl_start]; in prepare_bam_async_desc()
884 sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start; in prepare_bam_async_desc()
885 bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos; in prepare_bam_async_desc()
887 desc->dir = DMA_TO_DEVICE; in prepare_bam_async_desc()
889 sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start]; in prepare_bam_async_desc()
890 sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start; in prepare_bam_async_desc()
891 bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos; in prepare_bam_async_desc()
893 desc->dir = DMA_FROM_DEVICE; in prepare_bam_async_desc()
896 sg_mark_end(sgl + sgl_cnt - 1); in prepare_bam_async_desc()
897 ret = dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir); in prepare_bam_async_desc()
899 dev_err(nandc->dev, "failure in mapping desc\n"); in prepare_bam_async_desc()
901 return -ENOMEM; in prepare_bam_async_desc()
904 desc->sgl_cnt = sgl_cnt; in prepare_bam_async_desc()
905 desc->bam_sgl = sgl; in prepare_bam_async_desc()
911 dev_err(nandc->dev, "failure in prep desc\n"); in prepare_bam_async_desc()
912 dma_unmap_sg(nandc->dev, sgl, sgl_cnt, desc->dir); in prepare_bam_async_desc()
914 return -EINVAL; in prepare_bam_async_desc()
917 desc->dma_desc = dma_desc; in prepare_bam_async_desc()
920 if (chan == nandc->cmd_chan) in prepare_bam_async_desc()
921 bam_txn->last_cmd_desc = dma_desc; in prepare_bam_async_desc()
923 bam_txn->last_data_desc = dma_desc; in prepare_bam_async_desc()
925 list_add_tail(&desc->node, &nandc->desc_list); in prepare_bam_async_desc()
946 struct bam_transaction *bam_txn = nandc->bam_txn; in prep_bam_dma_desc_cmd()
948 bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos]; in prep_bam_dma_desc_cmd()
965 bam_txn->bam_ce_pos += size; in prep_bam_dma_desc_cmd()
969 bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start]; in prep_bam_dma_desc_cmd()
970 bam_ce_size = (bam_txn->bam_ce_pos - in prep_bam_dma_desc_cmd()
971 bam_txn->bam_ce_start) * in prep_bam_dma_desc_cmd()
973 sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos], in prep_bam_dma_desc_cmd()
975 bam_txn->cmd_sgl_pos++; in prep_bam_dma_desc_cmd()
976 bam_txn->bam_ce_start = bam_txn->bam_ce_pos; in prep_bam_dma_desc_cmd()
979 ret = prepare_bam_async_desc(nandc, nandc->cmd_chan, in prep_bam_dma_desc_cmd()
999 struct bam_transaction *bam_txn = nandc->bam_txn; in prep_bam_dma_desc_data()
1002 sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos], in prep_bam_dma_desc_data()
1004 bam_txn->rx_sgl_pos++; in prep_bam_dma_desc_data()
1006 sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos], in prep_bam_dma_desc_data()
1008 bam_txn->tx_sgl_pos++; in prep_bam_dma_desc_data()
1015 ret = prepare_bam_async_desc(nandc, nandc->tx_chan, in prep_bam_dma_desc_data()
1039 return -ENOMEM; in prep_adm_dma_desc()
1041 sgl = &desc->adm_sgl; in prep_adm_dma_desc()
1047 desc->dir = DMA_FROM_DEVICE; in prep_adm_dma_desc()
1050 desc->dir = DMA_TO_DEVICE; in prep_adm_dma_desc()
1053 ret = dma_map_sg(nandc->dev, sgl, 1, desc->dir); in prep_adm_dma_desc()
1055 ret = -ENOMEM; in prep_adm_dma_desc()
1064 slave_conf.src_addr = nandc->base_dma + reg_off; in prep_adm_dma_desc()
1065 if (nandc->data_crci) { in prep_adm_dma_desc()
1066 periph_conf.crci = nandc->data_crci; in prep_adm_dma_desc()
1072 slave_conf.dst_addr = nandc->base_dma + reg_off; in prep_adm_dma_desc()
1073 if (nandc->cmd_crci) { in prep_adm_dma_desc()
1074 periph_conf.crci = nandc->cmd_crci; in prep_adm_dma_desc()
1080 ret = dmaengine_slave_config(nandc->chan, &slave_conf); in prep_adm_dma_desc()
1082 dev_err(nandc->dev, "failed to configure dma channel\n"); in prep_adm_dma_desc()
1086 dma_desc = dmaengine_prep_slave_sg(nandc->chan, sgl, 1, dir_eng, 0); in prep_adm_dma_desc()
1088 dev_err(nandc->dev, "failed to prepare desc\n"); in prep_adm_dma_desc()
1089 ret = -EINVAL; in prep_adm_dma_desc()
1093 desc->dma_desc = dma_desc; in prep_adm_dma_desc()
1095 list_add_tail(&desc->node, &nandc->desc_list); in prep_adm_dma_desc()
1118 vaddr = nandc->reg_read_buf + nandc->reg_read_pos; in read_reg_dma()
1119 nandc->reg_read_pos += num_regs; in read_reg_dma()
1124 if (nandc->props->is_bam) in read_reg_dma()
1147 struct nandc_regs *regs = nandc->regs; in write_reg_dma()
1154 vaddr = ®s->erased_cw_detect_cfg_set; in write_reg_dma()
1156 vaddr = ®s->erased_cw_detect_cfg_clr; in write_reg_dma()
1168 if (nandc->props->is_bam) in write_reg_dma()
1191 if (nandc->props->is_bam) in read_data_dma()
1209 if (nandc->props->is_bam) in write_data_dma()
1225 if (!nandc->props->qpic_v2) in config_nand_page_read()
1234 * before reading each codeword in NAND page.
1240 struct nand_ecc_ctrl *ecc = &chip->ecc; in config_nand_cw_read()
1244 if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) in config_nand_cw_read()
1247 if (nandc->props->is_bam) in config_nand_cw_read()
1264 * single codeword in page
1284 if (!nandc->props->qpic_v2) in config_nand_page_write()
1291 * before writing each codeword in NAND page.
1311 struct bam_transaction *bam_txn = nandc->bam_txn; in submit_descs()
1314 if (nandc->props->is_bam) { in submit_descs()
1315 if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) { in submit_descs()
1316 ret = prepare_bam_async_desc(nandc, nandc->rx_chan, 0); in submit_descs()
1321 if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) { in submit_descs()
1322 ret = prepare_bam_async_desc(nandc, nandc->tx_chan, in submit_descs()
1328 if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) { in submit_descs()
1329 ret = prepare_bam_async_desc(nandc, nandc->cmd_chan, in submit_descs()
1336 list_for_each_entry(desc, &nandc->desc_list, node) in submit_descs()
1337 cookie = dmaengine_submit(desc->dma_desc); in submit_descs()
1339 if (nandc->props->is_bam) { in submit_descs()
1340 bam_txn->last_cmd_desc->callback = qpic_bam_dma_done; in submit_descs()
1341 bam_txn->last_cmd_desc->callback_param = bam_txn; in submit_descs()
1342 if (bam_txn->last_data_desc) { in submit_descs()
1343 bam_txn->last_data_desc->callback = qpic_bam_dma_done; in submit_descs()
1344 bam_txn->last_data_desc->callback_param = bam_txn; in submit_descs()
1345 bam_txn->wait_second_completion = true; in submit_descs()
1348 dma_async_issue_pending(nandc->tx_chan); in submit_descs()
1349 dma_async_issue_pending(nandc->rx_chan); in submit_descs()
1350 dma_async_issue_pending(nandc->cmd_chan); in submit_descs()
1352 if (!wait_for_completion_timeout(&bam_txn->txn_done, in submit_descs()
1354 ret = -ETIMEDOUT; in submit_descs()
1356 if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE) in submit_descs()
1357 ret = -ETIMEDOUT; in submit_descs()
1362 * Unmap the dma sg_list and free the desc allocated by both in submit_descs()
1365 list_for_each_entry_safe(desc, n, &nandc->desc_list, node) { in submit_descs()
1366 list_del(&desc->node); in submit_descs()
1368 if (nandc->props->is_bam) in submit_descs()
1369 dma_unmap_sg(nandc->dev, desc->bam_sgl, in submit_descs()
1370 desc->sgl_cnt, desc->dir); in submit_descs()
1372 dma_unmap_sg(nandc->dev, &desc->adm_sgl, 1, in submit_descs()
1373 desc->dir); in submit_descs()
1384 nandc->reg_read_pos = 0; in clear_read_regs()
1393 * but it notifies that it is an erased CW by placing special characters at
1396 * verify if the page is erased or not, and fix up the page for RS ECC by
1405 * is erased by looking for 0x54s at offsets 3 and 175 from the in erased_chunk_check_and_fixup()
1406 * beginning of each codeword in erased_chunk_check_and_fixup()
1442 /* reads back FLASH_STATUS register set by the controller */
1445 struct nand_chip *chip = &host->chip; in check_flash_errors()
1452 u32 flash = le32_to_cpu(nandc->reg_read_buf[i]); in check_flash_errors()
1455 return -EIO; in check_flash_errors()
1461 /* performs raw read for one codeword */
1468 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_read_cw_raw()
1474 nandc->buf_count = 0; in qcom_nandc_read_cw_raw()
1475 nandc->buf_start = 0; in qcom_nandc_read_cw_raw()
1477 host->use_ecc = false; in qcom_nandc_read_cw_raw()
1479 if (nandc->props->qpic_v2) in qcom_nandc_read_cw_raw()
1480 raw_cw = ecc->steps - 1; in qcom_nandc_read_cw_raw()
1483 set_address(host, host->cw_size * cw, page); in qcom_nandc_read_cw_raw()
1487 data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); in qcom_nandc_read_cw_raw()
1488 oob_size1 = host->bbm_size; in qcom_nandc_read_cw_raw()
1490 if (qcom_nandc_is_last_cw(ecc, cw) && !host->codeword_fixup) { in qcom_nandc_read_cw_raw()
1491 data_size2 = ecc->size - data_size1 - in qcom_nandc_read_cw_raw()
1492 ((ecc->steps - 1) * 4); in qcom_nandc_read_cw_raw()
1493 oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw + in qcom_nandc_read_cw_raw()
1494 host->spare_bytes; in qcom_nandc_read_cw_raw()
1496 data_size2 = host->cw_data - data_size1; in qcom_nandc_read_cw_raw()
1497 oob_size2 = host->ecc_bytes_hw + host->spare_bytes; in qcom_nandc_read_cw_raw()
1500 if (nandc->props->is_bam) { in qcom_nandc_read_cw_raw()
1528 dev_err(nandc->dev, "failure to read raw cw %d\n", cw); in qcom_nandc_read_cw_raw()
1539 * equal to the ecc->strength for each CW.
1542 * top-level API can be called with only data buf or OOB buf so use
1543 * chip->data_buf if data buf is null and chip->oob_poi if oob buf
1555 struct nand_chip *chip = &host->chip; in check_for_erased_page()
1557 struct nand_ecc_ctrl *ecc = &chip->ecc; in check_for_erased_page()
1566 oob_buf = chip->oob_poi; in check_for_erased_page()
1569 for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { in check_for_erased_page()
1570 if (qcom_nandc_is_last_cw(ecc, cw) && !host->codeword_fixup) { in check_for_erased_page()
1571 data_size = ecc->size - ((ecc->steps - 1) * 4); in check_for_erased_page()
1572 oob_size = (ecc->steps * 4) + host->ecc_bytes_hw; in check_for_erased_page()
1574 data_size = host->cw_data; in check_for_erased_page()
1575 oob_size = host->ecc_bytes_hw; in check_for_erased_page()
1579 cw_data_buf = data_buf + (cw * host->cw_data); in check_for_erased_page()
1580 cw_oob_buf = oob_buf + (cw * ecc->bytes); in check_for_erased_page()
1589 * as not-erased by HW because of a few bitflips in check_for_erased_page()
1592 cw_oob_buf + host->bbm_size, in check_for_erased_page()
1594 0, ecc->strength); in check_for_erased_page()
1596 mtd->ecc_stats.failed++; in check_for_erased_page()
1598 mtd->ecc_stats.corrected += ret; in check_for_erased_page()
1607 * reads back status registers set by the controller to notify page read
1608 * errors. this is equivalent to what 'ecc->correct()' would do.
1613 struct nand_chip *chip = &host->chip; in parse_read_errors()
1616 struct nand_ecc_ctrl *ecc = &chip->ecc; in parse_read_errors()
1623 buf = (struct read_stats *)nandc->reg_read_buf; in parse_read_errors()
1626 for (i = 0; i < ecc->steps; i++, buf++) { in parse_read_errors()
1631 data_len = ecc->size - ((ecc->steps - 1) << 2); in parse_read_errors()
1632 oob_len = ecc->steps << 2; in parse_read_errors()
1634 data_len = host->cw_data; in parse_read_errors()
1638 flash = le32_to_cpu(buf->flash); in parse_read_errors()
1639 buffer = le32_to_cpu(buf->buffer); in parse_read_errors()
1640 erased_cw = le32_to_cpu(buf->erased_cw); in parse_read_errors()
1643 * Check ECC failure for each codeword. ECC failure can in parse_read_errors()
1647 * 2. If this codeword contains all 0xff for which erased in parse_read_errors()
1648 * codeword detection check will be done. in parse_read_errors()
1652 * For BCH ECC, ignore erased codeword errors, if in parse_read_errors()
1655 if (host->bch_enabled) { in parse_read_errors()
1658 * For RS ECC, HW reports the erased CW by placing in parse_read_errors()
1674 * device failure, etc.) happened for this codeword and in parse_read_errors()
1688 mtd->ecc_stats.corrected += stat; in parse_read_errors()
1695 oob_buf += oob_len + ecc->bytes; in parse_read_errors()
1699 return -EIO; in parse_read_errors()
1710 * helper to perform the actual page read operation, used by ecc->read_page(),
1711 * ecc->read_oob()
1716 struct nand_chip *chip = &host->chip; in read_page_ecc()
1718 struct nand_ecc_ctrl *ecc = &chip->ecc; in read_page_ecc()
1724 /* queue cmd descs for each codeword */ in read_page_ecc()
1725 for (i = 0; i < ecc->steps; i++) { in read_page_ecc()
1728 if (qcom_nandc_is_last_cw(ecc, i) && !host->codeword_fixup) { in read_page_ecc()
1729 data_size = ecc->size - ((ecc->steps - 1) << 2); in read_page_ecc()
1730 oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + in read_page_ecc()
1731 host->spare_bytes; in read_page_ecc()
1733 data_size = host->cw_data; in read_page_ecc()
1734 oob_size = host->ecc_bytes_hw + host->spare_bytes; in read_page_ecc()
1737 if (nandc->props->is_bam) { in read_page_ecc()
1766 for (j = 0; j < host->bbm_size; j++) in read_page_ecc()
1781 dev_err(nandc->dev, "failure to read page/oob\n"); in read_page_ecc()
1789 * a helper that copies the last step/codeword of a page (containing free oob)
1794 struct nand_chip *chip = &host->chip; in copy_last_cw()
1796 struct nand_ecc_ctrl *ecc = &chip->ecc; in copy_last_cw()
1802 size = host->use_ecc ? host->cw_data : host->cw_size; in copy_last_cw()
1805 memset(nandc->data_buffer, 0xff, size); in copy_last_cw()
1807 set_address(host, host->cw_size * (ecc->steps - 1), page); in copy_last_cw()
1808 update_rw_regs(host, 1, true, ecc->steps - 1); in copy_last_cw()
1810 config_nand_single_cw_page_read(chip, host->use_ecc, ecc->steps - 1); in copy_last_cw()
1812 read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); in copy_last_cw()
1816 dev_err(nandc->dev, "failed to copy last codeword\n"); in copy_last_cw()
1828 * Since the frequent access will be to the non-boot partitions like rootfs, in qcom_nandc_is_boot_partition()
1829 * optimize the page check by: in qcom_nandc_is_boot_partition()
1836 boot_partition = &host->boot_partitions[host->nr_boot_partitions - 1]; in qcom_nandc_is_boot_partition()
1837 start = boot_partition->page_offset; in qcom_nandc_is_boot_partition()
1838 end = start + boot_partition->page_size; in qcom_nandc_is_boot_partition()
1848 /* Check the other boot partitions starting from the second-last partition */ in qcom_nandc_is_boot_partition()
1849 for (i = host->nr_boot_partitions - 2; i >= 0; i--) { in qcom_nandc_is_boot_partition()
1850 boot_partition = &host->boot_partitions[i]; in qcom_nandc_is_boot_partition()
1851 start = boot_partition->page_offset; in qcom_nandc_is_boot_partition()
1852 end = start + boot_partition->page_size; in qcom_nandc_is_boot_partition()
1866 if (codeword_fixup == host->codeword_fixup) in qcom_nandc_codeword_fixup()
1869 host->codeword_fixup = codeword_fixup; in qcom_nandc_codeword_fixup()
1871 host->cw_data = codeword_fixup ? 512 : 516; in qcom_nandc_codeword_fixup()
1872 host->spare_bytes = host->cw_size - host->ecc_bytes_hw - in qcom_nandc_codeword_fixup()
1873 host->bbm_size - host->cw_data; in qcom_nandc_codeword_fixup()
1875 host->cfg0 &= ~(SPARE_SIZE_BYTES_MASK | UD_SIZE_BYTES_MASK); in qcom_nandc_codeword_fixup()
1876 host->cfg0 |= host->spare_bytes << SPARE_SIZE_BYTES | in qcom_nandc_codeword_fixup()
1877 host->cw_data << UD_SIZE_BYTES; in qcom_nandc_codeword_fixup()
1879 host->ecc_bch_cfg &= ~ECC_NUM_DATA_BYTES_MASK; in qcom_nandc_codeword_fixup()
1880 host->ecc_bch_cfg |= host->cw_data << ECC_NUM_DATA_BYTES; in qcom_nandc_codeword_fixup()
1881 host->ecc_buf_cfg = (host->cw_data - 1) << NUM_STEPS; in qcom_nandc_codeword_fixup()
1884 /* implements ecc->read_page() */
1890 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_read_page()
1893 if (host->nr_boot_partitions) in qcom_nandc_read_page()
1897 nandc->buf_count = 0; in qcom_nandc_read_page()
1898 nandc->buf_start = 0; in qcom_nandc_read_page()
1899 host->use_ecc = true; in qcom_nandc_read_page()
1902 update_rw_regs(host, ecc->steps, true, 0); in qcom_nandc_read_page()
1905 oob_buf = oob_required ? chip->oob_poi : NULL; in qcom_nandc_read_page()
1912 /* implements ecc->read_page_raw() */
1918 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_read_page_raw()
1920 u8 *data_buf = buf, *oob_buf = chip->oob_poi; in qcom_nandc_read_page_raw()
1922 if (host->nr_boot_partitions) in qcom_nandc_read_page_raw()
1925 for (cw = 0; cw < ecc->steps; cw++) { in qcom_nandc_read_page_raw()
1931 data_buf += host->cw_data; in qcom_nandc_read_page_raw()
1932 oob_buf += ecc->bytes; in qcom_nandc_read_page_raw()
1938 /* implements ecc->read_oob() */
1943 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_read_oob()
1945 if (host->nr_boot_partitions) in qcom_nandc_read_oob()
1951 host->use_ecc = true; in qcom_nandc_read_oob()
1953 update_rw_regs(host, ecc->steps, true, 0); in qcom_nandc_read_oob()
1955 return read_page_ecc(host, NULL, chip->oob_poi, page); in qcom_nandc_read_oob()
1958 /* implements ecc->write_page() */
1964 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_write_page()
1968 if (host->nr_boot_partitions) in qcom_nandc_write_page()
1974 nandc->buf_count = 0; in qcom_nandc_write_page()
1975 nandc->buf_start = 0; in qcom_nandc_write_page()
1980 oob_buf = chip->oob_poi; in qcom_nandc_write_page()
1982 host->use_ecc = true; in qcom_nandc_write_page()
1983 update_rw_regs(host, ecc->steps, false, 0); in qcom_nandc_write_page()
1986 for (i = 0; i < ecc->steps; i++) { in qcom_nandc_write_page()
1989 if (qcom_nandc_is_last_cw(ecc, i) && !host->codeword_fixup) { in qcom_nandc_write_page()
1990 data_size = ecc->size - ((ecc->steps - 1) << 2); in qcom_nandc_write_page()
1991 oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + in qcom_nandc_write_page()
1992 host->spare_bytes; in qcom_nandc_write_page()
1994 data_size = host->cw_data; in qcom_nandc_write_page()
1995 oob_size = ecc->bytes; in qcom_nandc_write_page()
1999 i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0); in qcom_nandc_write_page()
2003 * to oob for the first n - 1 codewords since these oob regions in qcom_nandc_write_page()
2004 * just contain ECC bytes that's written by the controller in qcom_nandc_write_page()
2005 * itself. For the last codeword, we skip the bbm positions and in qcom_nandc_write_page()
2009 oob_buf += host->bbm_size; in qcom_nandc_write_page()
2023 dev_err(nandc->dev, "failure to write page\n"); in qcom_nandc_write_page()
2030 /* implements ecc->write_page_raw() */
2038 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_write_page_raw()
2042 if (host->nr_boot_partitions) in qcom_nandc_write_page_raw()
2050 oob_buf = chip->oob_poi; in qcom_nandc_write_page_raw()
2052 host->use_ecc = false; in qcom_nandc_write_page_raw()
2053 update_rw_regs(host, ecc->steps, false, 0); in qcom_nandc_write_page_raw()
2056 for (i = 0; i < ecc->steps; i++) { in qcom_nandc_write_page_raw()
2060 data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); in qcom_nandc_write_page_raw()
2061 oob_size1 = host->bbm_size; in qcom_nandc_write_page_raw()
2063 if (qcom_nandc_is_last_cw(ecc, i) && !host->codeword_fixup) { in qcom_nandc_write_page_raw()
2064 data_size2 = ecc->size - data_size1 - in qcom_nandc_write_page_raw()
2065 ((ecc->steps - 1) << 2); in qcom_nandc_write_page_raw()
2066 oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + in qcom_nandc_write_page_raw()
2067 host->spare_bytes; in qcom_nandc_write_page_raw()
2069 data_size2 = host->cw_data - data_size1; in qcom_nandc_write_page_raw()
2070 oob_size2 = host->ecc_bytes_hw + host->spare_bytes; in qcom_nandc_write_page_raw()
2096 dev_err(nandc->dev, "failure to write raw page\n"); in qcom_nandc_write_page_raw()
2104 * implements ecc->write_oob()
2106 * the NAND controller cannot write only data or only OOB within a codeword
2107 * since ECC is calculated for the combined codeword. So update the OOB from
2108 * chip->oob_poi, and pad the data area with OxFF before writing.
2115 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_write_oob()
2116 u8 *oob = chip->oob_poi; in qcom_nandc_write_oob()
2120 if (host->nr_boot_partitions) in qcom_nandc_write_oob()
2123 host->use_ecc = true; in qcom_nandc_write_oob()
2126 /* calculate the data and oob size for the last codeword/step */ in qcom_nandc_write_oob()
2127 data_size = ecc->size - ((ecc->steps - 1) << 2); in qcom_nandc_write_oob()
2128 oob_size = mtd->oobavail; in qcom_nandc_write_oob()
2130 memset(nandc->data_buffer, 0xff, host->cw_data); in qcom_nandc_write_oob()
2131 /* override new oob content to last codeword */ in qcom_nandc_write_oob()
2132 mtd_ooblayout_get_databytes(mtd, nandc->data_buffer + data_size, oob, in qcom_nandc_write_oob()
2133 0, mtd->oobavail); in qcom_nandc_write_oob()
2135 set_address(host, host->cw_size * (ecc->steps - 1), page); in qcom_nandc_write_oob()
2140 nandc->data_buffer, data_size + oob_size, 0); in qcom_nandc_write_oob()
2145 dev_err(nandc->dev, "failure to write oob\n"); in qcom_nandc_write_oob()
2157 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_block_bad()
2160 page = (int)(ofs >> chip->page_shift) & chip->pagemask; in qcom_nandc_block_bad()
2164 * the beginning of the last codeword, we don't care about reading ecc in qcom_nandc_block_bad()
2165 * portion of oob. we just want the first few bytes from this codeword in qcom_nandc_block_bad()
2168 host->use_ecc = false; in qcom_nandc_block_bad()
2176 dev_warn(nandc->dev, "error when trying to read BBM\n"); in qcom_nandc_block_bad()
2180 bbpos = mtd->writesize - host->cw_size * (ecc->steps - 1); in qcom_nandc_block_bad()
2182 bad = nandc->data_buffer[bbpos] != 0xff; in qcom_nandc_block_bad()
2184 if (chip->options & NAND_BUSWIDTH_16) in qcom_nandc_block_bad()
2185 bad = bad || (nandc->data_buffer[bbpos + 1] != 0xff); in qcom_nandc_block_bad()
2194 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nandc_block_markbad()
2201 * to mark the BBM as bad, we flash the entire last codeword with 0s. in qcom_nandc_block_markbad()
2202 * we don't care about the rest of the content in the codeword since in qcom_nandc_block_markbad()
2205 memset(nandc->data_buffer, 0x00, host->cw_size); in qcom_nandc_block_markbad()
2207 page = (int)(ofs >> chip->page_shift) & chip->pagemask; in qcom_nandc_block_markbad()
2210 host->use_ecc = false; in qcom_nandc_block_markbad()
2211 set_address(host, host->cw_size * (ecc->steps - 1), page); in qcom_nandc_block_markbad()
2212 update_rw_regs(host, 1, false, ecc->steps - 1); in qcom_nandc_block_markbad()
2216 nandc->data_buffer, host->cw_size, 0); in qcom_nandc_block_markbad()
2221 dev_err(nandc->dev, "failure to update BBM\n"); in qcom_nandc_block_markbad()
2233 * |----------------------| |---------------------------------|
2236 * | (516) xx.......yy| | (516-n*4) **(n*4)**xx.......yy|
2238 * |----------------------| |---------------------------------|
2239 * codeword 1,2..n-1 codeword n
2240 * <---(528/532 Bytes)--> <-------(528/532 Bytes)--------->
2252 * the qcom nand controller operates at a sub page/codeword level. each
2253 * codeword is 528 and 532 bytes for 4 bit and 8 bit ECC modes respectively.
2256 * the first n - 1 codewords contains 516 bytes of user data, the remaining
2257 * 12/16 bytes consist of ECC and reserved data. The nth codeword contains
2267 * |------------------------------| |---------------------------------------|
2272 * |------------------------------| |---------------------------------------|
2273 * codeword 1,2..n-1 codeword n
2274 * <-------(528/532 Bytes)------> <-----------(528/532 Bytes)----------->
2282 * size1/size2 = function of codeword size and 'n'
2285 * width) is now accessible. For the first n - 1 codewords, these are dummy Bad
2286 * Block Markers. In the last codeword, this position contains the real BBM
2291 * |-----------| |--------------------|
2296 * |-----------| |--------------------|
2297 * first n - 1 nth OOB region
2310 * dummy/real bad block bytes are grouped as ecc bytes (i.e, ecc->bytes is
2318 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nand_ooblayout_ecc()
2321 return -ERANGE; in qcom_nand_ooblayout_ecc()
2324 oobregion->length = (ecc->bytes * (ecc->steps - 1)) + in qcom_nand_ooblayout_ecc()
2325 host->bbm_size; in qcom_nand_ooblayout_ecc()
2326 oobregion->offset = 0; in qcom_nand_ooblayout_ecc()
2328 oobregion->length = host->ecc_bytes_hw + host->spare_bytes; in qcom_nand_ooblayout_ecc()
2329 oobregion->offset = mtd->oobsize - oobregion->length; in qcom_nand_ooblayout_ecc()
2340 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nand_ooblayout_free()
2343 return -ERANGE; in qcom_nand_ooblayout_free()
2345 oobregion->length = ecc->steps * 4; in qcom_nand_ooblayout_free()
2346 oobregion->offset = ((ecc->steps - 1) * ecc->bytes) + host->bbm_size; in qcom_nand_ooblayout_free()
2369 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_nand_attach_chip()
2376 ecc->size = NANDC_STEP_SIZE; in qcom_nand_attach_chip()
2377 wide_bus = chip->options & NAND_BUSWIDTH_16 ? true : false; in qcom_nand_attach_chip()
2378 cwperpage = mtd->writesize / NANDC_STEP_SIZE; in qcom_nand_attach_chip()
2385 mtd->oobsize - (cwperpage * 4)); in qcom_nand_attach_chip()
2387 dev_err(nandc->dev, "No valid ECC settings possible\n"); in qcom_nand_attach_chip()
2391 if (ecc->strength >= 8) { in qcom_nand_attach_chip()
2393 host->bch_enabled = true; in qcom_nand_attach_chip()
2397 host->ecc_bytes_hw = 14; in qcom_nand_attach_chip()
2398 host->spare_bytes = 0; in qcom_nand_attach_chip()
2399 host->bbm_size = 2; in qcom_nand_attach_chip()
2401 host->ecc_bytes_hw = 13; in qcom_nand_attach_chip()
2402 host->spare_bytes = 2; in qcom_nand_attach_chip()
2403 host->bbm_size = 1; in qcom_nand_attach_chip()
2411 if (nandc->props->ecc_modes & ECC_BCH_4BIT) { in qcom_nand_attach_chip()
2413 host->bch_enabled = true; in qcom_nand_attach_chip()
2417 host->ecc_bytes_hw = 8; in qcom_nand_attach_chip()
2418 host->spare_bytes = 2; in qcom_nand_attach_chip()
2419 host->bbm_size = 2; in qcom_nand_attach_chip()
2421 host->ecc_bytes_hw = 7; in qcom_nand_attach_chip()
2422 host->spare_bytes = 4; in qcom_nand_attach_chip()
2423 host->bbm_size = 1; in qcom_nand_attach_chip()
2427 host->ecc_bytes_hw = 10; in qcom_nand_attach_chip()
2430 host->spare_bytes = 0; in qcom_nand_attach_chip()
2431 host->bbm_size = 2; in qcom_nand_attach_chip()
2433 host->spare_bytes = 1; in qcom_nand_attach_chip()
2434 host->bbm_size = 1; in qcom_nand_attach_chip()
2440 * we consider ecc->bytes as the sum of all the non-data content in a in qcom_nand_attach_chip()
2445 ecc->bytes = host->ecc_bytes_hw + host->spare_bytes + host->bbm_size; in qcom_nand_attach_chip()
2447 ecc->read_page = qcom_nandc_read_page; in qcom_nand_attach_chip()
2448 ecc->read_page_raw = qcom_nandc_read_page_raw; in qcom_nand_attach_chip()
2449 ecc->read_oob = qcom_nandc_read_oob; in qcom_nand_attach_chip()
2450 ecc->write_page = qcom_nandc_write_page; in qcom_nand_attach_chip()
2451 ecc->write_page_raw = qcom_nandc_write_page_raw; in qcom_nand_attach_chip()
2452 ecc->write_oob = qcom_nandc_write_oob; in qcom_nand_attach_chip()
2454 ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in qcom_nand_attach_chip()
2458 if (nandc->props->is_bam) in qcom_nand_attach_chip()
2461 nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage, in qcom_nand_attach_chip()
2465 if (nandc->props->is_bam) { in qcom_nand_attach_chip()
2466 nandc->bam_txn = alloc_bam_transaction(nandc); in qcom_nand_attach_chip()
2467 if (!nandc->bam_txn) { in qcom_nand_attach_chip()
2468 dev_err(nandc->dev, in qcom_nand_attach_chip()
2470 return -ENOMEM; in qcom_nand_attach_chip()
2476 * spare data with ECC too. We protect spare data by default, so we set in qcom_nand_attach_chip()
2479 host->cw_data = 516; in qcom_nand_attach_chip()
2485 host->cw_size = host->cw_data + ecc->bytes; in qcom_nand_attach_chip()
2486 bad_block_byte = mtd->writesize - host->cw_size * (cwperpage - 1) + 1; in qcom_nand_attach_chip()
2488 host->cfg0 = (cwperpage - 1) << CW_PER_PAGE in qcom_nand_attach_chip()
2489 | host->cw_data << UD_SIZE_BYTES in qcom_nand_attach_chip()
2492 | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_RS in qcom_nand_attach_chip()
2495 | host->spare_bytes << SPARE_SIZE_BYTES; in qcom_nand_attach_chip()
2497 host->cfg1 = 7 << NAND_RECOVERY_CYCLES in qcom_nand_attach_chip()
2503 | host->bch_enabled << ENABLE_BCH_ECC; in qcom_nand_attach_chip()
2505 host->cfg0_raw = (cwperpage - 1) << CW_PER_PAGE in qcom_nand_attach_chip()
2506 | host->cw_size << UD_SIZE_BYTES in qcom_nand_attach_chip()
2510 host->cfg1_raw = 7 << NAND_RECOVERY_CYCLES in qcom_nand_attach_chip()
2518 host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE in qcom_nand_attach_chip()
2520 | host->cw_data << ECC_NUM_DATA_BYTES in qcom_nand_attach_chip()
2523 | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_BCH; in qcom_nand_attach_chip()
2525 if (!nandc->props->qpic_v2) in qcom_nand_attach_chip()
2526 host->ecc_buf_cfg = 0x203 << NUM_STEPS; in qcom_nand_attach_chip()
2528 host->clrflashstatus = FS_READY_BSY_N; in qcom_nand_attach_chip()
2529 host->clrreadstatus = 0xc0; in qcom_nand_attach_chip()
2530 nandc->regs->erased_cw_detect_cfg_clr = in qcom_nand_attach_chip()
2532 nandc->regs->erased_cw_detect_cfg_set = in qcom_nand_attach_chip()
2535 dev_dbg(nandc->dev, in qcom_nand_attach_chip()
2537 host->cfg0, host->cfg1, host->ecc_buf_cfg, host->ecc_bch_cfg, in qcom_nand_attach_chip()
2538 host->cw_size, host->cw_data, ecc->strength, ecc->bytes, in qcom_nand_attach_chip()
2559 if (nandc->props->qpic_v2) in qcom_op_cmd_mapping()
2573 q_op->flag = OP_PROGRAM_PAGE; in qcom_op_cmd_mapping()
2574 nandc->exec_opwrite = true; in qcom_op_cmd_mapping()
2578 if (host->use_ecc) in qcom_op_cmd_mapping()
2584 dev_err(nandc->dev, "Opcode not supported: %u\n", opcode); in qcom_op_cmd_mapping()
2585 return -EOPNOTSUPP; in qcom_op_cmd_mapping()
2591 /* NAND framework ->exec_op() hooks and related helpers */
2600 for (op_id = 0; op_id < subop->ninstrs; op_id++) { in qcom_parse_instructions()
2604 instr = &subop->instrs[op_id]; in qcom_parse_instructions()
2606 switch (instr->type) { in qcom_parse_instructions()
2608 ret = qcom_op_cmd_mapping(chip, instr->ctx.cmd.opcode, q_op); in qcom_parse_instructions()
2612 q_op->cmd_reg = ret; in qcom_parse_instructions()
2613 q_op->rdy_delay_ns = instr->delay_ns; in qcom_parse_instructions()
2619 addrs = &instr->ctx.addr.addrs[offset]; in qcom_parse_instructions()
2622 q_op->addr1_reg |= addrs[i] << (i * 8); in qcom_parse_instructions()
2625 q_op->addr2_reg |= addrs[4]; in qcom_parse_instructions()
2627 q_op->rdy_delay_ns = instr->delay_ns; in qcom_parse_instructions()
2631 q_op->data_instr = instr; in qcom_parse_instructions()
2632 q_op->data_instr_idx = op_id; in qcom_parse_instructions()
2633 q_op->rdy_delay_ns = instr->delay_ns; in qcom_parse_instructions()
2636 q_op->rdy_delay_ns = instr->delay_ns; in qcom_parse_instructions()
2640 q_op->rdy_timeout_ms = instr->ctx.waitrdy.timeout_ms; in qcom_parse_instructions()
2641 q_op->rdy_delay_ns = instr->delay_ns; in qcom_parse_instructions()
2669 flash = le32_to_cpu(nandc->reg_read_buf[0]); in qcom_wait_rdy_poll()
2675 dev_err(nandc->dev, "Timeout waiting for device to be ready:0x%08x\n", flash); in qcom_wait_rdy_poll()
2677 return -ETIMEDOUT; in qcom_wait_rdy_poll()
2685 struct nand_ecc_ctrl *ecc = &chip->ecc; in qcom_read_status_exec()
2693 host->status = NAND_STATUS_READY | NAND_STATUS_WP; in qcom_read_status_exec()
2699 num_cw = nandc->exec_opwrite ? ecc->steps : 1; in qcom_read_status_exec()
2700 nandc->exec_opwrite = false; in qcom_read_status_exec()
2702 nandc->buf_count = 0; in qcom_read_status_exec()
2703 nandc->buf_start = 0; in qcom_read_status_exec()
2704 host->use_ecc = false; in qcom_read_status_exec()
2718 dev_err(nandc->dev, "failure in submitting status descriptor\n"); in qcom_read_status_exec()
2725 flash_status = le32_to_cpu(nandc->reg_read_buf[i]); in qcom_read_status_exec()
2728 host->status &= ~NAND_STATUS_WP; in qcom_read_status_exec()
2731 (i == (num_cw - 1) && (flash_status & FS_DEVICE_STS_ERR))) in qcom_read_status_exec()
2732 host->status |= NAND_STATUS_FAIL; in qcom_read_status_exec()
2735 flash_status = host->status; in qcom_read_status_exec()
2739 memcpy(instr->ctx.data.buf.in, &flash_status, len); in qcom_read_status_exec()
2759 nandc->buf_count = 0; in qcom_read_id_type_exec()
2760 nandc->buf_start = 0; in qcom_read_id_type_exec()
2761 host->use_ecc = false; in qcom_read_id_type_exec()
2770 nandc->props->is_bam ? 0 : DM_EN); in qcom_read_id_type_exec()
2781 dev_err(nandc->dev, "failure in submitting read id descriptor\n"); in qcom_read_id_type_exec()
2790 memcpy(instr->ctx.data.buf.in, nandc->reg_read_buf, len); in qcom_read_id_type_exec()
2815 host->cfg0_raw & ~(7 << CW_PER_PAGE)); in qcom_misc_cmd_type_exec()
2816 nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw); in qcom_misc_cmd_type_exec()
2822 nandc->buf_count = 0; in qcom_misc_cmd_type_exec()
2823 nandc->buf_start = 0; in qcom_misc_cmd_type_exec()
2824 host->use_ecc = false; in qcom_misc_cmd_type_exec()
2841 dev_err(nandc->dev, "failure in submitting misc descriptor\n"); in qcom_misc_cmd_type_exec()
2869 nandc->buf_count = 0; in qcom_param_page_type_exec()
2870 nandc->buf_start = 0; in qcom_param_page_type_exec()
2871 host->use_ecc = false; in qcom_param_page_type_exec()
2890 if (!nandc->props->qpic_v2) in qcom_param_page_type_exec()
2894 if (!nandc->props->qpic_v2) { in qcom_param_page_type_exec()
2896 (nandc->vld & ~READ_START_VLD)); in qcom_param_page_type_exec()
2898 (nandc->cmd1 & ~(0xFF << READ_ADDR)) in qcom_param_page_type_exec()
2904 if (!nandc->props->qpic_v2) { in qcom_param_page_type_exec()
2905 nandc_set_reg(chip, NAND_DEV_CMD1_RESTORE, nandc->cmd1); in qcom_param_page_type_exec()
2906 nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); in qcom_param_page_type_exec()
2915 if (!nandc->props->qpic_v2) { in qcom_param_page_type_exec()
2920 nandc->buf_count = len; in qcom_param_page_type_exec()
2921 memset(nandc->data_buffer, 0xff, nandc->buf_count); in qcom_param_page_type_exec()
2925 read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, in qcom_param_page_type_exec()
2926 nandc->buf_count, 0); in qcom_param_page_type_exec()
2929 if (!nandc->props->qpic_v2) { in qcom_param_page_type_exec()
2936 dev_err(nandc->dev, "failure in submitting param page descriptor\n"); in qcom_param_page_type_exec()
2944 memcpy(instr->ctx.data.buf.in, nandc->data_buffer, len); in qcom_param_page_type_exec()
2980 for (op_id = 0; op_id < op->ninstrs; op_id++) { in qcom_check_op()
2981 instr = &op->instrs[op_id]; in qcom_check_op()
2983 switch (instr->type) { in qcom_check_op()
2985 if (instr->ctx.cmd.opcode != NAND_CMD_RESET && in qcom_check_op()
2986 instr->ctx.cmd.opcode != NAND_CMD_READID && in qcom_check_op()
2987 instr->ctx.cmd.opcode != NAND_CMD_PARAM && in qcom_check_op()
2988 instr->ctx.cmd.opcode != NAND_CMD_ERASE1 && in qcom_check_op()
2989 instr->ctx.cmd.opcode != NAND_CMD_ERASE2 && in qcom_check_op()
2990 instr->ctx.cmd.opcode != NAND_CMD_STATUS && in qcom_check_op()
2991 instr->ctx.cmd.opcode != NAND_CMD_PAGEPROG && in qcom_check_op()
2992 instr->ctx.cmd.opcode != NAND_CMD_READ0 && in qcom_check_op()
2993 instr->ctx.cmd.opcode != NAND_CMD_READSTART) in qcom_check_op()
2994 return -EOPNOTSUPP; in qcom_check_op()
3020 if (nandc->props->is_bam) { in qcom_nandc_unalloc()
3021 if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma)) in qcom_nandc_unalloc()
3022 dma_unmap_single(nandc->dev, nandc->reg_read_dma, in qcom_nandc_unalloc()
3024 sizeof(*nandc->reg_read_buf), in qcom_nandc_unalloc()
3027 if (nandc->tx_chan) in qcom_nandc_unalloc()
3028 dma_release_channel(nandc->tx_chan); in qcom_nandc_unalloc()
3030 if (nandc->rx_chan) in qcom_nandc_unalloc()
3031 dma_release_channel(nandc->rx_chan); in qcom_nandc_unalloc()
3033 if (nandc->cmd_chan) in qcom_nandc_unalloc()
3034 dma_release_channel(nandc->cmd_chan); in qcom_nandc_unalloc()
3036 if (nandc->chan) in qcom_nandc_unalloc()
3037 dma_release_channel(nandc->chan); in qcom_nandc_unalloc()
3045 ret = dma_set_coherent_mask(nandc->dev, DMA_BIT_MASK(32)); in qcom_nandc_alloc()
3047 dev_err(nandc->dev, "failed to set DMA mask\n"); in qcom_nandc_alloc()
3053 * data like ID and status, and preforming read-copy-write operations in qcom_nandc_alloc()
3054 * when writing to a codeword partially. 532 is the maximum possible in qcom_nandc_alloc()
3055 * size of a codeword for our nand controller in qcom_nandc_alloc()
3057 nandc->buf_size = 532; in qcom_nandc_alloc()
3059 nandc->data_buffer = devm_kzalloc(nandc->dev, nandc->buf_size, GFP_KERNEL); in qcom_nandc_alloc()
3060 if (!nandc->data_buffer) in qcom_nandc_alloc()
3061 return -ENOMEM; in qcom_nandc_alloc()
3063 nandc->regs = devm_kzalloc(nandc->dev, sizeof(*nandc->regs), GFP_KERNEL); in qcom_nandc_alloc()
3064 if (!nandc->regs) in qcom_nandc_alloc()
3065 return -ENOMEM; in qcom_nandc_alloc()
3067 nandc->reg_read_buf = devm_kcalloc(nandc->dev, MAX_REG_RD, in qcom_nandc_alloc()
3068 sizeof(*nandc->reg_read_buf), in qcom_nandc_alloc()
3070 if (!nandc->reg_read_buf) in qcom_nandc_alloc()
3071 return -ENOMEM; in qcom_nandc_alloc()
3073 if (nandc->props->is_bam) { in qcom_nandc_alloc()
3074 nandc->reg_read_dma = in qcom_nandc_alloc()
3075 dma_map_single(nandc->dev, nandc->reg_read_buf, in qcom_nandc_alloc()
3077 sizeof(*nandc->reg_read_buf), in qcom_nandc_alloc()
3079 if (dma_mapping_error(nandc->dev, nandc->reg_read_dma)) { in qcom_nandc_alloc()
3080 dev_err(nandc->dev, "failed to DMA MAP reg buffer\n"); in qcom_nandc_alloc()
3081 return -EIO; in qcom_nandc_alloc()
3084 nandc->tx_chan = dma_request_chan(nandc->dev, "tx"); in qcom_nandc_alloc()
3085 if (IS_ERR(nandc->tx_chan)) { in qcom_nandc_alloc()
3086 ret = PTR_ERR(nandc->tx_chan); in qcom_nandc_alloc()
3087 nandc->tx_chan = NULL; in qcom_nandc_alloc()
3088 dev_err_probe(nandc->dev, ret, in qcom_nandc_alloc()
3093 nandc->rx_chan = dma_request_chan(nandc->dev, "rx"); in qcom_nandc_alloc()
3094 if (IS_ERR(nandc->rx_chan)) { in qcom_nandc_alloc()
3095 ret = PTR_ERR(nandc->rx_chan); in qcom_nandc_alloc()
3096 nandc->rx_chan = NULL; in qcom_nandc_alloc()
3097 dev_err_probe(nandc->dev, ret, in qcom_nandc_alloc()
3102 nandc->cmd_chan = dma_request_chan(nandc->dev, "cmd"); in qcom_nandc_alloc()
3103 if (IS_ERR(nandc->cmd_chan)) { in qcom_nandc_alloc()
3104 ret = PTR_ERR(nandc->cmd_chan); in qcom_nandc_alloc()
3105 nandc->cmd_chan = NULL; in qcom_nandc_alloc()
3106 dev_err_probe(nandc->dev, ret, in qcom_nandc_alloc()
3115 * maximum codeword size in qcom_nandc_alloc()
3117 nandc->max_cwperpage = 1; in qcom_nandc_alloc()
3118 nandc->bam_txn = alloc_bam_transaction(nandc); in qcom_nandc_alloc()
3119 if (!nandc->bam_txn) { in qcom_nandc_alloc()
3120 dev_err(nandc->dev, in qcom_nandc_alloc()
3122 ret = -ENOMEM; in qcom_nandc_alloc()
3126 nandc->chan = dma_request_chan(nandc->dev, "rxtx"); in qcom_nandc_alloc()
3127 if (IS_ERR(nandc->chan)) { in qcom_nandc_alloc()
3128 ret = PTR_ERR(nandc->chan); in qcom_nandc_alloc()
3129 nandc->chan = NULL; in qcom_nandc_alloc()
3130 dev_err_probe(nandc->dev, ret, in qcom_nandc_alloc()
3136 INIT_LIST_HEAD(&nandc->desc_list); in qcom_nandc_alloc()
3137 INIT_LIST_HEAD(&nandc->host_list); in qcom_nandc_alloc()
3139 nand_controller_init(&nandc->controller); in qcom_nandc_alloc()
3140 nandc->controller.ops = &qcom_nandc_ops; in qcom_nandc_alloc()
3154 if (!nandc->props->is_qpic) in qcom_nandc_setup()
3157 if (!nandc->props->qpic_v2) in qcom_nandc_setup()
3162 if (nandc->props->is_bam) { in qcom_nandc_setup()
3179 if (!nandc->props->qpic_v2) { in qcom_nandc_setup()
3180 nandc->cmd1 = nandc_read(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD1)); in qcom_nandc_setup()
3181 nandc->vld = NAND_DEV_CMD_VLD_VAL; in qcom_nandc_setup()
3193 struct nand_chip *chip = &host->chip; in qcom_nand_host_parse_boot_partitions()
3196 struct device *dev = nandc->dev; in qcom_nand_host_parse_boot_partitions()
3199 if (!of_property_present(dn, "qcom,boot-partitions")) in qcom_nand_host_parse_boot_partitions()
3202 partitions_count = of_property_count_u32_elems(dn, "qcom,boot-partitions"); in qcom_nand_host_parse_boot_partitions()
3205 return partitions_count ? partitions_count : -EINVAL; in qcom_nand_host_parse_boot_partitions()
3208 host->nr_boot_partitions = partitions_count / 2; in qcom_nand_host_parse_boot_partitions()
3209 host->boot_partitions = devm_kcalloc(dev, host->nr_boot_partitions, in qcom_nand_host_parse_boot_partitions()
3210 sizeof(*host->boot_partitions), GFP_KERNEL); in qcom_nand_host_parse_boot_partitions()
3211 if (!host->boot_partitions) { in qcom_nand_host_parse_boot_partitions()
3212 host->nr_boot_partitions = 0; in qcom_nand_host_parse_boot_partitions()
3213 return -ENOMEM; in qcom_nand_host_parse_boot_partitions()
3216 for (i = 0, j = 0; i < host->nr_boot_partitions; i++, j += 2) { in qcom_nand_host_parse_boot_partitions()
3217 boot_partition = &host->boot_partitions[i]; in qcom_nand_host_parse_boot_partitions()
3219 ret = of_property_read_u32_index(dn, "qcom,boot-partitions", j, in qcom_nand_host_parse_boot_partitions()
3220 &boot_partition->page_offset); in qcom_nand_host_parse_boot_partitions()
3223 host->nr_boot_partitions = 0; in qcom_nand_host_parse_boot_partitions()
3227 if (boot_partition->page_offset % mtd->writesize) { in qcom_nand_host_parse_boot_partitions()
3230 host->nr_boot_partitions = 0; in qcom_nand_host_parse_boot_partitions()
3231 return -EINVAL; in qcom_nand_host_parse_boot_partitions()
3234 boot_partition->page_offset /= mtd->writesize; in qcom_nand_host_parse_boot_partitions()
3236 ret = of_property_read_u32_index(dn, "qcom,boot-partitions", j + 1, in qcom_nand_host_parse_boot_partitions()
3237 &boot_partition->page_size); in qcom_nand_host_parse_boot_partitions()
3240 host->nr_boot_partitions = 0; in qcom_nand_host_parse_boot_partitions()
3244 if (boot_partition->page_size % mtd->writesize) { in qcom_nand_host_parse_boot_partitions()
3247 host->nr_boot_partitions = 0; in qcom_nand_host_parse_boot_partitions()
3248 return -EINVAL; in qcom_nand_host_parse_boot_partitions()
3251 boot_partition->page_size /= mtd->writesize; in qcom_nand_host_parse_boot_partitions()
3261 struct nand_chip *chip = &host->chip; in qcom_nand_host_init_and_register()
3263 struct device *dev = nandc->dev; in qcom_nand_host_init_and_register()
3266 ret = of_property_read_u32(dn, "reg", &host->cs); in qcom_nand_host_init_and_register()
3268 dev_err(dev, "can't get chip-select\n"); in qcom_nand_host_init_and_register()
3269 return -ENXIO; in qcom_nand_host_init_and_register()
3273 mtd->name = devm_kasprintf(dev, GFP_KERNEL, "qcom_nand.%d", host->cs); in qcom_nand_host_init_and_register()
3274 if (!mtd->name) in qcom_nand_host_init_and_register()
3275 return -ENOMEM; in qcom_nand_host_init_and_register()
3277 mtd->owner = THIS_MODULE; in qcom_nand_host_init_and_register()
3278 mtd->dev.parent = dev; in qcom_nand_host_init_and_register()
3281 * the bad block marker is readable only when we read the last codeword in qcom_nand_host_init_and_register()
3284 * disabled (MTD_OPS_PLACE_OOB is set by default). use the block_bad in qcom_nand_host_init_and_register()
3288 chip->legacy.block_bad = qcom_nandc_block_bad; in qcom_nand_host_init_and_register()
3289 chip->legacy.block_markbad = qcom_nandc_block_markbad; in qcom_nand_host_init_and_register()
3291 chip->controller = &nandc->controller; in qcom_nand_host_init_and_register()
3292 chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA | in qcom_nand_host_init_and_register()
3296 host->status = NAND_STATUS_READY | NAND_STATUS_WP; in qcom_nand_host_init_and_register()
3306 if (nandc->props->use_codeword_fixup) { in qcom_nand_host_init_and_register()
3321 struct device *dev = nandc->dev; in qcom_probe_nand_devices()
3322 struct device_node *dn = dev->of_node, *child; in qcom_probe_nand_devices()
3324 int ret = -ENODEV; in qcom_probe_nand_devices()
3330 return -ENOMEM; in qcom_probe_nand_devices()
3339 list_add_tail(&host->node, &nandc->host_list); in qcom_probe_nand_devices()
3349 struct device_node *np = nandc->dev->of_node; in qcom_nandc_parse_dt()
3352 if (!nandc->props->is_bam) { in qcom_nandc_parse_dt()
3353 ret = of_property_read_u32(np, "qcom,cmd-crci", in qcom_nandc_parse_dt()
3354 &nandc->cmd_crci); in qcom_nandc_parse_dt()
3356 dev_err(nandc->dev, "command CRCI unspecified\n"); in qcom_nandc_parse_dt()
3360 ret = of_property_read_u32(np, "qcom,data-crci", in qcom_nandc_parse_dt()
3361 &nandc->data_crci); in qcom_nandc_parse_dt()
3363 dev_err(nandc->dev, "data CRCI unspecified\n"); in qcom_nandc_parse_dt()
3375 struct device *dev = &pdev->dev; in qcom_nandc_probe()
3379 nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc), GFP_KERNEL); in qcom_nandc_probe()
3381 return -ENOMEM; in qcom_nandc_probe()
3384 nandc->dev = dev; in qcom_nandc_probe()
3388 dev_err(&pdev->dev, "failed to get device data\n"); in qcom_nandc_probe()
3389 return -ENODEV; in qcom_nandc_probe()
3392 nandc->props = dev_data; in qcom_nandc_probe()
3394 nandc->core_clk = devm_clk_get(dev, "core"); in qcom_nandc_probe()
3395 if (IS_ERR(nandc->core_clk)) in qcom_nandc_probe()
3396 return PTR_ERR(nandc->core_clk); in qcom_nandc_probe()
3398 nandc->aon_clk = devm_clk_get(dev, "aon"); in qcom_nandc_probe()
3399 if (IS_ERR(nandc->aon_clk)) in qcom_nandc_probe()
3400 return PTR_ERR(nandc->aon_clk); in qcom_nandc_probe()
3406 nandc->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in qcom_nandc_probe()
3407 if (IS_ERR(nandc->base)) in qcom_nandc_probe()
3408 return PTR_ERR(nandc->base); in qcom_nandc_probe()
3410 nandc->base_phys = res->start; in qcom_nandc_probe()
3411 nandc->base_dma = dma_map_resource(dev, res->start, in qcom_nandc_probe()
3414 if (dma_mapping_error(dev, nandc->base_dma)) in qcom_nandc_probe()
3415 return -ENXIO; in qcom_nandc_probe()
3417 ret = clk_prepare_enable(nandc->core_clk); in qcom_nandc_probe()
3421 ret = clk_prepare_enable(nandc->aon_clk); in qcom_nandc_probe()
3442 clk_disable_unprepare(nandc->aon_clk); in qcom_nandc_probe()
3444 clk_disable_unprepare(nandc->core_clk); in qcom_nandc_probe()
3446 dma_unmap_resource(dev, nandc->base_dma, resource_size(res), in qcom_nandc_probe()
3459 list_for_each_entry(host, &nandc->host_list, node) { in qcom_nandc_remove()
3460 chip = &host->chip; in qcom_nandc_remove()
3468 clk_disable_unprepare(nandc->aon_clk); in qcom_nandc_remove()
3469 clk_disable_unprepare(nandc->core_clk); in qcom_nandc_remove()
3471 dma_unmap_resource(&pdev->dev, nandc->base_dma, resource_size(res), in qcom_nandc_remove()
3510 .compatible = "qcom,ipq806x-nand",
3514 .compatible = "qcom,ipq4019-nand",
3518 .compatible = "qcom,ipq6018-nand",
3522 .compatible = "qcom,ipq8074-nand",
3526 .compatible = "qcom,sdx55-nand",
3535 .name = "qcom-nandc",