Lines Matching refs:spinand

22 static void spinand_cache_op_adjust_colum(struct spinand_device *spinand,  in spinand_cache_op_adjust_colum()  argument
26 struct nand_device *nand = spinand_to_nand(spinand); in spinand_cache_op_adjust_colum()
37 static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) in spinand_read_reg_op() argument
40 spinand->scratchbuf); in spinand_read_reg_op()
43 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_read_reg_op()
47 *val = *spinand->scratchbuf; in spinand_read_reg_op()
51 static int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val) in spinand_write_reg_op() argument
54 spinand->scratchbuf); in spinand_write_reg_op()
56 *spinand->scratchbuf = val; in spinand_write_reg_op()
57 return spi_mem_exec_op(spinand->spimem, &op); in spinand_write_reg_op()
60 static int spinand_read_status(struct spinand_device *spinand, u8 *status) in spinand_read_status() argument
62 return spinand_read_reg_op(spinand, REG_STATUS, status); in spinand_read_status()
65 static int spinand_get_cfg(struct spinand_device *spinand, u8 *cfg) in spinand_get_cfg() argument
67 struct nand_device *nand = spinand_to_nand(spinand); in spinand_get_cfg()
69 if (WARN_ON(spinand->cur_target < 0 || in spinand_get_cfg()
70 spinand->cur_target >= nand->memorg.ntargets)) in spinand_get_cfg()
73 *cfg = spinand->cfg_cache[spinand->cur_target]; in spinand_get_cfg()
77 static int spinand_set_cfg(struct spinand_device *spinand, u8 cfg) in spinand_set_cfg() argument
79 struct nand_device *nand = spinand_to_nand(spinand); in spinand_set_cfg()
82 if (WARN_ON(spinand->cur_target < 0 || in spinand_set_cfg()
83 spinand->cur_target >= nand->memorg.ntargets)) in spinand_set_cfg()
86 if (spinand->cfg_cache[spinand->cur_target] == cfg) in spinand_set_cfg()
89 ret = spinand_write_reg_op(spinand, REG_CFG, cfg); in spinand_set_cfg()
93 spinand->cfg_cache[spinand->cur_target] = cfg; in spinand_set_cfg()
107 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val) in spinand_upd_cfg() argument
112 ret = spinand_get_cfg(spinand, &cfg); in spinand_upd_cfg()
119 return spinand_set_cfg(spinand, cfg); in spinand_upd_cfg()
131 int spinand_select_target(struct spinand_device *spinand, unsigned int target) in spinand_select_target() argument
133 struct nand_device *nand = spinand_to_nand(spinand); in spinand_select_target()
139 if (spinand->cur_target == target) in spinand_select_target()
143 spinand->cur_target = target; in spinand_select_target()
147 ret = spinand->select_target(spinand, target); in spinand_select_target()
151 spinand->cur_target = target; in spinand_select_target()
155 static int spinand_init_cfg_cache(struct spinand_device *spinand) in spinand_init_cfg_cache() argument
157 struct nand_device *nand = spinand_to_nand(spinand); in spinand_init_cfg_cache()
158 struct device *dev = &spinand->spimem->spi->dev; in spinand_init_cfg_cache()
162 spinand->cfg_cache = devm_kcalloc(dev, in spinand_init_cfg_cache()
164 sizeof(*spinand->cfg_cache), in spinand_init_cfg_cache()
166 if (!spinand->cfg_cache) in spinand_init_cfg_cache()
170 ret = spinand_select_target(spinand, target); in spinand_init_cfg_cache()
178 ret = spinand_read_reg_op(spinand, REG_CFG, in spinand_init_cfg_cache()
179 &spinand->cfg_cache[target]); in spinand_init_cfg_cache()
187 static int spinand_init_quad_enable(struct spinand_device *spinand) in spinand_init_quad_enable() argument
191 if (!(spinand->flags & SPINAND_HAS_QE_BIT)) in spinand_init_quad_enable()
194 if (spinand->op_templates.read_cache->data.buswidth == 4 || in spinand_init_quad_enable()
195 spinand->op_templates.write_cache->data.buswidth == 4 || in spinand_init_quad_enable()
196 spinand->op_templates.update_cache->data.buswidth == 4) in spinand_init_quad_enable()
199 return spinand_upd_cfg(spinand, CFG_QUAD_ENABLE, in spinand_init_quad_enable()
203 static int spinand_ecc_enable(struct spinand_device *spinand, in spinand_ecc_enable() argument
206 return spinand_upd_cfg(spinand, CFG_ECC_ENABLE, in spinand_ecc_enable()
210 static int spinand_write_enable_op(struct spinand_device *spinand) in spinand_write_enable_op() argument
214 return spi_mem_exec_op(spinand->spimem, &op); in spinand_write_enable_op()
217 static int spinand_load_page_op(struct spinand_device *spinand, in spinand_load_page_op() argument
220 struct nand_device *nand = spinand_to_nand(spinand); in spinand_load_page_op()
224 return spi_mem_exec_op(spinand->spimem, &op); in spinand_load_page_op()
227 static int spinand_read_from_cache_op(struct spinand_device *spinand, in spinand_read_from_cache_op() argument
230 struct spi_mem_op op = *spinand->op_templates.read_cache; in spinand_read_from_cache_op()
231 struct nand_device *nand = spinand_to_nand(spinand); in spinand_read_from_cache_op()
242 adjreq.databuf.in = spinand->databuf; in spinand_read_from_cache_op()
243 buf = spinand->databuf; in spinand_read_from_cache_op()
250 adjreq.oobbuf.in = spinand->oobbuf; in spinand_read_from_cache_op()
253 buf = spinand->oobbuf; in spinand_read_from_cache_op()
258 spinand_cache_op_adjust_colum(spinand, &adjreq, &column); in spinand_read_from_cache_op()
269 ret = spi_mem_adjust_op_size(spinand->spimem, &op); in spinand_read_from_cache_op()
273 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_read_from_cache_op()
283 memcpy(req->databuf.in, spinand->databuf + req->dataoffs, in spinand_read_from_cache_op()
289 spinand->oobbuf, in spinand_read_from_cache_op()
293 memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs, in spinand_read_from_cache_op()
300 static int spinand_write_to_cache_op(struct spinand_device *spinand, in spinand_write_to_cache_op() argument
303 struct spi_mem_op op = *spinand->op_templates.write_cache; in spinand_write_to_cache_op()
304 struct nand_device *nand = spinand_to_nand(spinand); in spinand_write_to_cache_op()
312 memset(spinand->databuf, 0xff, in spinand_write_to_cache_op()
317 memcpy(spinand->databuf + req->dataoffs, req->databuf.out, in spinand_write_to_cache_op()
321 adjreq.databuf.out = spinand->databuf; in spinand_write_to_cache_op()
323 buf = spinand->databuf; in spinand_write_to_cache_op()
329 spinand->oobbuf, in spinand_write_to_cache_op()
333 memcpy(spinand->oobbuf + req->ooboffs, req->oobbuf.out, in spinand_write_to_cache_op()
340 buf = spinand->oobbuf; in spinand_write_to_cache_op()
345 spinand_cache_op_adjust_colum(spinand, &adjreq, &column); in spinand_write_to_cache_op()
347 op = *spinand->op_templates.write_cache; in spinand_write_to_cache_op()
359 ret = spi_mem_adjust_op_size(spinand->spimem, &op); in spinand_write_to_cache_op()
363 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_write_to_cache_op()
378 op = *spinand->op_templates.update_cache; in spinand_write_to_cache_op()
386 static int spinand_program_op(struct spinand_device *spinand, in spinand_program_op() argument
389 struct nand_device *nand = spinand_to_nand(spinand); in spinand_program_op()
393 return spi_mem_exec_op(spinand->spimem, &op); in spinand_program_op()
396 static int spinand_erase_op(struct spinand_device *spinand, in spinand_erase_op() argument
399 struct nand_device *nand = spinand_to_nand(spinand); in spinand_erase_op()
403 return spi_mem_exec_op(spinand->spimem, &op); in spinand_erase_op()
406 static int spinand_wait(struct spinand_device *spinand, u8 *s) in spinand_wait() argument
413 ret = spinand_read_status(spinand, &status); in spinand_wait()
425 ret = spinand_read_status(spinand, &status); in spinand_wait()
436 static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf) in spinand_read_id_op() argument
438 struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf, in spinand_read_id_op()
442 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_read_id_op()
444 memcpy(buf, spinand->scratchbuf, SPINAND_MAX_ID_LEN); in spinand_read_id_op()
449 static int spinand_reset_op(struct spinand_device *spinand) in spinand_reset_op() argument
454 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_reset_op()
458 return spinand_wait(spinand, NULL); in spinand_reset_op()
461 static int spinand_lock_block(struct spinand_device *spinand, u8 lock) in spinand_lock_block() argument
463 return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock); in spinand_lock_block()
466 static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status) in spinand_check_ecc_status() argument
468 struct nand_device *nand = spinand_to_nand(spinand); in spinand_check_ecc_status()
470 if (spinand->eccinfo.get_status) in spinand_check_ecc_status()
471 return spinand->eccinfo.get_status(spinand, status); in spinand_check_ecc_status()
495 static int spinand_read_page(struct spinand_device *spinand, in spinand_read_page() argument
502 ret = spinand_load_page_op(spinand, req); in spinand_read_page()
506 ret = spinand_wait(spinand, &status); in spinand_read_page()
510 ret = spinand_read_from_cache_op(spinand, req); in spinand_read_page()
517 return spinand_check_ecc_status(spinand, status); in spinand_read_page()
520 static int spinand_write_page(struct spinand_device *spinand, in spinand_write_page() argument
526 ret = spinand_write_enable_op(spinand); in spinand_write_page()
530 ret = spinand_write_to_cache_op(spinand, req); in spinand_write_page()
534 ret = spinand_program_op(spinand, req); in spinand_write_page()
538 ret = spinand_wait(spinand, &status); in spinand_write_page()
548 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_read() local
556 if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout) in spinand_mtd_read()
559 mutex_lock(&spinand->lock); in spinand_mtd_read()
562 ret = spinand_select_target(spinand, iter.req.pos.target); in spinand_mtd_read()
566 ret = spinand_ecc_enable(spinand, enable_ecc); in spinand_mtd_read()
570 ret = spinand_read_page(spinand, &iter.req, enable_ecc); in spinand_mtd_read()
587 mutex_unlock(&spinand->lock); in spinand_mtd_read()
598 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_write() local
607 mutex_lock(&spinand->lock); in spinand_mtd_write()
610 ret = spinand_select_target(spinand, iter.req.pos.target); in spinand_mtd_write()
614 ret = spinand_ecc_enable(spinand, enable_ecc); in spinand_mtd_write()
618 ret = spinand_write_page(spinand, &iter.req); in spinand_mtd_write()
626 mutex_unlock(&spinand->lock); in spinand_mtd_write()
633 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_isbad() local
638 .oobbuf.in = spinand->oobbuf, in spinand_isbad()
642 memset(spinand->oobbuf, 0, 2); in spinand_isbad()
643 spinand_select_target(spinand, pos->target); in spinand_isbad()
644 spinand_read_page(spinand, &req, false); in spinand_isbad()
645 if (spinand->oobbuf[0] != 0xff || spinand->oobbuf[1] != 0xff) in spinand_isbad()
654 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_mtd_block_isbad() local
659 mutex_lock(&spinand->lock); in spinand_mtd_block_isbad()
661 mutex_unlock(&spinand->lock); in spinand_mtd_block_isbad()
668 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_markbad() local
673 .oobbuf.out = spinand->oobbuf, in spinand_markbad()
678 ret = spinand_select_target(spinand, pos->target); in spinand_markbad()
682 ret = spinand_write_enable_op(spinand); in spinand_markbad()
686 spinand_erase_op(spinand, pos); in spinand_markbad()
688 memset(spinand->oobbuf, 0, 2); in spinand_markbad()
689 return spinand_write_page(spinand, &req); in spinand_markbad()
695 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_mtd_block_markbad() local
700 mutex_lock(&spinand->lock); in spinand_mtd_block_markbad()
702 mutex_unlock(&spinand->lock); in spinand_mtd_block_markbad()
709 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_erase() local
713 ret = spinand_select_target(spinand, pos->target); in spinand_erase()
717 ret = spinand_write_enable_op(spinand); in spinand_erase()
721 ret = spinand_erase_op(spinand, pos); in spinand_erase()
725 ret = spinand_wait(spinand, &status); in spinand_erase()
735 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_erase() local
738 mutex_lock(&spinand->lock); in spinand_mtd_erase()
740 mutex_unlock(&spinand->lock); in spinand_mtd_erase()
747 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_block_isreserved() local
753 mutex_lock(&spinand->lock); in spinand_mtd_block_isreserved()
755 mutex_unlock(&spinand->lock); in spinand_mtd_block_isreserved()
772 static int spinand_manufacturer_detect(struct spinand_device *spinand) in spinand_manufacturer_detect() argument
778 ret = spinand_manufacturers[i]->ops->detect(spinand); in spinand_manufacturer_detect()
780 spinand->manufacturer = spinand_manufacturers[i]; in spinand_manufacturer_detect()
790 static int spinand_manufacturer_init(struct spinand_device *spinand) in spinand_manufacturer_init() argument
792 if (spinand->manufacturer->ops->init) in spinand_manufacturer_init()
793 return spinand->manufacturer->ops->init(spinand); in spinand_manufacturer_init()
798 static void spinand_manufacturer_cleanup(struct spinand_device *spinand) in spinand_manufacturer_cleanup() argument
801 if (spinand->manufacturer->ops->cleanup) in spinand_manufacturer_cleanup()
802 return spinand->manufacturer->ops->cleanup(spinand); in spinand_manufacturer_cleanup()
806 spinand_select_op_variant(struct spinand_device *spinand, in spinand_select_op_variant() argument
809 struct nand_device *nand = spinand_to_nand(spinand); in spinand_select_op_variant()
822 ret = spi_mem_adjust_op_size(spinand->spimem, &op); in spinand_select_op_variant()
826 if (!spi_mem_supports_op(spinand->spimem, &op)) in spinand_select_op_variant()
854 int spinand_match_and_init(struct spinand_device *spinand, in spinand_match_and_init() argument
858 struct nand_device *nand = spinand_to_nand(spinand); in spinand_match_and_init()
870 spinand->eccinfo = table[i].eccinfo; in spinand_match_and_init()
871 spinand->flags = table[i].flags; in spinand_match_and_init()
872 spinand->select_target = table[i].select_target; in spinand_match_and_init()
874 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
879 spinand->op_templates.read_cache = op; in spinand_match_and_init()
881 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
886 spinand->op_templates.write_cache = op; in spinand_match_and_init()
888 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
890 spinand->op_templates.update_cache = op; in spinand_match_and_init()
898 static int spinand_detect(struct spinand_device *spinand) in spinand_detect() argument
900 struct device *dev = &spinand->spimem->spi->dev; in spinand_detect()
901 struct nand_device *nand = spinand_to_nand(spinand); in spinand_detect()
904 ret = spinand_reset_op(spinand); in spinand_detect()
908 ret = spinand_read_id_op(spinand, spinand->id.data); in spinand_detect()
912 spinand->id.len = SPINAND_MAX_ID_LEN; in spinand_detect()
914 ret = spinand_manufacturer_detect(spinand); in spinand_detect()
917 spinand->id.data); in spinand_detect()
921 if (nand->memorg.ntargets > 1 && !spinand->select_target) { in spinand_detect()
927 dev_info(&spinand->spimem->spi->dev, in spinand_detect()
928 "%s SPI NAND was found.\n", spinand->manufacturer->name); in spinand_detect()
929 dev_info(&spinand->spimem->spi->dev, in spinand_detect()
961 static int spinand_init(struct spinand_device *spinand) in spinand_init() argument
963 struct device *dev = &spinand->spimem->spi->dev; in spinand_init()
964 struct mtd_info *mtd = spinand_to_mtd(spinand); in spinand_init()
972 spinand->scratchbuf = kzalloc(SPINAND_MAX_ID_LEN, GFP_KERNEL); in spinand_init()
973 if (!spinand->scratchbuf) in spinand_init()
976 ret = spinand_detect(spinand); in spinand_init()
985 spinand->databuf = kzalloc(nanddev_page_size(nand) + in spinand_init()
988 if (!spinand->databuf) { in spinand_init()
993 spinand->oobbuf = spinand->databuf + nanddev_page_size(nand); in spinand_init()
995 ret = spinand_init_cfg_cache(spinand); in spinand_init()
999 ret = spinand_init_quad_enable(spinand); in spinand_init()
1003 ret = spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0); in spinand_init()
1007 ret = spinand_manufacturer_init(spinand); in spinand_init()
1017 ret = spinand_select_target(spinand, i); in spinand_init()
1021 ret = spinand_lock_block(spinand, BL_ALL_UNLOCKED); in spinand_init()
1041 if (spinand->eccinfo.ooblayout) in spinand_init()
1042 mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout); in spinand_init()
1058 spinand_manufacturer_cleanup(spinand); in spinand_init()
1061 kfree(spinand->databuf); in spinand_init()
1062 kfree(spinand->scratchbuf); in spinand_init()
1066 static void spinand_cleanup(struct spinand_device *spinand) in spinand_cleanup() argument
1068 struct nand_device *nand = spinand_to_nand(spinand); in spinand_cleanup()
1071 spinand_manufacturer_cleanup(spinand); in spinand_cleanup()
1072 kfree(spinand->databuf); in spinand_cleanup()
1073 kfree(spinand->scratchbuf); in spinand_cleanup()
1078 struct spinand_device *spinand; in spinand_probe() local
1082 spinand = devm_kzalloc(&mem->spi->dev, sizeof(*spinand), in spinand_probe()
1084 if (!spinand) in spinand_probe()
1087 spinand->spimem = mem; in spinand_probe()
1088 spi_mem_set_drvdata(mem, spinand); in spinand_probe()
1089 spinand_set_of_node(spinand, mem->spi->dev.of_node); in spinand_probe()
1090 mutex_init(&spinand->lock); in spinand_probe()
1091 mtd = spinand_to_mtd(spinand); in spinand_probe()
1094 ret = spinand_init(spinand); in spinand_probe()
1105 spinand_cleanup(spinand); in spinand_probe()
1112 struct spinand_device *spinand; in spinand_remove() local
1116 spinand = spi_mem_get_drvdata(mem); in spinand_remove()
1117 mtd = spinand_to_mtd(spinand); in spinand_remove()
1123 spinand_cleanup(spinand); in spinand_remove()