Lines Matching +full:imx51 +full:- +full:src
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
24 #include <linux/platform_data/mtd-mxc_nand.h>
29 #define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
30 #define NFC_V1_V2_BUF_ADDR (host->regs + 0x04)
31 #define NFC_V1_V2_FLASH_ADDR (host->regs + 0x06)
32 #define NFC_V1_V2_FLASH_CMD (host->regs + 0x08)
33 #define NFC_V1_V2_CONFIG (host->regs + 0x0a)
34 #define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
35 #define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
36 #define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10)
37 #define NFC_V1_V2_WRPROT (host->regs + 0x12)
38 #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
39 #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
40 #define NFC_V21_UNLOCKSTART_BLKADDR0 (host->regs + 0x20)
41 #define NFC_V21_UNLOCKSTART_BLKADDR1 (host->regs + 0x24)
42 #define NFC_V21_UNLOCKSTART_BLKADDR2 (host->regs + 0x28)
43 #define NFC_V21_UNLOCKSTART_BLKADDR3 (host->regs + 0x2c)
44 #define NFC_V21_UNLOCKEND_BLKADDR0 (host->regs + 0x22)
45 #define NFC_V21_UNLOCKEND_BLKADDR1 (host->regs + 0x26)
46 #define NFC_V21_UNLOCKEND_BLKADDR2 (host->regs + 0x2a)
47 #define NFC_V21_UNLOCKEND_BLKADDR3 (host->regs + 0x2e)
48 #define NFC_V1_V2_NF_WRPRST (host->regs + 0x18)
49 #define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
50 #define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
76 #define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
77 #define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04)
79 #define NFC_V3_CONFIG1 (host->regs_axi + 0x34)
83 #define NFC_V3_ECC_STATUS_RESULT (host->regs_axi + 0x38)
85 #define NFC_V3_LAUNCH (host->regs_axi + 0x40)
87 #define NFC_V3_WRPROT (host->regs_ip + 0x0)
93 #define NFC_V3_WRPROT_UNLOCK_BLK_ADD0 (host->regs_ip + 0x04)
95 #define NFC_V3_CONFIG2 (host->regs_ip + 0x24)
110 #define NFC_V3_CONFIG3 (host->regs_ip + 0x28)
118 #define NFC_V3_IPC (host->regs_ip + 0x2C)
122 #define NFC_V3_DELAY_LINE (host->regs_ip + 0x34)
193 static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) in memcpy32_fromio() argument
197 const __iomem u32 *s = src; in memcpy32_fromio()
203 static void memcpy16_fromio(void *trg, const void __iomem *src, size_t size) in memcpy16_fromio() argument
207 const __iomem u16 *s = src; in memcpy16_fromio()
209 /* We assume that src (IO) is always 32bit aligned */ in memcpy16_fromio()
211 memcpy32_fromio(trg, src, size); in memcpy16_fromio()
219 static inline void memcpy32_toio(void __iomem *trg, const void *src, int size) in memcpy32_toio() argument
222 __iowrite32_copy(trg, src, size / 4); in memcpy32_toio()
225 static void memcpy16_toio(void __iomem *trg, const void *src, int size) in memcpy16_toio() argument
229 const u16 *s = src; in memcpy16_toio()
232 if (PTR_ALIGN(src, 4) == src && IS_ALIGNED(size, 4)) { in memcpy16_toio()
233 memcpy32_toio(trg, src, size); in memcpy16_toio()
246 * This function handles the needed shuffling between host->data_buf (which
255 u16 num_chunks = mtd->writesize / 512; in copy_spare()
258 u8 __iomem *s = host->spare0; in copy_spare()
259 u16 sparebuf_size = host->devtype_data->spare_len; in copy_spare()
262 oob_chunk_size = (host->used_oobsize / num_chunks) & ~1; in copy_spare()
265 for (i = 0; i < num_chunks - 1; i++) in copy_spare()
273 host->used_oobsize - i * oob_chunk_size); in copy_spare()
275 for (i = 0; i < num_chunks - 1; i++) in copy_spare()
283 host->used_oobsize - i * oob_chunk_size); in copy_spare()
288 * MXC NANDFC can only perform full page+spare or spare-only read/write. When
291 * column == 0 (unless no column cycle is needed indicated by column == -1)
299 if (column != -1) { in mxc_do_addr_cycle()
300 host->devtype_data->send_addr(host, column & 0xff, in mxc_do_addr_cycle()
301 page_addr == -1); in mxc_do_addr_cycle()
302 if (mtd->writesize > 512) in mxc_do_addr_cycle()
304 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
310 if (page_addr != -1) { in mxc_do_addr_cycle()
311 /* paddr_0 - p_addr_7 */ in mxc_do_addr_cycle()
312 host->devtype_data->send_addr(host, (page_addr & 0xff), false); in mxc_do_addr_cycle()
314 if (mtd->writesize > 512) { in mxc_do_addr_cycle()
315 if (mtd->size >= 0x10000000) { in mxc_do_addr_cycle()
316 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
317 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
320 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
324 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
325 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
328 if (nand_chip->options & NAND_ROW_ADDR_3) { in mxc_do_addr_cycle()
329 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
330 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
333 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
337 /* paddr_8 - paddr_15 */ in mxc_do_addr_cycle()
338 host->devtype_data->send_addr(host, in mxc_do_addr_cycle()
366 if (!host->devtype_data->irqpending_quirk) in check_int_v1_v2()
402 if (host->devtype_data->irqpending_quirk) { in irq_control()
404 enable_irq(host->irq); in irq_control()
406 disable_irq_nosync(host->irq); in irq_control()
408 host->devtype_data->irq_control(host, activate); in irq_control()
431 if (!host->devtype_data->check_int(host)) in mxc_nfc_irq()
436 complete(&host->op_completion); in mxc_nfc_irq()
452 if (host->devtype_data->check_int(host)) in wait_op_done()
458 reinit_completion(&host->op_completion); in wait_op_done()
462 timeout = wait_for_completion_timeout(&host->op_completion, HZ); in wait_op_done()
463 if (!timeout && !host->devtype_data->check_int(host)) { in wait_op_done()
464 dev_dbg(host->dev, "timeout waiting for irq\n"); in wait_op_done()
465 ret = -ETIMEDOUT; in wait_op_done()
474 done = host->devtype_data->check_int(host); in wait_op_done()
478 } while (--max_retries); in wait_op_done()
481 dev_dbg(host->dev, "timeout polling for completion\n"); in wait_op_done()
482 ret = -ETIMEDOUT; in wait_op_done()
507 dev_dbg(host->dev, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); in send_cmd_v1_v2()
512 if (host->devtype_data->irqpending_quirk && (cmd == NAND_CMD_RESET)) { in send_cmd_v1_v2()
516 while (max_retries-- > 0) { in send_cmd_v1_v2()
523 dev_dbg(host->dev, "%s: RESET failed\n", __func__); in send_cmd_v1_v2()
546 dev_dbg(host->dev, "send_addr(host, 0x%x %d)\n", addr, islast); in send_addr_v1_v2()
577 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in send_page_v2()
591 if (mtd->writesize > 512) in send_page_v1()
599 writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); in send_page_v1()
615 memcpy32_fromio(host->data_buf, host->main_area0, 16); in send_read_id_v3()
622 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in send_read_id_v1_v2()
629 memcpy32_fromio(host->data_buf, host->main_area0, 16); in send_read_id_v1_v2()
644 void __iomem *main_buf = host->main_area0; in get_dev_status_v1_v2()
648 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in get_dev_status_v1_v2()
672 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) in mxc_nand_enable_hwecc_v1_v2()
690 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) in mxc_nand_enable_hwecc_v3()
722 host->devtype_data->enable_hwecc(chip, ecc); in mxc_nand_read_page_v1()
724 host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); in mxc_nand_read_page_v1()
727 if (mtd->writesize > 512) in mxc_nand_read_page_v1()
728 host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true); in mxc_nand_read_page_v1()
730 no_subpages = mtd->writesize >> 9; in mxc_nand_read_page_v1()
736 writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); in mxc_nand_read_page_v1()
753 mtd->ecc_stats.corrected++; in mxc_nand_read_page_v1()
757 mtd->ecc_stats.failed++; in mxc_nand_read_page_v1()
764 memcpy32_fromio(buf, host->main_area0, mtd->writesize); in mxc_nand_read_page_v1()
781 host->devtype_data->enable_hwecc(chip, ecc); in mxc_nand_read_page_v2_v3()
783 host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); in mxc_nand_read_page_v2_v3()
786 if (mtd->writesize > 512) in mxc_nand_read_page_v2_v3()
787 host->devtype_data->send_cmd(host, in mxc_nand_read_page_v2_v3()
790 host->devtype_data->send_page(mtd, NFC_OUTPUT); in mxc_nand_read_page_v2_v3()
793 memcpy32_fromio(buf, host->main_area0, mtd->writesize); in mxc_nand_read_page_v2_v3()
797 ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf; in mxc_nand_read_page_v2_v3()
798 err_limit = (host->eccsize == 4) ? 0x4 : 0x8; in mxc_nand_read_page_v2_v3()
800 no_subpages = mtd->writesize >> 9; in mxc_nand_read_page_v2_v3()
802 ecc_stat = host->devtype_data->get_ecc_status(host); in mxc_nand_read_page_v2_v3()
807 mtd->ecc_stats.failed++; in mxc_nand_read_page_v2_v3()
809 mtd->ecc_stats.corrected += err; in mxc_nand_read_page_v2_v3()
814 } while (--no_subpages); in mxc_nand_read_page_v2_v3()
826 oob_buf = chip->oob_poi; in mxc_nand_read_page()
830 return host->devtype_data->read_page(chip, buf, oob_buf, 1, page); in mxc_nand_read_page()
840 oob_buf = chip->oob_poi; in mxc_nand_read_page_raw()
844 return host->devtype_data->read_page(chip, buf, oob_buf, 0, page); in mxc_nand_read_page_raw()
851 return host->devtype_data->read_page(chip, NULL, chip->oob_poi, 0, in mxc_nand_read_oob()
861 host->devtype_data->enable_hwecc(chip, ecc); in mxc_nand_write_page()
863 host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false); in mxc_nand_write_page()
866 memcpy32_toio(host->main_area0, buf, mtd->writesize); in mxc_nand_write_page()
867 copy_spare(mtd, false, chip->oob_poi); in mxc_nand_write_page()
869 host->devtype_data->send_page(mtd, NFC_INPUT); in mxc_nand_write_page()
870 host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true); in mxc_nand_write_page()
893 memset(host->data_buf, 0xff, mtd->writesize); in mxc_nand_write_oob()
895 return mxc_nand_write_page(chip, host->data_buf, false, page); in mxc_nand_write_oob()
904 if (host->status_request) in mxc_nand_read_byte()
905 return host->devtype_data->get_dev_status(host) & 0xFF; in mxc_nand_read_byte()
907 if (nand_chip->options & NAND_BUSWIDTH_16) { in mxc_nand_read_byte()
909 ret = *(uint16_t *)(host->data_buf + host->buf_start); in mxc_nand_read_byte()
911 host->buf_start += 2; in mxc_nand_read_byte()
913 ret = *(uint8_t *)(host->data_buf + host->buf_start); in mxc_nand_read_byte()
914 host->buf_start++; in mxc_nand_read_byte()
917 dev_dbg(host->dev, "%s: ret=0x%hhx (start=%u)\n", __func__, ret, host->buf_start); in mxc_nand_read_byte()
929 u16 col = host->buf_start; in mxc_nand_write_buf()
930 int n = mtd->oobsize + mtd->writesize - col; in mxc_nand_write_buf()
934 memcpy(host->data_buf + col, buf, n); in mxc_nand_write_buf()
936 host->buf_start += n; in mxc_nand_write_buf()
948 u16 col = host->buf_start; in mxc_nand_read_buf()
949 int n = mtd->oobsize + mtd->writesize - col; in mxc_nand_read_buf()
953 memcpy(buf, host->data_buf + col, n); in mxc_nand_read_buf()
955 host->buf_start += n; in mxc_nand_read_buf()
964 if (chip == -1) { in mxc_nand_select_chip_v1_v3()
966 if (host->clk_act) { in mxc_nand_select_chip_v1_v3()
967 clk_disable_unprepare(host->clk); in mxc_nand_select_chip_v1_v3()
968 host->clk_act = 0; in mxc_nand_select_chip_v1_v3()
973 if (!host->clk_act) { in mxc_nand_select_chip_v1_v3()
975 clk_prepare_enable(host->clk); in mxc_nand_select_chip_v1_v3()
976 host->clk_act = 1; in mxc_nand_select_chip_v1_v3()
984 if (chip == -1) { in mxc_nand_select_chip_v2()
986 if (host->clk_act) { in mxc_nand_select_chip_v2()
987 clk_disable_unprepare(host->clk); in mxc_nand_select_chip_v2()
988 host->clk_act = 0; in mxc_nand_select_chip_v2()
993 if (!host->clk_act) { in mxc_nand_select_chip_v2()
995 clk_prepare_enable(host->clk); in mxc_nand_select_chip_v2()
996 host->clk_act = 1; in mxc_nand_select_chip_v2()
999 host->active_cs = chip; in mxc_nand_select_chip_v2()
1000 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); in mxc_nand_select_chip_v2()
1010 if (section >= nand_chip->ecc.steps) in mxc_v1_ooblayout_ecc()
1011 return -ERANGE; in mxc_v1_ooblayout_ecc()
1013 oobregion->offset = (section * 16) + 6; in mxc_v1_ooblayout_ecc()
1014 oobregion->length = MXC_V1_ECCBYTES; in mxc_v1_ooblayout_ecc()
1024 if (section > nand_chip->ecc.steps) in mxc_v1_ooblayout_free()
1025 return -ERANGE; in mxc_v1_ooblayout_free()
1028 if (mtd->writesize <= 512) { in mxc_v1_ooblayout_free()
1029 oobregion->offset = 0; in mxc_v1_ooblayout_free()
1030 oobregion->length = 5; in mxc_v1_ooblayout_free()
1032 oobregion->offset = 2; in mxc_v1_ooblayout_free()
1033 oobregion->length = 4; in mxc_v1_ooblayout_free()
1036 oobregion->offset = ((section - 1) * 16) + MXC_V1_ECCBYTES + 6; in mxc_v1_ooblayout_free()
1037 if (section < nand_chip->ecc.steps) in mxc_v1_ooblayout_free()
1038 oobregion->length = (section * 16) + 6 - in mxc_v1_ooblayout_free()
1039 oobregion->offset; in mxc_v1_ooblayout_free()
1041 oobregion->length = mtd->oobsize - oobregion->offset; in mxc_v1_ooblayout_free()
1056 int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; in mxc_v2_ooblayout_ecc()
1058 if (section >= nand_chip->ecc.steps) in mxc_v2_ooblayout_ecc()
1059 return -ERANGE; in mxc_v2_ooblayout_ecc()
1061 oobregion->offset = (section * stepsize) + 7; in mxc_v2_ooblayout_ecc()
1062 oobregion->length = nand_chip->ecc.bytes; in mxc_v2_ooblayout_ecc()
1071 int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; in mxc_v2_ooblayout_free()
1073 if (section >= nand_chip->ecc.steps) in mxc_v2_ooblayout_free()
1074 return -ERANGE; in mxc_v2_ooblayout_free()
1077 if (mtd->writesize <= 512) { in mxc_v2_ooblayout_free()
1078 oobregion->offset = 0; in mxc_v2_ooblayout_free()
1079 oobregion->length = 5; in mxc_v2_ooblayout_free()
1081 oobregion->offset = 2; in mxc_v2_ooblayout_free()
1082 oobregion->length = 4; in mxc_v2_ooblayout_free()
1085 oobregion->offset = section * stepsize; in mxc_v2_ooblayout_free()
1086 oobregion->length = 7; in mxc_v2_ooblayout_free()
1106 oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize; in get_eccsize()
1120 if (nand_chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST && in preset_v1()
1121 mtd->writesize) in preset_v1()
1124 if (!host->devtype_data->irqpending_quirk) in preset_v1()
1127 host->eccsize = 1; in preset_v1()
1154 return -ENOTSUPP; in mxc_nand_v2_setup_interface()
1158 tRC_min_ns = timings->tRC_min / 1000; in mxc_nand_v2_setup_interface()
1168 rate_round = clk_round_rate(host->clk, rate); in mxc_nand_v2_setup_interface()
1173 rate_round = clk_round_rate(host->clk, rate); in mxc_nand_v2_setup_interface()
1182 if (timings->tCLS_min > tRC_ps - 1000 || in mxc_nand_v2_setup_interface()
1183 timings->tCLH_min > tRC_ps - 2000 || in mxc_nand_v2_setup_interface()
1184 timings->tCS_min > tRC_ps - 1000 || in mxc_nand_v2_setup_interface()
1185 timings->tCH_min > tRC_ps - 2000 || in mxc_nand_v2_setup_interface()
1186 timings->tWP_min > tRC_ps - 1500 || in mxc_nand_v2_setup_interface()
1187 timings->tALS_min > tRC_ps || in mxc_nand_v2_setup_interface()
1188 timings->tALH_min > tRC_ps - 3000 || in mxc_nand_v2_setup_interface()
1189 timings->tDS_min > tRC_ps || in mxc_nand_v2_setup_interface()
1190 timings->tDH_min > tRC_ps - 5000 || in mxc_nand_v2_setup_interface()
1191 timings->tWC_min > 2 * tRC_ps || in mxc_nand_v2_setup_interface()
1192 timings->tWH_min > tRC_ps - 2500 || in mxc_nand_v2_setup_interface()
1193 timings->tRR_min > 6 * tRC_ps || in mxc_nand_v2_setup_interface()
1194 timings->tRP_min > 3 * tRC_ps / 2 || in mxc_nand_v2_setup_interface()
1195 timings->tRC_min > 2 * tRC_ps || in mxc_nand_v2_setup_interface()
1196 timings->tREH_min > (tRC_ps / 2) - 2500) { in mxc_nand_v2_setup_interface()
1197 dev_dbg(host->dev, "Timing out of bounds\n"); in mxc_nand_v2_setup_interface()
1198 return -EINVAL; in mxc_nand_v2_setup_interface()
1204 ret = clk_set_rate(host->clk, rate); in mxc_nand_v2_setup_interface()
1210 dev_dbg(host->dev, "Setting rate to %ldHz, %s mode\n", rate_round, in mxc_nand_v2_setup_interface()
1225 if (!host->devtype_data->irqpending_quirk) in preset_v2()
1228 if (mtd->writesize) { in preset_v2()
1229 uint16_t pages_per_block = mtd->erasesize / mtd->writesize; in preset_v2()
1231 if (nand_chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) in preset_v2()
1234 host->eccsize = get_eccsize(mtd); in preset_v2()
1235 if (host->eccsize == 4) in preset_v2()
1238 config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6); in preset_v2()
1240 host->eccsize = 1; in preset_v2()
1246 /* spare area size in 16-bit half-words */ in preset_v2()
1247 writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA); in preset_v2()
1288 NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) | in preset_v3()
1293 addr_phases = fls(chip->pagemask) >> 3; in preset_v3()
1295 if (mtd->writesize == 2048) { in preset_v3()
1298 } else if (mtd->writesize == 4096) { in preset_v3()
1303 config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1); in preset_v3()
1306 if (mtd->writesize) { in preset_v3()
1307 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) in preset_v3()
1311 ffs(mtd->erasesize / mtd->writesize) - 6, in preset_v3()
1312 host->devtype_data->ppb_shift); in preset_v3()
1313 host->eccsize = get_eccsize(mtd); in preset_v3()
1314 if (host->eccsize == 8) in preset_v3()
1326 if (!(chip->options & NAND_BUSWIDTH_16)) in preset_v3()
1342 dev_dbg(host->dev, "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", in mxc_nand_command()
1346 host->status_request = false; in mxc_nand_command()
1348 /* Command pre-processing step */ in mxc_nand_command()
1351 host->devtype_data->preset(mtd); in mxc_nand_command()
1352 host->devtype_data->send_cmd(host, command, false); in mxc_nand_command()
1356 host->buf_start = 0; in mxc_nand_command()
1357 host->status_request = true; in mxc_nand_command()
1359 host->devtype_data->send_cmd(host, command, true); in mxc_nand_command()
1360 WARN_ONCE(column != -1 || page_addr != -1, in mxc_nand_command()
1367 host->devtype_data->send_cmd(host, command, true); in mxc_nand_command()
1369 host->devtype_data->send_read_id(host); in mxc_nand_command()
1370 host->buf_start = 0; in mxc_nand_command()
1375 host->devtype_data->send_cmd(host, command, false); in mxc_nand_command()
1376 WARN_ONCE(column != -1, in mxc_nand_command()
1383 host->devtype_data->send_cmd(host, command, false); in mxc_nand_command()
1385 host->devtype_data->send_page(mtd, NFC_OUTPUT); in mxc_nand_command()
1386 memcpy32_fromio(host->data_buf, host->main_area0, 512); in mxc_nand_command()
1387 host->buf_start = 0; in mxc_nand_command()
1403 host->buf_start = 0; in mxc_nand_set_features()
1406 chip->legacy.write_byte(chip, subfeature_param[i]); in mxc_nand_set_features()
1408 memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); in mxc_nand_set_features()
1409 host->devtype_data->send_cmd(host, NAND_CMD_SET_FEATURES, false); in mxc_nand_set_features()
1410 mxc_do_addr_cycle(mtd, addr, -1); in mxc_nand_set_features()
1411 host->devtype_data->send_page(mtd, NFC_INPUT); in mxc_nand_set_features()
1423 host->devtype_data->send_cmd(host, NAND_CMD_GET_FEATURES, false); in mxc_nand_get_features()
1424 mxc_do_addr_cycle(mtd, addr, -1); in mxc_nand_get_features()
1425 host->devtype_data->send_page(mtd, NFC_OUTPUT); in mxc_nand_get_features()
1426 memcpy32_fromio(host->data_buf, host->main_area0, 512); in mxc_nand_get_features()
1427 host->buf_start = 0; in mxc_nand_get_features()
1430 *subfeature_param++ = chip->legacy.read_byte(chip); in mxc_nand_get_features()
1591 return host->devtype_data == &imx21_nand_devtype_data; in is_imx21_nfc()
1596 return host->devtype_data == &imx27_nand_devtype_data; in is_imx27_nfc()
1601 return host->devtype_data == &imx25_nand_devtype_data; in is_imx25_nfc()
1606 return host->devtype_data == &imx51_nand_devtype_data; in is_imx51_nfc()
1611 return host->devtype_data == &imx53_nand_devtype_data; in is_imx53_nfc()
1616 .name = "imx21-nand",
1619 .name = "imx27-nand",
1622 .name = "imx25-nand",
1625 .name = "imx51-nand",
1628 .name = "imx53-nand",
1639 .compatible = "fsl,imx21-nand",
1642 .compatible = "fsl,imx27-nand",
1645 .compatible = "fsl,imx25-nand",
1648 .compatible = "fsl,imx51-nand",
1651 .compatible = "fsl,imx53-nand",
1660 struct device_node *np = host->dev->of_node; in mxcnd_probe_dt()
1662 of_match_device(mxcnd_dt_ids, host->dev); in mxcnd_probe_dt()
1667 host->devtype_data = of_id->data; in mxcnd_probe_dt()
1682 struct device *dev = mtd->dev.parent; in mxcnd_attach_chip()
1684 chip->ecc.bytes = host->devtype_data->eccbytes; in mxcnd_attach_chip()
1685 host->eccsize = host->devtype_data->eccsize; in mxcnd_attach_chip()
1686 chip->ecc.size = 512; in mxcnd_attach_chip()
1687 mtd_set_ooblayout(mtd, host->devtype_data->ooblayout); in mxcnd_attach_chip()
1689 switch (chip->ecc.engine_type) { in mxcnd_attach_chip()
1691 chip->ecc.read_page = mxc_nand_read_page; in mxcnd_attach_chip()
1692 chip->ecc.read_page_raw = mxc_nand_read_page_raw; in mxcnd_attach_chip()
1693 chip->ecc.read_oob = mxc_nand_read_oob; in mxcnd_attach_chip()
1694 chip->ecc.write_page = mxc_nand_write_page_ecc; in mxcnd_attach_chip()
1695 chip->ecc.write_page_raw = mxc_nand_write_page_raw; in mxcnd_attach_chip()
1696 chip->ecc.write_oob = mxc_nand_write_oob; in mxcnd_attach_chip()
1703 return -EINVAL; in mxcnd_attach_chip()
1706 if (chip->bbt_options & NAND_BBT_USE_FLASH) { in mxcnd_attach_chip()
1707 chip->bbt_td = &bbt_main_descr; in mxcnd_attach_chip()
1708 chip->bbt_md = &bbt_mirror_descr; in mxcnd_attach_chip()
1712 devm_kfree(dev, (void *)host->data_buf); in mxcnd_attach_chip()
1713 host->data_buf = devm_kzalloc(dev, mtd->writesize + mtd->oobsize, in mxcnd_attach_chip()
1715 if (!host->data_buf) in mxcnd_attach_chip()
1716 return -ENOMEM; in mxcnd_attach_chip()
1719 host->devtype_data->preset(mtd); in mxcnd_attach_chip()
1721 if (!chip->ecc.bytes) { in mxcnd_attach_chip()
1722 if (host->eccsize == 8) in mxcnd_attach_chip()
1723 chip->ecc.bytes = 18; in mxcnd_attach_chip()
1724 else if (host->eccsize == 4) in mxcnd_attach_chip()
1725 chip->ecc.bytes = 9; in mxcnd_attach_chip()
1732 * might cause ECC data corruption when doing sub-page write to a in mxcnd_attach_chip()
1735 host->used_oobsize = min(mtd->oobsize, 218U); in mxcnd_attach_chip()
1737 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) { in mxcnd_attach_chip()
1739 chip->ecc.strength = 1; in mxcnd_attach_chip()
1741 chip->ecc.strength = (host->eccsize == 4) ? 4 : 8; in mxcnd_attach_chip()
1752 return host->devtype_data->setup_interface(chip, chipnr, conf); in mxcnd_setup_interface()
1769 host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host), in mxcnd_probe()
1772 return -ENOMEM; in mxcnd_probe()
1775 host->data_buf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL); in mxcnd_probe()
1776 if (!host->data_buf) in mxcnd_probe()
1777 return -ENOMEM; in mxcnd_probe()
1779 host->dev = &pdev->dev; in mxcnd_probe()
1781 this = &host->nand; in mxcnd_probe()
1783 mtd->dev.parent = &pdev->dev; in mxcnd_probe()
1784 mtd->name = DRIVER_NAME; in mxcnd_probe()
1787 this->legacy.chip_delay = 5; in mxcnd_probe()
1790 nand_set_flash_node(this, pdev->dev.of_node), in mxcnd_probe()
1791 this->legacy.dev_ready = mxc_nand_dev_ready; in mxcnd_probe()
1792 this->legacy.cmdfunc = mxc_nand_command; in mxcnd_probe()
1793 this->legacy.read_byte = mxc_nand_read_byte; in mxcnd_probe()
1794 this->legacy.write_buf = mxc_nand_write_buf; in mxcnd_probe()
1795 this->legacy.read_buf = mxc_nand_read_buf; in mxcnd_probe()
1796 this->legacy.set_features = mxc_nand_set_features; in mxcnd_probe()
1797 this->legacy.get_features = mxc_nand_get_features; in mxcnd_probe()
1799 host->clk = devm_clk_get(&pdev->dev, NULL); in mxcnd_probe()
1800 if (IS_ERR(host->clk)) in mxcnd_probe()
1801 return PTR_ERR(host->clk); in mxcnd_probe()
1806 dev_get_platdata(&pdev->dev); in mxcnd_probe()
1808 host->pdata = *pdata; in mxcnd_probe()
1809 host->devtype_data = (struct mxc_nand_devtype_data *) in mxcnd_probe()
1810 pdev->id_entry->driver_data; in mxcnd_probe()
1812 err = -ENODEV; in mxcnd_probe()
1818 if (!host->devtype_data->setup_interface) in mxcnd_probe()
1819 this->options |= NAND_KEEP_TIMINGS; in mxcnd_probe()
1821 if (host->devtype_data->needs_ip) { in mxcnd_probe()
1823 host->regs_ip = devm_ioremap_resource(&pdev->dev, res); in mxcnd_probe()
1824 if (IS_ERR(host->regs_ip)) in mxcnd_probe()
1825 return PTR_ERR(host->regs_ip); in mxcnd_probe()
1832 host->base = devm_ioremap_resource(&pdev->dev, res); in mxcnd_probe()
1833 if (IS_ERR(host->base)) in mxcnd_probe()
1834 return PTR_ERR(host->base); in mxcnd_probe()
1836 host->main_area0 = host->base; in mxcnd_probe()
1838 if (host->devtype_data->regs_offset) in mxcnd_probe()
1839 host->regs = host->base + host->devtype_data->regs_offset; in mxcnd_probe()
1840 host->spare0 = host->base + host->devtype_data->spare0_offset; in mxcnd_probe()
1841 if (host->devtype_data->axi_offset) in mxcnd_probe()
1842 host->regs_axi = host->base + host->devtype_data->axi_offset; in mxcnd_probe()
1844 this->legacy.select_chip = host->devtype_data->select_chip; in mxcnd_probe()
1847 if (host->pdata.width == 2) in mxcnd_probe()
1848 this->options |= NAND_BUSWIDTH_16; in mxcnd_probe()
1851 if (host->pdata.flash_bbt) in mxcnd_probe()
1852 this->bbt_options |= NAND_BBT_USE_FLASH; in mxcnd_probe()
1854 init_completion(&host->op_completion); in mxcnd_probe()
1856 host->irq = platform_get_irq(pdev, 0); in mxcnd_probe()
1857 if (host->irq < 0) in mxcnd_probe()
1858 return host->irq; in mxcnd_probe()
1861 * Use host->devtype_data->irq_control() here instead of irq_control() in mxcnd_probe()
1865 host->devtype_data->irq_control(host, 0); in mxcnd_probe()
1867 err = devm_request_irq(&pdev->dev, host->irq, mxc_nfc_irq, in mxcnd_probe()
1872 err = clk_prepare_enable(host->clk); in mxcnd_probe()
1875 host->clk_act = 1; in mxcnd_probe()
1882 if (host->devtype_data->irqpending_quirk) { in mxcnd_probe()
1883 disable_irq_nosync(host->irq); in mxcnd_probe()
1884 host->devtype_data->irq_control(host, 1); in mxcnd_probe()
1888 this->legacy.dummy_controller.ops = &mxcnd_controller_ops; in mxcnd_probe()
1895 host->pdata.parts, in mxcnd_probe()
1896 host->pdata.nr_parts); in mxcnd_probe()
1907 if (host->clk_act) in mxcnd_probe()
1908 clk_disable_unprepare(host->clk); in mxcnd_probe()
1916 struct nand_chip *chip = &host->nand; in mxcnd_remove()
1922 if (host->clk_act) in mxcnd_remove()
1923 clk_disable_unprepare(host->clk); in mxcnd_remove()