Lines Matching refs:spinand

23 static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)  in spinand_read_reg_op()  argument
26 spinand->scratchbuf); in spinand_read_reg_op()
29 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_read_reg_op()
33 *val = *spinand->scratchbuf; in spinand_read_reg_op()
37 static int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val) in spinand_write_reg_op() argument
40 spinand->scratchbuf); in spinand_write_reg_op()
42 *spinand->scratchbuf = val; in spinand_write_reg_op()
43 return spi_mem_exec_op(spinand->spimem, &op); in spinand_write_reg_op()
46 static int spinand_read_status(struct spinand_device *spinand, u8 *status) in spinand_read_status() argument
48 return spinand_read_reg_op(spinand, REG_STATUS, status); in spinand_read_status()
51 static int spinand_get_cfg(struct spinand_device *spinand, u8 *cfg) in spinand_get_cfg() argument
53 struct nand_device *nand = spinand_to_nand(spinand); in spinand_get_cfg()
55 if (WARN_ON(spinand->cur_target < 0 || in spinand_get_cfg()
56 spinand->cur_target >= nand->memorg.ntargets)) in spinand_get_cfg()
59 *cfg = spinand->cfg_cache[spinand->cur_target]; in spinand_get_cfg()
63 static int spinand_set_cfg(struct spinand_device *spinand, u8 cfg) in spinand_set_cfg() argument
65 struct nand_device *nand = spinand_to_nand(spinand); in spinand_set_cfg()
68 if (WARN_ON(spinand->cur_target < 0 || in spinand_set_cfg()
69 spinand->cur_target >= nand->memorg.ntargets)) in spinand_set_cfg()
72 if (spinand->cfg_cache[spinand->cur_target] == cfg) in spinand_set_cfg()
75 ret = spinand_write_reg_op(spinand, REG_CFG, cfg); in spinand_set_cfg()
79 spinand->cfg_cache[spinand->cur_target] = cfg; in spinand_set_cfg()
93 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val) in spinand_upd_cfg() argument
98 ret = spinand_get_cfg(spinand, &cfg); in spinand_upd_cfg()
105 return spinand_set_cfg(spinand, cfg); in spinand_upd_cfg()
117 int spinand_select_target(struct spinand_device *spinand, unsigned int target) in spinand_select_target() argument
119 struct nand_device *nand = spinand_to_nand(spinand); in spinand_select_target()
125 if (spinand->cur_target == target) in spinand_select_target()
129 spinand->cur_target = target; in spinand_select_target()
133 ret = spinand->select_target(spinand, target); in spinand_select_target()
137 spinand->cur_target = target; in spinand_select_target()
141 static int spinand_read_cfg(struct spinand_device *spinand) in spinand_read_cfg() argument
143 struct nand_device *nand = spinand_to_nand(spinand); in spinand_read_cfg()
148 ret = spinand_select_target(spinand, target); in spinand_read_cfg()
156 ret = spinand_read_reg_op(spinand, REG_CFG, in spinand_read_cfg()
157 &spinand->cfg_cache[target]); in spinand_read_cfg()
165 static int spinand_init_cfg_cache(struct spinand_device *spinand) in spinand_init_cfg_cache() argument
167 struct nand_device *nand = spinand_to_nand(spinand); in spinand_init_cfg_cache()
168 struct device *dev = &spinand->spimem->spi->dev; in spinand_init_cfg_cache()
170 spinand->cfg_cache = devm_kcalloc(dev, in spinand_init_cfg_cache()
172 sizeof(*spinand->cfg_cache), in spinand_init_cfg_cache()
174 if (!spinand->cfg_cache) in spinand_init_cfg_cache()
180 static int spinand_init_quad_enable(struct spinand_device *spinand) in spinand_init_quad_enable() argument
184 if (!(spinand->flags & SPINAND_HAS_QE_BIT)) in spinand_init_quad_enable()
187 if (spinand->op_templates.read_cache->data.buswidth == 4 || in spinand_init_quad_enable()
188 spinand->op_templates.write_cache->data.buswidth == 4 || in spinand_init_quad_enable()
189 spinand->op_templates.update_cache->data.buswidth == 4) in spinand_init_quad_enable()
192 return spinand_upd_cfg(spinand, CFG_QUAD_ENABLE, in spinand_init_quad_enable()
196 static int spinand_ecc_enable(struct spinand_device *spinand, in spinand_ecc_enable() argument
199 return spinand_upd_cfg(spinand, CFG_ECC_ENABLE, in spinand_ecc_enable()
203 static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status) in spinand_check_ecc_status() argument
205 struct nand_device *nand = spinand_to_nand(spinand); in spinand_check_ecc_status()
207 if (spinand->eccinfo.get_status) in spinand_check_ecc_status()
208 return spinand->eccinfo.get_status(spinand, status); in spinand_check_ecc_status()
258 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_ondie_ecc_init_ctx() local
272 if (spinand->eccinfo.ooblayout) in spinand_ondie_ecc_init_ctx()
273 mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout); in spinand_ondie_ecc_init_ctx()
288 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_ondie_ecc_prepare_io_req() local
291 memset(spinand->oobbuf, 0xff, nanddev_per_page_oobsize(nand)); in spinand_ondie_ecc_prepare_io_req()
294 return spinand_ecc_enable(spinand, enable); in spinand_ondie_ecc_prepare_io_req()
301 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_ondie_ecc_finish_io_req() local
302 struct mtd_info *mtd = spinand_to_mtd(spinand); in spinand_ondie_ecc_finish_io_req()
313 ret = spinand_check_ecc_status(spinand, engine_conf->status); in spinand_ondie_ecc_finish_io_req()
342 static int spinand_write_enable_op(struct spinand_device *spinand) in spinand_write_enable_op() argument
346 return spi_mem_exec_op(spinand->spimem, &op); in spinand_write_enable_op()
349 static int spinand_load_page_op(struct spinand_device *spinand, in spinand_load_page_op() argument
352 struct nand_device *nand = spinand_to_nand(spinand); in spinand_load_page_op()
356 return spi_mem_exec_op(spinand->spimem, &op); in spinand_load_page_op()
359 static int spinand_read_from_cache_op(struct spinand_device *spinand, in spinand_read_from_cache_op() argument
362 struct nand_device *nand = spinand_to_nand(spinand); in spinand_read_from_cache_op()
363 struct mtd_info *mtd = spinand_to_mtd(spinand); in spinand_read_from_cache_op()
371 buf = spinand->databuf; in spinand_read_from_cache_op()
379 buf = spinand->oobbuf; in spinand_read_from_cache_op()
385 rdesc = spinand->dirmaps[req->pos.plane].rdesc; in spinand_read_from_cache_op()
387 rdesc = spinand->dirmaps[req->pos.plane].rdesc_ecc; in spinand_read_from_cache_op()
403 memcpy(req->databuf.in, spinand->databuf + req->dataoffs, in spinand_read_from_cache_op()
409 spinand->oobbuf, in spinand_read_from_cache_op()
413 memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs, in spinand_read_from_cache_op()
420 static int spinand_write_to_cache_op(struct spinand_device *spinand, in spinand_write_to_cache_op() argument
423 struct nand_device *nand = spinand_to_nand(spinand); in spinand_write_to_cache_op()
424 struct mtd_info *mtd = spinand_to_mtd(spinand); in spinand_write_to_cache_op()
427 void *buf = spinand->databuf; in spinand_write_to_cache_op()
441 memset(spinand->databuf, 0xff, nanddev_page_size(nand)); in spinand_write_to_cache_op()
444 memcpy(spinand->databuf + req->dataoffs, req->databuf.out, in spinand_write_to_cache_op()
450 spinand->oobbuf, in spinand_write_to_cache_op()
454 memcpy(spinand->oobbuf + req->ooboffs, req->oobbuf.out, in spinand_write_to_cache_op()
459 wdesc = spinand->dirmaps[req->pos.plane].wdesc; in spinand_write_to_cache_op()
461 wdesc = spinand->dirmaps[req->pos.plane].wdesc_ecc; in spinand_write_to_cache_op()
479 static int spinand_program_op(struct spinand_device *spinand, in spinand_program_op() argument
482 struct nand_device *nand = spinand_to_nand(spinand); in spinand_program_op()
486 return spi_mem_exec_op(spinand->spimem, &op); in spinand_program_op()
489 static int spinand_erase_op(struct spinand_device *spinand, in spinand_erase_op() argument
492 struct nand_device *nand = spinand_to_nand(spinand); in spinand_erase_op()
496 return spi_mem_exec_op(spinand->spimem, &op); in spinand_erase_op()
499 static int spinand_wait(struct spinand_device *spinand, in spinand_wait() argument
505 spinand->scratchbuf); in spinand_wait()
509 ret = spi_mem_poll_status(spinand->spimem, &op, STATUS_BUSY, 0, in spinand_wait()
516 status = *spinand->scratchbuf; in spinand_wait()
524 ret = spinand_read_status(spinand, &status); in spinand_wait()
535 static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr, in spinand_read_id_op() argument
539 naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN); in spinand_read_id_op()
542 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_read_id_op()
544 memcpy(buf, spinand->scratchbuf, SPINAND_MAX_ID_LEN); in spinand_read_id_op()
549 static int spinand_reset_op(struct spinand_device *spinand) in spinand_reset_op() argument
554 ret = spi_mem_exec_op(spinand->spimem, &op); in spinand_reset_op()
558 return spinand_wait(spinand, in spinand_reset_op()
564 static int spinand_lock_block(struct spinand_device *spinand, u8 lock) in spinand_lock_block() argument
566 return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock); in spinand_lock_block()
569 static int spinand_read_page(struct spinand_device *spinand, in spinand_read_page() argument
572 struct nand_device *nand = spinand_to_nand(spinand); in spinand_read_page()
580 ret = spinand_load_page_op(spinand, req); in spinand_read_page()
584 ret = spinand_wait(spinand, in spinand_read_page()
593 ret = spinand_read_from_cache_op(spinand, req); in spinand_read_page()
600 static int spinand_write_page(struct spinand_device *spinand, in spinand_write_page() argument
603 struct nand_device *nand = spinand_to_nand(spinand); in spinand_write_page()
611 ret = spinand_write_enable_op(spinand); in spinand_write_page()
615 ret = spinand_write_to_cache_op(spinand, req); in spinand_write_page()
619 ret = spinand_program_op(spinand, req); in spinand_write_page()
623 ret = spinand_wait(spinand, in spinand_write_page()
636 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_read() local
645 if (ops->mode == MTD_OPS_RAW || !spinand->eccinfo.ooblayout) in spinand_mtd_read()
648 mutex_lock(&spinand->lock); in spinand_mtd_read()
656 ret = spinand_select_target(spinand, iter.req.pos.target); in spinand_mtd_read()
660 ret = spinand_read_page(spinand, &iter.req); in spinand_mtd_read()
681 mutex_unlock(&spinand->lock); in spinand_mtd_read()
692 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_write() local
701 mutex_lock(&spinand->lock); in spinand_mtd_write()
707 ret = spinand_select_target(spinand, iter.req.pos.target); in spinand_mtd_write()
711 ret = spinand_write_page(spinand, &iter.req); in spinand_mtd_write()
719 mutex_unlock(&spinand->lock); in spinand_mtd_write()
726 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_isbad() local
736 spinand_select_target(spinand, pos->target); in spinand_isbad()
737 spinand_read_page(spinand, &req); in spinand_isbad()
747 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_mtd_block_isbad() local
752 mutex_lock(&spinand->lock); in spinand_mtd_block_isbad()
754 mutex_unlock(&spinand->lock); in spinand_mtd_block_isbad()
761 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_markbad() local
772 ret = spinand_select_target(spinand, pos->target); in spinand_markbad()
776 ret = spinand_write_enable_op(spinand); in spinand_markbad()
780 return spinand_write_page(spinand, &req); in spinand_markbad()
786 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_mtd_block_markbad() local
791 mutex_lock(&spinand->lock); in spinand_mtd_block_markbad()
793 mutex_unlock(&spinand->lock); in spinand_mtd_block_markbad()
800 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_erase() local
804 ret = spinand_select_target(spinand, pos->target); in spinand_erase()
808 ret = spinand_write_enable_op(spinand); in spinand_erase()
812 ret = spinand_erase_op(spinand, pos); in spinand_erase()
816 ret = spinand_wait(spinand, in spinand_erase()
830 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_erase() local
833 mutex_lock(&spinand->lock); in spinand_mtd_erase()
835 mutex_unlock(&spinand->lock); in spinand_mtd_erase()
842 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_block_isreserved() local
848 mutex_lock(&spinand->lock); in spinand_mtd_block_isreserved()
850 mutex_unlock(&spinand->lock); in spinand_mtd_block_isreserved()
855 static int spinand_create_dirmap(struct spinand_device *spinand, in spinand_create_dirmap() argument
858 struct nand_device *nand = spinand_to_nand(spinand); in spinand_create_dirmap()
868 info.op_tmpl = *spinand->op_templates.update_cache; in spinand_create_dirmap()
869 desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, in spinand_create_dirmap()
870 spinand->spimem, &info); in spinand_create_dirmap()
874 spinand->dirmaps[plane].wdesc = desc; in spinand_create_dirmap()
876 info.op_tmpl = *spinand->op_templates.read_cache; in spinand_create_dirmap()
877 desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, in spinand_create_dirmap()
878 spinand->spimem, &info); in spinand_create_dirmap()
882 spinand->dirmaps[plane].rdesc = desc; in spinand_create_dirmap()
885 spinand->dirmaps[plane].wdesc_ecc = spinand->dirmaps[plane].wdesc; in spinand_create_dirmap()
886 spinand->dirmaps[plane].rdesc_ecc = spinand->dirmaps[plane].rdesc; in spinand_create_dirmap()
891 info.op_tmpl = *spinand->op_templates.update_cache; in spinand_create_dirmap()
893 desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, in spinand_create_dirmap()
894 spinand->spimem, &info); in spinand_create_dirmap()
898 spinand->dirmaps[plane].wdesc_ecc = desc; in spinand_create_dirmap()
900 info.op_tmpl = *spinand->op_templates.read_cache; in spinand_create_dirmap()
902 desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, in spinand_create_dirmap()
903 spinand->spimem, &info); in spinand_create_dirmap()
907 spinand->dirmaps[plane].rdesc_ecc = desc; in spinand_create_dirmap()
912 static int spinand_create_dirmaps(struct spinand_device *spinand) in spinand_create_dirmaps() argument
914 struct nand_device *nand = spinand_to_nand(spinand); in spinand_create_dirmaps()
917 spinand->dirmaps = devm_kzalloc(&spinand->spimem->spi->dev, in spinand_create_dirmaps()
918 sizeof(*spinand->dirmaps) * in spinand_create_dirmaps()
921 if (!spinand->dirmaps) in spinand_create_dirmaps()
925 ret = spinand_create_dirmap(spinand, i); in spinand_create_dirmaps()
952 static int spinand_manufacturer_match(struct spinand_device *spinand, in spinand_manufacturer_match() argument
955 u8 *id = spinand->id.data; in spinand_manufacturer_match()
966 ret = spinand_match_and_init(spinand, in spinand_manufacturer_match()
973 spinand->manufacturer = manufacturer; in spinand_manufacturer_match()
979 static int spinand_id_detect(struct spinand_device *spinand) in spinand_id_detect() argument
981 u8 *id = spinand->id.data; in spinand_id_detect()
984 ret = spinand_read_id_op(spinand, 0, 0, id); in spinand_id_detect()
987 ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE); in spinand_id_detect()
991 ret = spinand_read_id_op(spinand, 1, 0, id); in spinand_id_detect()
994 ret = spinand_manufacturer_match(spinand, in spinand_id_detect()
999 ret = spinand_read_id_op(spinand, 0, 1, id); in spinand_id_detect()
1002 ret = spinand_manufacturer_match(spinand, in spinand_id_detect()
1008 static int spinand_manufacturer_init(struct spinand_device *spinand) in spinand_manufacturer_init() argument
1010 if (spinand->manufacturer->ops->init) in spinand_manufacturer_init()
1011 return spinand->manufacturer->ops->init(spinand); in spinand_manufacturer_init()
1016 static void spinand_manufacturer_cleanup(struct spinand_device *spinand) in spinand_manufacturer_cleanup() argument
1019 if (spinand->manufacturer->ops->cleanup) in spinand_manufacturer_cleanup()
1020 return spinand->manufacturer->ops->cleanup(spinand); in spinand_manufacturer_cleanup()
1024 spinand_select_op_variant(struct spinand_device *spinand, in spinand_select_op_variant() argument
1027 struct nand_device *nand = spinand_to_nand(spinand); in spinand_select_op_variant()
1040 ret = spi_mem_adjust_op_size(spinand->spimem, &op); in spinand_select_op_variant()
1044 if (!spi_mem_supports_op(spinand->spimem, &op)) in spinand_select_op_variant()
1072 int spinand_match_and_init(struct spinand_device *spinand, in spinand_match_and_init() argument
1077 u8 *id = spinand->id.data; in spinand_match_and_init()
1078 struct nand_device *nand = spinand_to_nand(spinand); in spinand_match_and_init()
1093 spinand->eccinfo = table[i].eccinfo; in spinand_match_and_init()
1094 spinand->flags = table[i].flags; in spinand_match_and_init()
1095 spinand->id.len = 1 + table[i].devid.len; in spinand_match_and_init()
1096 spinand->select_target = table[i].select_target; in spinand_match_and_init()
1098 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
1103 spinand->op_templates.read_cache = op; in spinand_match_and_init()
1105 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
1110 spinand->op_templates.write_cache = op; in spinand_match_and_init()
1112 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
1114 spinand->op_templates.update_cache = op; in spinand_match_and_init()
1122 static int spinand_detect(struct spinand_device *spinand) in spinand_detect() argument
1124 struct device *dev = &spinand->spimem->spi->dev; in spinand_detect()
1125 struct nand_device *nand = spinand_to_nand(spinand); in spinand_detect()
1128 ret = spinand_reset_op(spinand); in spinand_detect()
1132 ret = spinand_id_detect(spinand); in spinand_detect()
1135 spinand->id.data); in spinand_detect()
1139 if (nand->memorg.ntargets > 1 && !spinand->select_target) { in spinand_detect()
1145 dev_info(&spinand->spimem->spi->dev, in spinand_detect()
1146 "%s SPI NAND was found.\n", spinand->manufacturer->name); in spinand_detect()
1147 dev_info(&spinand->spimem->spi->dev, in spinand_detect()
1155 static int spinand_init_flash(struct spinand_device *spinand) in spinand_init_flash() argument
1157 struct device *dev = &spinand->spimem->spi->dev; in spinand_init_flash()
1158 struct nand_device *nand = spinand_to_nand(spinand); in spinand_init_flash()
1161 ret = spinand_read_cfg(spinand); in spinand_init_flash()
1165 ret = spinand_init_quad_enable(spinand); in spinand_init_flash()
1169 ret = spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0); in spinand_init_flash()
1173 ret = spinand_manufacturer_init(spinand); in spinand_init_flash()
1183 ret = spinand_select_target(spinand, i); in spinand_init_flash()
1187 ret = spinand_lock_block(spinand, BL_ALL_UNLOCKED); in spinand_init_flash()
1193 spinand_manufacturer_cleanup(spinand); in spinand_init_flash()
1200 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_resume() local
1203 ret = spinand_reset_op(spinand); in spinand_mtd_resume()
1207 ret = spinand_init_flash(spinand); in spinand_mtd_resume()
1211 spinand_ecc_enable(spinand, false); in spinand_mtd_resume()
1214 static int spinand_init(struct spinand_device *spinand) in spinand_init() argument
1216 struct device *dev = &spinand->spimem->spi->dev; in spinand_init()
1217 struct mtd_info *mtd = spinand_to_mtd(spinand); in spinand_init()
1225 spinand->scratchbuf = kzalloc(SPINAND_MAX_ID_LEN, GFP_KERNEL); in spinand_init()
1226 if (!spinand->scratchbuf) in spinand_init()
1229 ret = spinand_detect(spinand); in spinand_init()
1238 spinand->databuf = kzalloc(nanddev_page_size(nand) + in spinand_init()
1241 if (!spinand->databuf) { in spinand_init()
1246 spinand->oobbuf = spinand->databuf + nanddev_page_size(nand); in spinand_init()
1248 ret = spinand_init_cfg_cache(spinand); in spinand_init()
1252 ret = spinand_init_flash(spinand); in spinand_init()
1264 spinand_ecc_enable(spinand, false); in spinand_init()
1290 ret = spinand_create_dirmaps(spinand); in spinand_init()
1307 spinand_manufacturer_cleanup(spinand); in spinand_init()
1310 kfree(spinand->databuf); in spinand_init()
1311 kfree(spinand->scratchbuf); in spinand_init()
1315 static void spinand_cleanup(struct spinand_device *spinand) in spinand_cleanup() argument
1317 struct nand_device *nand = spinand_to_nand(spinand); in spinand_cleanup()
1320 spinand_manufacturer_cleanup(spinand); in spinand_cleanup()
1321 kfree(spinand->databuf); in spinand_cleanup()
1322 kfree(spinand->scratchbuf); in spinand_cleanup()
1327 struct spinand_device *spinand; in spinand_probe() local
1331 spinand = devm_kzalloc(&mem->spi->dev, sizeof(*spinand), in spinand_probe()
1333 if (!spinand) in spinand_probe()
1336 spinand->spimem = mem; in spinand_probe()
1337 spi_mem_set_drvdata(mem, spinand); in spinand_probe()
1338 spinand_set_of_node(spinand, mem->spi->dev.of_node); in spinand_probe()
1339 mutex_init(&spinand->lock); in spinand_probe()
1340 mtd = spinand_to_mtd(spinand); in spinand_probe()
1343 ret = spinand_init(spinand); in spinand_probe()
1354 spinand_cleanup(spinand); in spinand_probe()
1361 struct spinand_device *spinand; in spinand_remove() local
1365 spinand = spi_mem_get_drvdata(mem); in spinand_remove()
1366 mtd = spinand_to_mtd(spinand); in spinand_remove()
1372 spinand_cleanup(spinand); in spinand_remove()