Lines Matching +full:clk +full:- +full:out +full:- +full:strength
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
10 #include <linux/dma-mapping.h>
12 #include <linux/clk.h>
13 #include <linux/clk-provider.h>
84 #define ECC_CHECK_RETURN_FF (-1)
143 u32 strength; member
170 struct clk *core_clk;
171 struct clk *device_clk;
172 struct clk *nand_clk;
209 #define MESON_ECC_DATA(b, s, sz) { .bch = (b), .strength = (s), .size = (sz) }
221 static int meson_nand_calc_ecc_bytes(int step_size, int strength) in meson_nand_calc_ecc_bytes() argument
225 if (step_size == 512 && strength == 8) in meson_nand_calc_ecc_bytes()
228 ecc_bytes = DIV_ROUND_UP(strength * fls(step_size * 8), 8); in meson_nand_calc_ecc_bytes()
269 if (chip < 0 || WARN_ON_ONCE(chip >= meson_chip->nsels)) in meson_nfc_select_chip()
272 nfc->param.chip_select = meson_chip->sels[chip] ? NAND_CE1 : NAND_CE0; in meson_nfc_select_chip()
273 nfc->param.rb_select = nfc->param.chip_select; in meson_nfc_select_chip()
274 nfc->timing.twb = meson_chip->twb; in meson_nfc_select_chip()
275 nfc->timing.tadl = meson_chip->tadl; in meson_nfc_select_chip()
276 nfc->timing.tbers_max = meson_chip->tbers_max; in meson_nfc_select_chip()
278 if (nfc->clk_rate != meson_chip->clk_rate) { in meson_nfc_select_chip()
279 ret = clk_set_rate(nfc->nand_clk, meson_chip->clk_rate); in meson_nfc_select_chip()
281 dev_err(nfc->dev, "failed to set clock rate\n"); in meson_nfc_select_chip()
284 nfc->clk_rate = meson_chip->clk_rate; in meson_nfc_select_chip()
286 if (nfc->bus_timing != meson_chip->bus_timing) { in meson_nfc_select_chip()
287 value = (NFC_CLK_CYCLE - 1) | (meson_chip->bus_timing << 5); in meson_nfc_select_chip()
288 writel(value, nfc->reg_base + NFC_REG_CFG); in meson_nfc_select_chip()
289 writel((1 << 31), nfc->reg_base + NFC_REG_CMD); in meson_nfc_select_chip()
290 nfc->bus_timing = meson_chip->bus_timing; in meson_nfc_select_chip()
296 writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff), in meson_nfc_cmd_idle()
297 nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_idle()
303 nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_seed()
310 return (nand->options & NAND_IS_BOOT_MEDIUM) && in meson_nfc_is_boot_page()
311 !(page % meson_chip->boot_page_step) && in meson_nfc_is_boot_page()
312 (page < meson_chip->boot_pages); in meson_nfc_is_boot_page()
320 int len = mtd->writesize, pagesize, pages; in meson_nfc_cmd_access()
324 if (nand->options & NAND_NEED_SCRAMBLING) in meson_nfc_cmd_access()
330 len = mtd->writesize + mtd->oobsize; in meson_nfc_cmd_access()
334 pages = mtd->writesize / 512; in meson_nfc_cmd_access()
340 pagesize = nand->ecc.size >> 3; in meson_nfc_cmd_access()
341 pages = len / nand->ecc.size; in meson_nfc_cmd_access()
343 cmd = CMDRWGEN(DMA_DIR(dir), scrambler, meson_chip->bch_mode, in meson_nfc_cmd_access()
350 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_access()
358 * The Nand flash controller is designed as two stages pipleline - in meson_nfc_drain_cmd()
377 ret = readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size, in meson_nfc_wait_cmd_finish()
381 dev_err(nfc->dev, "wait for empty CMD FIFO time out\n"); in meson_nfc_wait_cmd_finish()
398 len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i; in meson_nfc_oob_ptr()
400 return meson_chip->data_buf + len; in meson_nfc_oob_ptr()
408 temp = nand->ecc.size + nand->ecc.bytes; in meson_nfc_data_ptr()
411 return meson_chip->data_buf + len; in meson_nfc_data_ptr()
420 oob_len = nand->ecc.bytes + 2; in meson_nfc_get_data_oob()
421 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_get_data_oob()
424 memcpy(buf, dsrc, nand->ecc.size); in meson_nfc_get_data_oob()
425 buf += nand->ecc.size; in meson_nfc_get_data_oob()
439 oob_len = nand->ecc.bytes + 2; in meson_nfc_set_data_oob()
440 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_set_data_oob()
443 memcpy(dsrc, buf, nand->ecc.size); in meson_nfc_set_data_oob()
444 buf += nand->ecc.size; in meson_nfc_set_data_oob()
458 meson_nfc_cmd_idle(nfc, nfc->timing.twb); in meson_nfc_wait_no_rb_pin()
462 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_no_rb_pin()
464 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_no_rb_pin()
466 reinit_completion(&nfc->completion); in meson_nfc_wait_no_rb_pin()
470 cmd = NFC_CMD_RB | NFC_CMD_RB_INT_NO_PIN | nfc->timing.tbers_max; in meson_nfc_wait_no_rb_pin()
471 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_wait_no_rb_pin()
473 if (!wait_for_completion_timeout(&nfc->completion, in meson_nfc_wait_no_rb_pin()
475 return -ETIMEDOUT; in meson_nfc_wait_no_rb_pin()
488 meson_nfc_cmd_idle(nfc, nfc->timing.twb); in meson_nfc_wait_rb_pin()
492 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_rb_pin()
494 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_rb_pin()
496 reinit_completion(&nfc->completion); in meson_nfc_wait_rb_pin()
500 | nfc->param.chip_select | nfc->timing.tbers_max; in meson_nfc_wait_rb_pin()
501 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_wait_rb_pin()
503 ret = wait_for_completion_timeout(&nfc->completion, in meson_nfc_wait_rb_pin()
506 ret = -1; in meson_nfc_wait_rb_pin()
516 if (nfc->no_rb_pin) { in meson_nfc_queue_rb()
520 * it will wait for interrupt - controllers checks IO in meson_nfc_queue_rb()
524 * needed (for all cases except page programming - this in meson_nfc_queue_rb()
540 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) { in meson_nfc_set_user_byte()
541 info = &meson_chip->info_buf[i]; in meson_nfc_set_user_byte()
553 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) { in meson_nfc_get_user_byte()
554 info = &meson_chip->info_buf[i]; in meson_nfc_get_user_byte()
568 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_ecc_correct()
569 info = &meson_chip->info_buf[i]; in meson_nfc_ecc_correct()
571 mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); in meson_nfc_ecc_correct()
576 if ((nand->options & NAND_NEED_SCRAMBLING) && in meson_nfc_ecc_correct()
577 ECC_ZERO_CNT(*info) < nand->ecc.strength) { in meson_nfc_ecc_correct()
578 mtd->ecc_stats.corrected += ECC_ZERO_CNT(*info); in meson_nfc_ecc_correct()
583 ret = -EBADMSG; in meson_nfc_ecc_correct()
597 nfc->daddr = dma_map_single(nfc->dev, databuf, datalen, dir); in meson_nfc_dma_buffer_setup()
598 ret = dma_mapping_error(nfc->dev, nfc->daddr); in meson_nfc_dma_buffer_setup()
600 dev_err(nfc->dev, "DMA mapping error\n"); in meson_nfc_dma_buffer_setup()
603 cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr); in meson_nfc_dma_buffer_setup()
604 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
606 cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr); in meson_nfc_dma_buffer_setup()
607 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
610 nfc->iaddr = dma_map_single(nfc->dev, infobuf, infolen, dir); in meson_nfc_dma_buffer_setup()
611 ret = dma_mapping_error(nfc->dev, nfc->iaddr); in meson_nfc_dma_buffer_setup()
613 dev_err(nfc->dev, "DMA mapping error\n"); in meson_nfc_dma_buffer_setup()
614 dma_unmap_single(nfc->dev, in meson_nfc_dma_buffer_setup()
615 nfc->daddr, datalen, dir); in meson_nfc_dma_buffer_setup()
618 nfc->info_bytes = infolen; in meson_nfc_dma_buffer_setup()
619 cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); in meson_nfc_dma_buffer_setup()
620 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
622 cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr); in meson_nfc_dma_buffer_setup()
623 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
635 dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); in meson_nfc_dma_buffer_release()
637 dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); in meson_nfc_dma_buffer_release()
638 nfc->info_bytes = 0; in meson_nfc_dma_buffer_release()
651 return -ENOMEM; in meson_nfc_read_buf()
656 goto out; in meson_nfc_read_buf()
659 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_read_buf()
665 out: in meson_nfc_read_buf()
683 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_write_buf()
699 u32 *addrs = nfc->cmdfifo.rw.addrs; in meson_nfc_rw_cmd_prepare_and_execute()
700 u32 cs = nfc->param.chip_select; in meson_nfc_rw_cmd_prepare_and_execute()
707 nfc->cmdfifo.rw.cmd0 = cs | NFC_CMD_CLE | cmd0; in meson_nfc_rw_cmd_prepare_and_execute()
710 if (mtd->writesize <= 512) { in meson_nfc_rw_cmd_prepare_and_execute()
711 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
721 if (nand->options & NAND_ROW_ADDR_3) in meson_nfc_rw_cmd_prepare_and_execute()
725 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
728 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
731 writel_relaxed(nfc->cmdfifo.cmd[i], in meson_nfc_rw_cmd_prepare_and_execute()
732 nfc->reg_base + NFC_REG_CMD); in meson_nfc_rw_cmd_prepare_and_execute()
735 nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART; in meson_nfc_rw_cmd_prepare_and_execute()
736 writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD); in meson_nfc_rw_cmd_prepare_and_execute()
737 meson_nfc_queue_rb(nand, PSEC_TO_MSEC(sdr->tR_max), true); in meson_nfc_rw_cmd_prepare_and_execute()
739 meson_nfc_cmd_idle(nfc, nfc->timing.tadl); in meson_nfc_rw_cmd_prepare_and_execute()
757 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_write_page_sub()
759 data_len = mtd->writesize + mtd->oobsize; in meson_nfc_write_page_sub()
760 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_write_page_sub()
766 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_write_page_sub()
767 data_len, meson_chip->info_buf, in meson_nfc_write_page_sub()
774 cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG; in meson_nfc_write_page_sub()
775 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_write_page_sub()
776 meson_nfc_queue_rb(nand, PSEC_TO_MSEC(sdr->tPROG_max), false); in meson_nfc_write_page_sub()
786 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_raw()
798 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_hwecc()
800 memcpy(meson_chip->data_buf, buf, mtd->writesize); in meson_nfc_write_page_hwecc()
801 memset(meson_chip->info_buf, 0, nand->ecc.steps * PER_INFO_BYTE); in meson_nfc_write_page_hwecc()
815 neccpages = raw ? 1 : nand->ecc.steps; in meson_nfc_check_ecc_pages_valid()
816 info = &meson_chip->info_buf[neccpages - 1]; in meson_nfc_check_ecc_pages_valid()
821 dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes, in meson_nfc_check_ecc_pages_valid()
836 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_read_page_sub()
838 data_len = mtd->writesize + mtd->oobsize; in meson_nfc_read_page_sub()
839 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_read_page_sub()
845 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_read_page_sub()
846 data_len, meson_chip->info_buf, in meson_nfc_read_page_sub()
864 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_raw()
881 struct nand_ecc_ctrl *ecc = &nand->ecc; in meson_nfc_read_page_hwecc()
884 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_hwecc()
895 memset(buf, 0xff, mtd->writesize); in meson_nfc_read_page_hwecc()
896 memset(oob_buf, 0xff, mtd->oobsize); in meson_nfc_read_page_hwecc()
898 if ((nand->options & NAND_NEED_SCRAMBLING) || !buf) { in meson_nfc_read_page_hwecc()
899 mtd->ecc_stats.failed++; in meson_nfc_read_page_hwecc()
906 for (i = 0; i < nand->ecc.steps ; i++) { in meson_nfc_read_page_hwecc()
907 u8 *data = buf + i * ecc->size; in meson_nfc_read_page_hwecc()
908 u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); in meson_nfc_read_page_hwecc()
912 ret = nand_check_erased_ecc_chunk(data, ecc->size, in meson_nfc_read_page_hwecc()
913 oob, ecc->bytes + 2, in meson_nfc_read_page_hwecc()
915 ecc->strength); in meson_nfc_read_page_hwecc()
917 mtd->ecc_stats.failed++; in meson_nfc_read_page_hwecc()
919 mtd->ecc_stats.corrected += ret; in meson_nfc_read_page_hwecc()
923 } else if (buf && buf != meson_chip->data_buf) { in meson_nfc_read_page_hwecc()
924 memcpy(buf, meson_chip->data_buf, mtd->writesize); in meson_nfc_read_page_hwecc()
953 if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR)) in meson_nand_op_get_dma_safe_input_buf()
956 if (meson_nfc_is_buffer_dma_safe(instr->ctx.data.buf.in)) in meson_nand_op_get_dma_safe_input_buf()
957 return instr->ctx.data.buf.in; in meson_nand_op_get_dma_safe_input_buf()
959 return kzalloc(instr->ctx.data.len, GFP_KERNEL); in meson_nand_op_get_dma_safe_input_buf()
966 if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR) || in meson_nand_op_put_dma_safe_input_buf()
970 if (buf == instr->ctx.data.buf.in) in meson_nand_op_put_dma_safe_input_buf()
973 memcpy(instr->ctx.data.buf.in, buf, instr->ctx.data.len); in meson_nand_op_put_dma_safe_input_buf()
980 if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR)) in meson_nand_op_get_dma_safe_output_buf()
983 if (meson_nfc_is_buffer_dma_safe(instr->ctx.data.buf.out)) in meson_nand_op_get_dma_safe_output_buf()
984 return (void *)instr->ctx.data.buf.out; in meson_nand_op_get_dma_safe_output_buf()
986 return kmemdup(instr->ctx.data.buf.out, in meson_nand_op_get_dma_safe_output_buf()
987 instr->ctx.data.len, GFP_KERNEL); in meson_nand_op_get_dma_safe_output_buf()
994 if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR) || in meson_nand_op_put_dma_safe_output_buf()
998 if (buf != instr->ctx.data.buf.out) in meson_nand_op_put_dma_safe_output_buf()
1007 for (op_id = 0; op_id < op->ninstrs; op_id++) { in meson_nfc_check_op()
1010 instr = &op->instrs[op_id]; in meson_nfc_check_op()
1012 switch (instr->type) { in meson_nfc_check_op()
1015 if (instr->ctx.data.len > NFC_CMD_RAW_LEN) in meson_nfc_check_op()
1016 return -ENOTSUPP; in meson_nfc_check_op()
1045 meson_nfc_select_chip(nand, op->cs); in meson_nfc_exec_op()
1046 for (op_id = 0; op_id < op->ninstrs; op_id++) { in meson_nfc_exec_op()
1047 instr = &op->instrs[op_id]; in meson_nfc_exec_op()
1048 delay_idle = DIV_ROUND_UP(PSEC_TO_NSEC(instr->delay_ns), in meson_nfc_exec_op()
1049 meson_chip->level1_divider * in meson_nfc_exec_op()
1051 switch (instr->type) { in meson_nfc_exec_op()
1053 cmd = nfc->param.chip_select | NFC_CMD_CLE; in meson_nfc_exec_op()
1054 cmd |= instr->ctx.cmd.opcode & 0xff; in meson_nfc_exec_op()
1055 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_exec_op()
1060 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in meson_nfc_exec_op()
1061 cmd = nfc->param.chip_select | NFC_CMD_ALE; in meson_nfc_exec_op()
1062 cmd |= instr->ctx.addr.addrs[i] & 0xff; in meson_nfc_exec_op()
1063 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_exec_op()
1071 return -ENOMEM; in meson_nfc_exec_op()
1072 meson_nfc_read_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
1079 return -ENOMEM; in meson_nfc_exec_op()
1080 meson_nfc_write_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
1085 meson_nfc_queue_rb(nand, instr->ctx.waitrdy.timeout_ms, in meson_nfc_exec_op()
1087 if (instr->delay_ns) in meson_nfc_exec_op()
1101 if (section >= nand->ecc.steps) in meson_ooblayout_ecc()
1102 return -ERANGE; in meson_ooblayout_ecc()
1104 oobregion->offset = 2 + (section * (2 + nand->ecc.bytes)); in meson_ooblayout_ecc()
1105 oobregion->length = nand->ecc.bytes; in meson_ooblayout_ecc()
1115 if (section >= nand->ecc.steps) in meson_ooblayout_free()
1116 return -ERANGE; in meson_ooblayout_free()
1118 oobregion->offset = section * (2 + nand->ecc.bytes); in meson_ooblayout_free()
1119 oobregion->length = 2; in meson_ooblayout_free()
1136 nfc->core_clk = devm_clk_get(nfc->dev, "core"); in meson_nfc_clk_init()
1137 if (IS_ERR(nfc->core_clk)) { in meson_nfc_clk_init()
1138 dev_err(nfc->dev, "failed to get core clock\n"); in meson_nfc_clk_init()
1139 return PTR_ERR(nfc->core_clk); in meson_nfc_clk_init()
1142 nfc->device_clk = devm_clk_get(nfc->dev, "device"); in meson_nfc_clk_init()
1143 if (IS_ERR(nfc->device_clk)) { in meson_nfc_clk_init()
1144 dev_err(nfc->dev, "failed to get device clock\n"); in meson_nfc_clk_init()
1145 return PTR_ERR(nfc->device_clk); in meson_nfc_clk_init()
1148 init.name = devm_kasprintf(nfc->dev, in meson_nfc_clk_init()
1150 dev_name(nfc->dev)); in meson_nfc_clk_init()
1152 return -ENOMEM; in meson_nfc_clk_init()
1158 nfc->nand_divider.reg = nfc->reg_clk; in meson_nfc_clk_init()
1159 nfc->nand_divider.shift = CLK_DIV_SHIFT; in meson_nfc_clk_init()
1160 nfc->nand_divider.width = CLK_DIV_WIDTH; in meson_nfc_clk_init()
1161 nfc->nand_divider.hw.init = &init; in meson_nfc_clk_init()
1162 nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED | in meson_nfc_clk_init()
1166 nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw); in meson_nfc_clk_init()
1167 if (IS_ERR(nfc->nand_clk)) in meson_nfc_clk_init()
1168 return PTR_ERR(nfc->nand_clk); in meson_nfc_clk_init()
1172 nfc->reg_clk); in meson_nfc_clk_init()
1174 ret = clk_prepare_enable(nfc->core_clk); in meson_nfc_clk_init()
1176 dev_err(nfc->dev, "failed to enable core clock\n"); in meson_nfc_clk_init()
1180 ret = clk_prepare_enable(nfc->device_clk); in meson_nfc_clk_init()
1182 dev_err(nfc->dev, "failed to enable device clock\n"); in meson_nfc_clk_init()
1186 ret = clk_prepare_enable(nfc->nand_clk); in meson_nfc_clk_init()
1188 dev_err(nfc->dev, "pre enable NFC divider fail\n"); in meson_nfc_clk_init()
1192 ret = clk_set_rate(nfc->nand_clk, 24000000); in meson_nfc_clk_init()
1199 clk_disable_unprepare(nfc->nand_clk); in meson_nfc_clk_init()
1201 clk_disable_unprepare(nfc->device_clk); in meson_nfc_clk_init()
1203 clk_disable_unprepare(nfc->core_clk); in meson_nfc_clk_init()
1209 clk_disable_unprepare(nfc->nand_clk); in meson_nfc_disable_clk()
1210 clk_disable_unprepare(nfc->device_clk); in meson_nfc_disable_clk()
1211 clk_disable_unprepare(nfc->core_clk); in meson_nfc_disable_clk()
1218 kfree(meson_chip->info_buf); in meson_nfc_free_buffer()
1219 kfree(meson_chip->data_buf); in meson_nfc_free_buffer()
1228 nsectors = mtd->writesize / nand->ecc.size; in meson_chip_buffer_init()
1230 page_bytes = mtd->writesize + mtd->oobsize; in meson_chip_buffer_init()
1233 meson_chip->data_buf = kmalloc(page_bytes, GFP_KERNEL); in meson_chip_buffer_init()
1234 if (!meson_chip->data_buf) in meson_chip_buffer_init()
1235 return -ENOMEM; in meson_chip_buffer_init()
1237 meson_chip->info_buf = kmalloc(info_bytes, GFP_KERNEL); in meson_chip_buffer_init()
1238 if (!meson_chip->info_buf) { in meson_chip_buffer_init()
1239 kfree(meson_chip->data_buf); in meson_chip_buffer_init()
1240 return -ENOMEM; in meson_chip_buffer_init()
1256 return -ENOTSUPP; in meson_nfc_setup_interface()
1261 div = DIV_ROUND_UP((timings->tRC_min / 1000), NFC_CLK_CYCLE); in meson_nfc_setup_interface()
1262 bt_min = (timings->tREA_max + NFC_DEFAULT_DELAY) / div; in meson_nfc_setup_interface()
1263 bt_max = (NFC_DEFAULT_DELAY + timings->tRHOH_min + in meson_nfc_setup_interface()
1264 timings->tRC_min / 2) / div; in meson_nfc_setup_interface()
1266 meson_chip->twb = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tWB_max), in meson_nfc_setup_interface()
1268 meson_chip->tadl = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tADL_min), in meson_nfc_setup_interface()
1270 tbers_clocks = DIV_ROUND_UP_ULL(PSEC_TO_NSEC(timings->tBERS_max), in meson_nfc_setup_interface()
1272 meson_chip->tbers_max = ilog2(tbers_clocks); in meson_nfc_setup_interface()
1274 meson_chip->tbers_max++; in meson_nfc_setup_interface()
1280 return -EINVAL; in meson_nfc_setup_interface()
1282 meson_chip->level1_divider = div; in meson_nfc_setup_interface()
1283 meson_chip->clk_rate = 1000000000 / meson_chip->level1_divider; in meson_nfc_setup_interface()
1284 meson_chip->bus_timing = (bt_min + bt_max) / 2 + 1; in meson_nfc_setup_interface()
1294 if (nand->ecc.strength > 60 || nand->ecc.strength < 8) in meson_nand_bch_mode()
1295 return -EINVAL; in meson_nand_bch_mode()
1298 if (meson_ecc[i].strength == nand->ecc.strength && in meson_nand_bch_mode()
1299 meson_ecc[i].size == nand->ecc.size) { in meson_nand_bch_mode()
1300 meson_chip->bch_mode = meson_ecc[i].bch; in meson_nand_bch_mode()
1305 return -EINVAL; in meson_nand_bch_mode()
1321 if (!mtd->name) { in meson_nand_attach_chip()
1322 mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL, in meson_nand_attach_chip()
1324 dev_name(nfc->dev), in meson_nand_attach_chip()
1325 meson_chip->sels[0]); in meson_nand_attach_chip()
1326 if (!mtd->name) in meson_nand_attach_chip()
1327 return -ENOMEM; in meson_nand_attach_chip()
1330 raw_writesize = mtd->writesize + mtd->oobsize; in meson_nand_attach_chip()
1332 dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n", in meson_nand_attach_chip()
1334 return -EINVAL; in meson_nand_attach_chip()
1337 if (nand->bbt_options & NAND_BBT_USE_FLASH) in meson_nand_attach_chip()
1338 nand->bbt_options |= NAND_BBT_NO_OOB; in meson_nand_attach_chip()
1340 nand->options |= NAND_NO_SUBPAGE_WRITE; in meson_nand_attach_chip()
1342 ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, in meson_nand_attach_chip()
1343 mtd->oobsize - 2); in meson_nand_attach_chip()
1345 dev_err(nfc->dev, "failed to ECC init\n"); in meson_nand_attach_chip()
1346 return -EINVAL; in meson_nand_attach_chip()
1353 return -EINVAL; in meson_nand_attach_chip()
1355 nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in meson_nand_attach_chip()
1356 nand->ecc.write_page_raw = meson_nfc_write_page_raw; in meson_nand_attach_chip()
1357 nand->ecc.write_page = meson_nfc_write_page_hwecc; in meson_nand_attach_chip()
1358 nand->ecc.write_oob_raw = nand_write_oob_std; in meson_nand_attach_chip()
1359 nand->ecc.write_oob = nand_write_oob_std; in meson_nand_attach_chip()
1361 nand->ecc.read_page_raw = meson_nfc_read_page_raw; in meson_nand_attach_chip()
1362 nand->ecc.read_page = meson_nfc_read_page_hwecc; in meson_nand_attach_chip()
1363 nand->ecc.read_oob_raw = meson_nfc_read_oob_raw; in meson_nand_attach_chip()
1364 nand->ecc.read_oob = meson_nfc_read_oob; in meson_nand_attach_chip()
1366 if (nand->options & NAND_BUSWIDTH_16) { in meson_nand_attach_chip()
1367 dev_err(nfc->dev, "16bits bus width not supported"); in meson_nand_attach_chip()
1368 return -EINVAL; in meson_nand_attach_chip()
1372 return -ENOMEM; in meson_nand_attach_chip()
1398 return -EINVAL; in meson_nfc_nand_chip_init()
1404 return -ENOMEM; in meson_nfc_nand_chip_init()
1406 meson_chip->nsels = nsels; in meson_nfc_nand_chip_init()
1416 if (test_and_set_bit(tmp, &nfc->assigned_cs)) { in meson_nfc_nand_chip_init()
1418 return -EINVAL; in meson_nfc_nand_chip_init()
1422 nand = &meson_chip->nand; in meson_nfc_nand_chip_init()
1423 nand->controller = &nfc->controller; in meson_nfc_nand_chip_init()
1424 nand->controller->ops = &meson_nand_controller_ops; in meson_nfc_nand_chip_init()
1428 nand->options |= NAND_USES_DMA; in meson_nfc_nand_chip_init()
1430 mtd->owner = THIS_MODULE; in meson_nfc_nand_chip_init()
1431 mtd->dev.parent = dev; in meson_nfc_nand_chip_init()
1433 ret = of_property_read_u32(np, "nand-rb", &nand_rb_val); in meson_nfc_nand_chip_init()
1434 if (ret == -EINVAL) in meson_nfc_nand_chip_init()
1435 nfc->no_rb_pin = true; in meson_nfc_nand_chip_init()
1440 return -EINVAL; in meson_nfc_nand_chip_init()
1446 if (nand->options & NAND_IS_BOOT_MEDIUM) { in meson_nfc_nand_chip_init()
1447 ret = of_property_read_u32(np, "amlogic,boot-pages", in meson_nfc_nand_chip_init()
1448 &meson_chip->boot_pages); in meson_nfc_nand_chip_init()
1450 dev_err(dev, "could not retrieve 'amlogic,boot-pages' property: %d", in meson_nfc_nand_chip_init()
1456 ret = of_property_read_u32(np, "amlogic,boot-page-step", in meson_nfc_nand_chip_init()
1457 &meson_chip->boot_page_step); in meson_nfc_nand_chip_init()
1459 dev_err(dev, "could not retrieve 'amlogic,boot-page-step' property: %d", in meson_nfc_nand_chip_init()
1473 list_add_tail(&meson_chip->node, &nfc->chips); in meson_nfc_nand_chip_init()
1483 while (!list_empty(&nfc->chips)) { in meson_nfc_nand_chips_cleanup()
1484 meson_chip = list_first_entry(&nfc->chips, in meson_nfc_nand_chips_cleanup()
1486 mtd = nand_to_mtd(&meson_chip->nand); in meson_nfc_nand_chips_cleanup()
1489 nand_cleanup(&meson_chip->nand); in meson_nfc_nand_chips_cleanup()
1490 list_del(&meson_chip->node); in meson_nfc_nand_chips_cleanup()
1497 struct device_node *np = dev->of_node; in meson_nfc_nand_chips_init()
1516 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_irq()
1521 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_irq()
1523 complete(&nfc->completion); in meson_nfc_irq()
1537 .compatible = "amlogic,meson-gxl-nfc",
1540 .compatible = "amlogic,meson-axg-nfc",
1549 struct device *dev = &pdev->dev; in meson_nfc_probe()
1555 return -ENOMEM; in meson_nfc_probe()
1557 nfc->data = of_device_get_match_data(&pdev->dev); in meson_nfc_probe()
1558 if (!nfc->data) in meson_nfc_probe()
1559 return -ENODEV; in meson_nfc_probe()
1561 nand_controller_init(&nfc->controller); in meson_nfc_probe()
1562 INIT_LIST_HEAD(&nfc->chips); in meson_nfc_probe()
1563 init_completion(&nfc->completion); in meson_nfc_probe()
1565 nfc->dev = dev; in meson_nfc_probe()
1567 nfc->reg_base = devm_platform_ioremap_resource_byname(pdev, "nfc"); in meson_nfc_probe()
1568 if (IS_ERR(nfc->reg_base)) in meson_nfc_probe()
1569 return PTR_ERR(nfc->reg_base); in meson_nfc_probe()
1571 nfc->reg_clk = devm_platform_ioremap_resource_byname(pdev, "emmc"); in meson_nfc_probe()
1572 if (IS_ERR(nfc->reg_clk)) in meson_nfc_probe()
1573 return PTR_ERR(nfc->reg_clk); in meson_nfc_probe()
1577 return -EINVAL; in meson_nfc_probe()
1585 writel(0, nfc->reg_base + NFC_REG_CFG); in meson_nfc_probe()
1589 ret = -EINVAL; in meson_nfc_probe()
1626 .name = "meson-nand",