Lines Matching +full:imx51 +full:- +full:src
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
27 #define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
28 #define NFC_V1_V2_BUF_ADDR (host->regs + 0x04)
29 #define NFC_V1_V2_FLASH_ADDR (host->regs + 0x06)
30 #define NFC_V1_V2_FLASH_CMD (host->regs + 0x08)
31 #define NFC_V1_V2_CONFIG (host->regs + 0x0a)
32 #define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
33 #define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
34 #define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10)
35 #define NFC_V1_V2_WRPROT (host->regs + 0x12)
36 #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
37 #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
38 #define NFC_V21_UNLOCKSTART_BLKADDR0 (host->regs + 0x20)
39 #define NFC_V21_UNLOCKSTART_BLKADDR1 (host->regs + 0x24)
40 #define NFC_V21_UNLOCKSTART_BLKADDR2 (host->regs + 0x28)
41 #define NFC_V21_UNLOCKSTART_BLKADDR3 (host->regs + 0x2c)
42 #define NFC_V21_UNLOCKEND_BLKADDR0 (host->regs + 0x22)
43 #define NFC_V21_UNLOCKEND_BLKADDR1 (host->regs + 0x26)
44 #define NFC_V21_UNLOCKEND_BLKADDR2 (host->regs + 0x2a)
45 #define NFC_V21_UNLOCKEND_BLKADDR3 (host->regs + 0x2e)
46 #define NFC_V1_V2_NF_WRPRST (host->regs + 0x18)
47 #define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
48 #define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
74 #define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
75 #define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04)
77 #define NFC_V3_CONFIG1 (host->regs_axi + 0x34)
81 #define NFC_V3_ECC_STATUS_RESULT (host->regs_axi + 0x38)
83 #define NFC_V3_LAUNCH (host->regs_axi + 0x40)
85 #define NFC_V3_WRPROT (host->regs_ip + 0x0)
91 #define NFC_V3_WRPROT_UNLOCK_BLK_ADD0 (host->regs_ip + 0x04)
93 #define NFC_V3_CONFIG2 (host->regs_ip + 0x24)
108 #define NFC_V3_CONFIG3 (host->regs_ip + 0x28)
116 #define NFC_V3_IPC (host->regs_ip + 0x2C)
120 #define NFC_V3_DELAY_LINE (host->regs_ip + 0x34)
190 static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) in memcpy32_fromio() argument
194 const __iomem u32 *s = src; in memcpy32_fromio()
200 static void memcpy16_fromio(void *trg, const void __iomem *src, size_t size) in memcpy16_fromio() argument
204 const __iomem u16 *s = src; in memcpy16_fromio()
206 /* We assume that src (IO) is always 32bit aligned */ in memcpy16_fromio()
208 memcpy32_fromio(trg, src, size); in memcpy16_fromio()
216 static inline void memcpy32_toio(void __iomem *trg, const void *src, int size) in memcpy32_toio() argument
219 __iowrite32_copy(trg, src, size / 4); in memcpy32_toio()
222 static void memcpy16_toio(void __iomem *trg, const void *src, int size) in memcpy16_toio() argument
226 const u16 *s = src; in memcpy16_toio()
229 if (PTR_ALIGN(src, 4) == src && IS_ALIGNED(size, 4)) { in memcpy16_toio()
230 memcpy32_toio(trg, src, size); in memcpy16_toio()
243 * This function handles the needed shuffling between host->data_buf (which
252 u16 num_chunks = mtd->writesize / 512; in copy_spare()
255 u8 __iomem *s = host->spare0; in copy_spare()
256 u16 sparebuf_size = host->devtype_data->spare_len; in copy_spare()
259 oob_chunk_size = (host->used_oobsize / num_chunks) & ~1; in copy_spare()
262 for (i = 0; i < num_chunks - 1; i++) in copy_spare()
270 host->used_oobsize - i * oob_chunk_size); in copy_spare()
272 for (i = 0; i < num_chunks - 1; i++) in copy_spare()
280 host->used_oobsize - i * oob_chunk_size); in copy_spare()
285 * MXC NANDFC can only perform full page+spare or spare-only read/write. When
288 * column == 0 (unless no column cycle is needed indicated by column == -1)
296 if (column != -1) { in mxc_do_addr_cycle()
297 host->devtype_data->send_addr(host, column & 0xff, in mxc_do_addr_cycle()
298 page_addr == -1); in mxc_do_addr_cycle()
299 if (mtd->writesize > 512) in mxc_do_addr_cycle()
301 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
307 if (page_addr != -1) { in mxc_do_addr_cycle()
308 /* paddr_0 - p_addr_7 */ in mxc_do_addr_cycle()
309 host->devtype_data->send_addr(host, (page_addr & 0xff), false); in mxc_do_addr_cycle()
311 if (mtd->writesize > 512) { in mxc_do_addr_cycle()
312 if (mtd->size >= 0x10000000) { in mxc_do_addr_cycle()
313 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
314 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
317 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
321 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
322 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
325 if (nand_chip->options & NAND_ROW_ADDR_3) { in mxc_do_addr_cycle()
326 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
327 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
330 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
334 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
335 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
363 if (!host->devtype_data->irqpending_quirk) in check_int_v1_v2()
399 if (host->devtype_data->irqpending_quirk) { in irq_control()
401 enable_irq(host->irq); in irq_control()
403 disable_irq_nosync(host->irq); in irq_control()
405 host->devtype_data->irq_control(host, activate); in irq_control()
428 if (!host->devtype_data->check_int(host)) in mxc_nfc_irq()
433 complete(&host->op_completion); in mxc_nfc_irq()
449 if (host->devtype_data->check_int(host)) in wait_op_done()
455 reinit_completion(&host->op_completion); in wait_op_done()
459 timeout = wait_for_completion_timeout(&host->op_completion, HZ); in wait_op_done()
460 if (!timeout && !host->devtype_data->check_int(host)) { in wait_op_done()
461 dev_dbg(host->dev, "timeout waiting for irq\n"); in wait_op_done()
462 ret = -ETIMEDOUT; in wait_op_done()
471 done = host->devtype_data->check_int(host); in wait_op_done()
475 } while (--max_retries); in wait_op_done()
478 dev_dbg(host->dev, "timeout polling for completion\n"); in wait_op_done()
479 ret = -ETIMEDOUT; in wait_op_done()
504 dev_dbg(host->dev, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); in send_cmd_v1_v2()
509 if (host->devtype_data->irqpending_quirk && (cmd == NAND_CMD_RESET)) { in send_cmd_v1_v2()
513 while (max_retries-- > 0) { in send_cmd_v1_v2()
520 dev_dbg(host->dev, "%s: RESET failed\n", __func__); in send_cmd_v1_v2()
543 dev_dbg(host->dev, "send_addr(host, 0x%x %d)\n", addr, islast); in send_addr_v1_v2()
574 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in send_page_v2()
588 if (mtd->writesize > 512) in send_page_v1()
596 writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); in send_page_v1()
612 memcpy32_fromio(host->data_buf, host->main_area0, 16); in send_read_id_v3()
619 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in send_read_id_v1_v2()
626 memcpy32_fromio(host->data_buf, host->main_area0, 16); in send_read_id_v1_v2()
641 void __iomem *main_buf = host->main_area0; in get_dev_status_v1_v2()
645 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in get_dev_status_v1_v2()
669 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) in mxc_nand_enable_hwecc_v1_v2()
687 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) in mxc_nand_enable_hwecc_v3()
719 host->devtype_data->enable_hwecc(chip, ecc); in mxc_nand_read_page_v1()
721 host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); in mxc_nand_read_page_v1()
724 if (mtd->writesize > 512) in mxc_nand_read_page_v1()
725 host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true); in mxc_nand_read_page_v1()
727 no_subpages = mtd->writesize >> 9; in mxc_nand_read_page_v1()
733 writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); in mxc_nand_read_page_v1()
750 mtd->ecc_stats.corrected++; in mxc_nand_read_page_v1()
754 mtd->ecc_stats.failed++; in mxc_nand_read_page_v1()
761 memcpy32_fromio(buf, host->main_area0, mtd->writesize); in mxc_nand_read_page_v1()
778 host->devtype_data->enable_hwecc(chip, ecc); in mxc_nand_read_page_v2_v3()
780 host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); in mxc_nand_read_page_v2_v3()
783 if (mtd->writesize > 512) in mxc_nand_read_page_v2_v3()
784 host->devtype_data->send_cmd(host, in mxc_nand_read_page_v2_v3()
787 host->devtype_data->send_page(mtd, NFC_OUTPUT); in mxc_nand_read_page_v2_v3()
790 memcpy32_fromio(buf, host->main_area0, mtd->writesize); in mxc_nand_read_page_v2_v3()
794 ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf; in mxc_nand_read_page_v2_v3()
795 err_limit = (host->eccsize == 4) ? 0x4 : 0x8; in mxc_nand_read_page_v2_v3()
797 no_subpages = mtd->writesize >> 9; in mxc_nand_read_page_v2_v3()
799 ecc_stat = host->devtype_data->get_ecc_status(host); in mxc_nand_read_page_v2_v3()
804 mtd->ecc_stats.failed++; in mxc_nand_read_page_v2_v3()
806 mtd->ecc_stats.corrected += err; in mxc_nand_read_page_v2_v3()
811 } while (--no_subpages); in mxc_nand_read_page_v2_v3()
823 oob_buf = chip->oob_poi; in mxc_nand_read_page()
827 return host->devtype_data->read_page(chip, buf, oob_buf, 1, page); in mxc_nand_read_page()
837 oob_buf = chip->oob_poi; in mxc_nand_read_page_raw()
841 return host->devtype_data->read_page(chip, buf, oob_buf, 0, page); in mxc_nand_read_page_raw()
848 return host->devtype_data->read_page(chip, NULL, chip->oob_poi, 0, in mxc_nand_read_oob()
858 host->devtype_data->enable_hwecc(chip, ecc); in mxc_nand_write_page()
860 host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false); in mxc_nand_write_page()
863 memcpy32_toio(host->main_area0, buf, mtd->writesize); in mxc_nand_write_page()
864 copy_spare(mtd, false, chip->oob_poi); in mxc_nand_write_page()
866 host->devtype_data->send_page(mtd, NFC_INPUT); in mxc_nand_write_page()
867 host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true); in mxc_nand_write_page()
890 memset(host->data_buf, 0xff, mtd->writesize); in mxc_nand_write_oob()
892 return mxc_nand_write_page(chip, host->data_buf, false, page); in mxc_nand_write_oob()
901 if (host->status_request) in mxc_nand_read_byte()
902 return host->devtype_data->get_dev_status(host) & 0xFF; in mxc_nand_read_byte()
904 if (nand_chip->options & NAND_BUSWIDTH_16) { in mxc_nand_read_byte()
906 ret = *(uint16_t *)(host->data_buf + host->buf_start); in mxc_nand_read_byte()
908 host->buf_start += 2; in mxc_nand_read_byte()
910 ret = *(uint8_t *)(host->data_buf + host->buf_start); in mxc_nand_read_byte()
911 host->buf_start++; in mxc_nand_read_byte()
914 dev_dbg(host->dev, "%s: ret=0x%hhx (start=%u)\n", __func__, ret, host->buf_start); in mxc_nand_read_byte()
926 u16 col = host->buf_start; in mxc_nand_write_buf()
927 int n = mtd->oobsize + mtd->writesize - col; in mxc_nand_write_buf()
931 memcpy(host->data_buf + col, buf, n); in mxc_nand_write_buf()
933 host->buf_start += n; in mxc_nand_write_buf()
945 u16 col = host->buf_start; in mxc_nand_read_buf()
946 int n = mtd->oobsize + mtd->writesize - col; in mxc_nand_read_buf()
950 memcpy(buf, host->data_buf + col, n); in mxc_nand_read_buf()
952 host->buf_start += n; in mxc_nand_read_buf()
961 if (chip == -1) { in mxc_nand_select_chip_v1_v3()
963 if (host->clk_act) { in mxc_nand_select_chip_v1_v3()
964 clk_disable_unprepare(host->clk); in mxc_nand_select_chip_v1_v3()
965 host->clk_act = 0; in mxc_nand_select_chip_v1_v3()
970 if (!host->clk_act) { in mxc_nand_select_chip_v1_v3()
972 clk_prepare_enable(host->clk); in mxc_nand_select_chip_v1_v3()
973 host->clk_act = 1; in mxc_nand_select_chip_v1_v3()
981 if (chip == -1) { in mxc_nand_select_chip_v2()
983 if (host->clk_act) { in mxc_nand_select_chip_v2()
984 clk_disable_unprepare(host->clk); in mxc_nand_select_chip_v2()
985 host->clk_act = 0; in mxc_nand_select_chip_v2()
990 if (!host->clk_act) { in mxc_nand_select_chip_v2()
992 clk_prepare_enable(host->clk); in mxc_nand_select_chip_v2()
993 host->clk_act = 1; in mxc_nand_select_chip_v2()
996 host->active_cs = chip; in mxc_nand_select_chip_v2()
997 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in mxc_nand_select_chip_v2()
1007 if (section >= nand_chip->ecc.steps) in mxc_v1_ooblayout_ecc()
1008 return -ERANGE; in mxc_v1_ooblayout_ecc()
1010 oobregion->offset = (section * 16) + 6; in mxc_v1_ooblayout_ecc()
1011 oobregion->length = MXC_V1_ECCBYTES; in mxc_v1_ooblayout_ecc()
1021 if (section > nand_chip->ecc.steps) in mxc_v1_ooblayout_free()
1022 return -ERANGE; in mxc_v1_ooblayout_free()
1025 if (mtd->writesize <= 512) { in mxc_v1_ooblayout_free()
1026 oobregion->offset = 0; in mxc_v1_ooblayout_free()
1027 oobregion->length = 5; in mxc_v1_ooblayout_free()
1029 oobregion->offset = 2; in mxc_v1_ooblayout_free()
1030 oobregion->length = 4; in mxc_v1_ooblayout_free()
1033 oobregion->offset = ((section - 1) * 16) + MXC_V1_ECCBYTES + 6; in mxc_v1_ooblayout_free()
1034 if (section < nand_chip->ecc.steps) in mxc_v1_ooblayout_free()
1035 oobregion->length = (section * 16) + 6 - in mxc_v1_ooblayout_free()
1036 oobregion->offset; in mxc_v1_ooblayout_free()
1038 oobregion->length = mtd->oobsize - oobregion->offset; in mxc_v1_ooblayout_free()
1053 int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; in mxc_v2_ooblayout_ecc()
1055 if (section >= nand_chip->ecc.steps) in mxc_v2_ooblayout_ecc()
1056 return -ERANGE; in mxc_v2_ooblayout_ecc()
1058 oobregion->offset = (section * stepsize) + 7; in mxc_v2_ooblayout_ecc()
1059 oobregion->length = nand_chip->ecc.bytes; in mxc_v2_ooblayout_ecc()
1068 int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; in mxc_v2_ooblayout_free()
1070 if (section >= nand_chip->ecc.steps) in mxc_v2_ooblayout_free()
1071 return -ERANGE; in mxc_v2_ooblayout_free()
1074 if (mtd->writesize <= 512) { in mxc_v2_ooblayout_free()
1075 oobregion->offset = 0; in mxc_v2_ooblayout_free()
1076 oobregion->length = 5; in mxc_v2_ooblayout_free()
1078 oobregion->offset = 2; in mxc_v2_ooblayout_free()
1079 oobregion->length = 4; in mxc_v2_ooblayout_free()
1082 oobregion->offset = section * stepsize; in mxc_v2_ooblayout_free()
1083 oobregion->length = 7; in mxc_v2_ooblayout_free()
1103 oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize; in get_eccsize()
1117 if (nand_chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST && in preset_v1()
1118 mtd->writesize) in preset_v1()
1121 if (!host->devtype_data->irqpending_quirk) in preset_v1()
1124 host->eccsize = 1; in preset_v1()
1151 return -ENOTSUPP; in mxc_nand_v2_setup_interface()
1155 tRC_min_ns = timings->tRC_min / 1000; in mxc_nand_v2_setup_interface()
1165 rate_round = clk_round_rate(host->clk, rate); in mxc_nand_v2_setup_interface()
1170 rate_round = clk_round_rate(host->clk, rate); in mxc_nand_v2_setup_interface()
1179 if (timings->tCLS_min > tRC_ps - 1000 || in mxc_nand_v2_setup_interface()
1180 timings->tCLH_min > tRC_ps - 2000 || in mxc_nand_v2_setup_interface()
1181 timings->tCS_min > tRC_ps - 1000 || in mxc_nand_v2_setup_interface()
1182 timings->tCH_min > tRC_ps - 2000 || in mxc_nand_v2_setup_interface()
1183 timings->tWP_min > tRC_ps - 1500 || in mxc_nand_v2_setup_interface()
1184 timings->tALS_min > tRC_ps || in mxc_nand_v2_setup_interface()
1185 timings->tALH_min > tRC_ps - 3000 || in mxc_nand_v2_setup_interface()
1186 timings->tDS_min > tRC_ps || in mxc_nand_v2_setup_interface()
1187 timings->tDH_min > tRC_ps - 5000 || in mxc_nand_v2_setup_interface()
1188 timings->tWC_min > 2 * tRC_ps || in mxc_nand_v2_setup_interface()
1189 timings->tWH_min > tRC_ps - 2500 || in mxc_nand_v2_setup_interface()
1190 timings->tRR_min > 6 * tRC_ps || in mxc_nand_v2_setup_interface()
1191 timings->tRP_min > 3 * tRC_ps / 2 || in mxc_nand_v2_setup_interface()
1192 timings->tRC_min > 2 * tRC_ps || in mxc_nand_v2_setup_interface()
1193 timings->tREH_min > (tRC_ps / 2) - 2500) { in mxc_nand_v2_setup_interface()
1194 dev_dbg(host->dev, "Timing out of bounds\n"); in mxc_nand_v2_setup_interface()
1195 return -EINVAL; in mxc_nand_v2_setup_interface()
1201 ret = clk_set_rate(host->clk, rate); in mxc_nand_v2_setup_interface()
1207 dev_dbg(host->dev, "Setting rate to %ldHz, %s mode\n", rate_round, in mxc_nand_v2_setup_interface()
1222 if (!host->devtype_data->irqpending_quirk) in preset_v2()
1225 if (mtd->writesize) { in preset_v2()
1226 uint16_t pages_per_block = mtd->erasesize / mtd->writesize; in preset_v2()
1228 if (nand_chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) in preset_v2()
1231 host->eccsize = get_eccsize(mtd); in preset_v2()
1232 if (host->eccsize == 4) in preset_v2()
1235 config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6); in preset_v2()
1237 host->eccsize = 1; in preset_v2()
1243 /* spare area size in 16-bit half-words */ in preset_v2()
1244 writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA); in preset_v2()
1285 NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) | in preset_v3()
1290 addr_phases = fls(chip->pagemask) >> 3; in preset_v3()
1292 if (mtd->writesize == 2048) { in preset_v3()
1295 } else if (mtd->writesize == 4096) { in preset_v3()
1300 config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1); in preset_v3()
1303 if (mtd->writesize) { in preset_v3()
1304 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) in preset_v3()
1308 ffs(mtd->erasesize / mtd->writesize) - 6, in preset_v3()
1309 host->devtype_data->ppb_shift); in preset_v3()
1310 host->eccsize = get_eccsize(mtd); in preset_v3()
1311 if (host->eccsize == 8) in preset_v3()
1323 if (!(chip->options & NAND_BUSWIDTH_16)) in preset_v3()
1339 dev_dbg(host->dev, "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", in mxc_nand_command()
1343 host->status_request = false; in mxc_nand_command()
1345 /* Command pre-processing step */ in mxc_nand_command()
1348 host->devtype_data->preset(mtd); in mxc_nand_command()
1349 host->devtype_data->send_cmd(host, command, false); in mxc_nand_command()
1353 host->buf_start = 0; in mxc_nand_command()
1354 host->status_request = true; in mxc_nand_command()
1356 host->devtype_data->send_cmd(host, command, true); in mxc_nand_command()
1357 WARN_ONCE(column != -1 || page_addr != -1, in mxc_nand_command()
1364 host->devtype_data->send_cmd(host, command, true); in mxc_nand_command()
1366 host->devtype_data->send_read_id(host); in mxc_nand_command()
1367 host->buf_start = 0; in mxc_nand_command()
1372 host->devtype_data->send_cmd(host, command, false); in mxc_nand_command()
1373 WARN_ONCE(column != -1, in mxc_nand_command()
1380 host->devtype_data->send_cmd(host, command, false); in mxc_nand_command()
1382 host->devtype_data->send_page(mtd, NFC_OUTPUT); in mxc_nand_command()
1383 memcpy32_fromio(host->data_buf, host->main_area0, 512); in mxc_nand_command()
1384 host->buf_start = 0; in mxc_nand_command()
1400 host->buf_start = 0; in mxc_nand_set_features()
1403 chip->legacy.write_byte(chip, subfeature_param[i]); in mxc_nand_set_features()
1405 memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); in mxc_nand_set_features()
1406 host->devtype_data->send_cmd(host, NAND_CMD_SET_FEATURES, false); in mxc_nand_set_features()
1407 mxc_do_addr_cycle(mtd, addr, -1); in mxc_nand_set_features()
1408 host->devtype_data->send_page(mtd, NFC_INPUT); in mxc_nand_set_features()
1420 host->devtype_data->send_cmd(host, NAND_CMD_GET_FEATURES, false); in mxc_nand_get_features()
1421 mxc_do_addr_cycle(mtd, addr, -1); in mxc_nand_get_features()
1422 host->devtype_data->send_page(mtd, NFC_OUTPUT); in mxc_nand_get_features()
1423 memcpy32_fromio(host->data_buf, host->main_area0, 512); in mxc_nand_get_features()
1424 host->buf_start = 0; in mxc_nand_get_features()
1427 *subfeature_param++ = chip->legacy.read_byte(chip); in mxc_nand_get_features()
1588 return host->devtype_data == &imx21_nand_devtype_data; in is_imx21_nfc()
1593 return host->devtype_data == &imx27_nand_devtype_data; in is_imx27_nfc()
1598 return host->devtype_data == &imx25_nand_devtype_data; in is_imx25_nfc()
1602 { .compatible = "fsl,imx21-nand", .data = &imx21_nand_devtype_data, },
1603 { .compatible = "fsl,imx27-nand", .data = &imx27_nand_devtype_data, },
1604 { .compatible = "fsl,imx25-nand", .data = &imx25_nand_devtype_data, },
1605 { .compatible = "fsl,imx51-nand", .data = &imx51_nand_devtype_data, },
1606 { .compatible = "fsl,imx53-nand", .data = &imx53_nand_devtype_data, },
1615 struct device *dev = mtd->dev.parent; in mxcnd_attach_chip()
1617 chip->ecc.bytes = host->devtype_data->eccbytes; in mxcnd_attach_chip()
1618 host->eccsize = host->devtype_data->eccsize; in mxcnd_attach_chip()
1619 chip->ecc.size = 512; in mxcnd_attach_chip()
1620 mtd_set_ooblayout(mtd, host->devtype_data->ooblayout); in mxcnd_attach_chip()
1622 switch (chip->ecc.engine_type) { in mxcnd_attach_chip()
1624 chip->ecc.read_page = mxc_nand_read_page; in mxcnd_attach_chip()
1625 chip->ecc.read_page_raw = mxc_nand_read_page_raw; in mxcnd_attach_chip()
1626 chip->ecc.read_oob = mxc_nand_read_oob; in mxcnd_attach_chip()
1627 chip->ecc.write_page = mxc_nand_write_page_ecc; in mxcnd_attach_chip()
1628 chip->ecc.write_page_raw = mxc_nand_write_page_raw; in mxcnd_attach_chip()
1629 chip->ecc.write_oob = mxc_nand_write_oob; in mxcnd_attach_chip()
1636 return -EINVAL; in mxcnd_attach_chip()
1639 if (chip->bbt_options & NAND_BBT_USE_FLASH) { in mxcnd_attach_chip()
1640 chip->bbt_td = &bbt_main_descr; in mxcnd_attach_chip()
1641 chip->bbt_md = &bbt_mirror_descr; in mxcnd_attach_chip()
1645 devm_kfree(dev, (void *)host->data_buf); in mxcnd_attach_chip()
1646 host->data_buf = devm_kzalloc(dev, mtd->writesize + mtd->oobsize, in mxcnd_attach_chip()
1648 if (!host->data_buf) in mxcnd_attach_chip()
1649 return -ENOMEM; in mxcnd_attach_chip()
1652 host->devtype_data->preset(mtd); in mxcnd_attach_chip()
1654 if (!chip->ecc.bytes) { in mxcnd_attach_chip()
1655 if (host->eccsize == 8) in mxcnd_attach_chip()
1656 chip->ecc.bytes = 18; in mxcnd_attach_chip()
1657 else if (host->eccsize == 4) in mxcnd_attach_chip()
1658 chip->ecc.bytes = 9; in mxcnd_attach_chip()
1665 * might cause ECC data corruption when doing sub-page write to a in mxcnd_attach_chip()
1668 host->used_oobsize = min(mtd->oobsize, 218U); in mxcnd_attach_chip()
1670 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) { in mxcnd_attach_chip()
1672 chip->ecc.strength = 1; in mxcnd_attach_chip()
1674 chip->ecc.strength = (host->eccsize == 4) ? 4 : 8; in mxcnd_attach_chip()
1685 return host->devtype_data->setup_interface(chip, chipnr, conf); in mxcnd_setup_interface()
1701 host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host), in mxcnd_probe()
1704 return -ENOMEM; in mxcnd_probe()
1707 host->data_buf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL); in mxcnd_probe()
1708 if (!host->data_buf) in mxcnd_probe()
1709 return -ENOMEM; in mxcnd_probe()
1711 host->dev = &pdev->dev; in mxcnd_probe()
1713 this = &host->nand; in mxcnd_probe()
1715 mtd->dev.parent = &pdev->dev; in mxcnd_probe()
1716 mtd->name = DRIVER_NAME; in mxcnd_probe()
1719 this->legacy.chip_delay = 5; in mxcnd_probe()
1722 nand_set_flash_node(this, pdev->dev.of_node); in mxcnd_probe()
1723 this->legacy.dev_ready = mxc_nand_dev_ready; in mxcnd_probe()
1724 this->legacy.cmdfunc = mxc_nand_command; in mxcnd_probe()
1725 this->legacy.read_byte = mxc_nand_read_byte; in mxcnd_probe()
1726 this->legacy.write_buf = mxc_nand_write_buf; in mxcnd_probe()
1727 this->legacy.read_buf = mxc_nand_read_buf; in mxcnd_probe()
1728 this->legacy.set_features = mxc_nand_set_features; in mxcnd_probe()
1729 this->legacy.get_features = mxc_nand_get_features; in mxcnd_probe()
1731 host->clk = devm_clk_get(&pdev->dev, NULL); in mxcnd_probe()
1732 if (IS_ERR(host->clk)) in mxcnd_probe()
1733 return PTR_ERR(host->clk); in mxcnd_probe()
1735 host->devtype_data = device_get_match_data(&pdev->dev); in mxcnd_probe()
1737 if (!host->devtype_data->setup_interface) in mxcnd_probe()
1738 this->options |= NAND_KEEP_TIMINGS; in mxcnd_probe()
1740 if (host->devtype_data->needs_ip) { in mxcnd_probe()
1741 host->regs_ip = devm_platform_ioremap_resource(pdev, 0); in mxcnd_probe()
1742 if (IS_ERR(host->regs_ip)) in mxcnd_probe()
1743 return PTR_ERR(host->regs_ip); in mxcnd_probe()
1745 host->base = devm_platform_ioremap_resource(pdev, 1); in mxcnd_probe()
1747 host->base = devm_platform_ioremap_resource(pdev, 0); in mxcnd_probe()
1750 if (IS_ERR(host->base)) in mxcnd_probe()
1751 return PTR_ERR(host->base); in mxcnd_probe()
1753 host->main_area0 = host->base; in mxcnd_probe()
1755 if (host->devtype_data->regs_offset) in mxcnd_probe()
1756 host->regs = host->base + host->devtype_data->regs_offset; in mxcnd_probe()
1757 host->spare0 = host->base + host->devtype_data->spare0_offset; in mxcnd_probe()
1758 if (host->devtype_data->axi_offset) in mxcnd_probe()
1759 host->regs_axi = host->base + host->devtype_data->axi_offset; in mxcnd_probe()
1761 this->legacy.select_chip = host->devtype_data->select_chip; in mxcnd_probe()
1763 init_completion(&host->op_completion); in mxcnd_probe()
1765 host->irq = platform_get_irq(pdev, 0); in mxcnd_probe()
1766 if (host->irq < 0) in mxcnd_probe()
1767 return host->irq; in mxcnd_probe()
1770 * Use host->devtype_data->irq_control() here instead of irq_control() in mxcnd_probe()
1774 host->devtype_data->irq_control(host, 0); in mxcnd_probe()
1776 err = devm_request_irq(&pdev->dev, host->irq, mxc_nfc_irq, in mxcnd_probe()
1781 err = clk_prepare_enable(host->clk); in mxcnd_probe()
1784 host->clk_act = 1; in mxcnd_probe()
1791 if (host->devtype_data->irqpending_quirk) { in mxcnd_probe()
1792 disable_irq_nosync(host->irq); in mxcnd_probe()
1793 host->devtype_data->irq_control(host, 1); in mxcnd_probe()
1797 this->legacy.dummy_controller.ops = &mxcnd_controller_ops; in mxcnd_probe()
1814 if (host->clk_act) in mxcnd_probe()
1815 clk_disable_unprepare(host->clk); in mxcnd_probe()
1823 struct nand_chip *chip = &host->nand; in mxcnd_remove()
1829 if (host->clk_act) in mxcnd_remove()
1830 clk_disable_unprepare(host->clk); in mxcnd_remove()