Lines Matching refs:spinand
33 static void spinand_cache_op_adjust_colum(struct spinand_device *spinand, in spinand_cache_op_adjust_colum() argument
37 struct nand_device *nand = spinand_to_nand(spinand); in spinand_cache_op_adjust_colum()
48 static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) in spinand_read_reg_op() argument
51 spinand->scratchbuf); in spinand_read_reg_op()
54 ret = spi_mem_exec_op(spinand->slave, &op); in spinand_read_reg_op()
58 *val = *spinand->scratchbuf; in spinand_read_reg_op()
62 static int spinand_write_reg_op(struct spinand_device *spinand, u8 reg, u8 val) in spinand_write_reg_op() argument
65 spinand->scratchbuf); in spinand_write_reg_op()
67 *spinand->scratchbuf = val; in spinand_write_reg_op()
68 return spi_mem_exec_op(spinand->slave, &op); in spinand_write_reg_op()
71 static int spinand_read_status(struct spinand_device *spinand, u8 *status) in spinand_read_status() argument
73 return spinand_read_reg_op(spinand, REG_STATUS, status); in spinand_read_status()
76 static int spinand_get_cfg(struct spinand_device *spinand, u8 *cfg) in spinand_get_cfg() argument
78 struct nand_device *nand = spinand_to_nand(spinand); in spinand_get_cfg()
80 if (WARN_ON(spinand->cur_target < 0 || in spinand_get_cfg()
81 spinand->cur_target >= nand->memorg.ntargets)) in spinand_get_cfg()
84 *cfg = spinand->cfg_cache[spinand->cur_target]; in spinand_get_cfg()
88 static int spinand_set_cfg(struct spinand_device *spinand, u8 cfg) in spinand_set_cfg() argument
90 struct nand_device *nand = spinand_to_nand(spinand); in spinand_set_cfg()
93 if (WARN_ON(spinand->cur_target < 0 || in spinand_set_cfg()
94 spinand->cur_target >= nand->memorg.ntargets)) in spinand_set_cfg()
97 if (spinand->cfg_cache[spinand->cur_target] == cfg) in spinand_set_cfg()
100 ret = spinand_write_reg_op(spinand, REG_CFG, cfg); in spinand_set_cfg()
104 spinand->cfg_cache[spinand->cur_target] = cfg; in spinand_set_cfg()
118 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val) in spinand_upd_cfg() argument
123 ret = spinand_get_cfg(spinand, &cfg); in spinand_upd_cfg()
130 return spinand_set_cfg(spinand, cfg); in spinand_upd_cfg()
142 int spinand_select_target(struct spinand_device *spinand, unsigned int target) in spinand_select_target() argument
144 struct nand_device *nand = spinand_to_nand(spinand); in spinand_select_target()
150 if (spinand->cur_target == target) in spinand_select_target()
154 spinand->cur_target = target; in spinand_select_target()
158 ret = spinand->select_target(spinand, target); in spinand_select_target()
162 spinand->cur_target = target; in spinand_select_target()
166 static int spinand_init_cfg_cache(struct spinand_device *spinand) in spinand_init_cfg_cache() argument
168 struct nand_device *nand = spinand_to_nand(spinand); in spinand_init_cfg_cache()
169 struct udevice *dev = spinand->slave->dev; in spinand_init_cfg_cache()
173 spinand->cfg_cache = devm_kzalloc(dev, in spinand_init_cfg_cache()
174 sizeof(*spinand->cfg_cache) * in spinand_init_cfg_cache()
177 if (!spinand->cfg_cache) in spinand_init_cfg_cache()
181 ret = spinand_select_target(spinand, target); in spinand_init_cfg_cache()
189 ret = spinand_read_reg_op(spinand, REG_CFG, in spinand_init_cfg_cache()
190 &spinand->cfg_cache[target]); in spinand_init_cfg_cache()
198 static int spinand_init_quad_enable(struct spinand_device *spinand) in spinand_init_quad_enable() argument
202 if (!(spinand->flags & SPINAND_HAS_QE_BIT)) in spinand_init_quad_enable()
205 if (spinand->op_templates.read_cache->data.buswidth == 4 || in spinand_init_quad_enable()
206 spinand->op_templates.write_cache->data.buswidth == 4 || in spinand_init_quad_enable()
207 spinand->op_templates.update_cache->data.buswidth == 4) in spinand_init_quad_enable()
210 return spinand_upd_cfg(spinand, CFG_QUAD_ENABLE, in spinand_init_quad_enable()
214 static int spinand_ecc_enable(struct spinand_device *spinand, in spinand_ecc_enable() argument
217 return spinand_upd_cfg(spinand, CFG_ECC_ENABLE, in spinand_ecc_enable()
221 static int spinand_write_enable_op(struct spinand_device *spinand) in spinand_write_enable_op() argument
225 return spi_mem_exec_op(spinand->slave, &op); in spinand_write_enable_op()
228 static int spinand_load_page_op(struct spinand_device *spinand, in spinand_load_page_op() argument
231 struct nand_device *nand = spinand_to_nand(spinand); in spinand_load_page_op()
235 return spi_mem_exec_op(spinand->slave, &op); in spinand_load_page_op()
238 static int spinand_read_from_cache_op(struct spinand_device *spinand, in spinand_read_from_cache_op() argument
241 struct spi_mem_op op = *spinand->op_templates.read_cache; in spinand_read_from_cache_op()
242 struct nand_device *nand = spinand_to_nand(spinand); in spinand_read_from_cache_op()
253 adjreq.databuf.in = spinand->databuf; in spinand_read_from_cache_op()
254 buf = spinand->databuf; in spinand_read_from_cache_op()
258 if (spinand->support_cont_read && req->datalen) { in spinand_read_from_cache_op()
269 adjreq.oobbuf.in = spinand->oobbuf; in spinand_read_from_cache_op()
272 buf = spinand->oobbuf; in spinand_read_from_cache_op()
277 spinand_cache_op_adjust_colum(spinand, &adjreq, &column); in spinand_read_from_cache_op()
288 ret = spi_mem_adjust_op_size(spinand->slave, &op); in spinand_read_from_cache_op()
292 ret = spi_mem_exec_op(spinand->slave, &op); in spinand_read_from_cache_op()
301 if (!spinand->support_cont_read && req->datalen) in spinand_read_from_cache_op()
302 memcpy(req->databuf.in, spinand->databuf + req->dataoffs, req->datalen); in spinand_read_from_cache_op()
307 spinand->oobbuf, in spinand_read_from_cache_op()
311 memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs, in spinand_read_from_cache_op()
318 static int spinand_write_to_cache_op(struct spinand_device *spinand, in spinand_write_to_cache_op() argument
321 struct spi_mem_op op = *spinand->op_templates.write_cache; in spinand_write_to_cache_op()
322 struct nand_device *nand = spinand_to_nand(spinand); in spinand_write_to_cache_op()
337 memset(spinand->databuf, 0xff, in spinand_write_to_cache_op()
342 memcpy(spinand->databuf + req->dataoffs, req->databuf.out, in spinand_write_to_cache_op()
346 adjreq.databuf.out = spinand->databuf; in spinand_write_to_cache_op()
348 buf = spinand->databuf; in spinand_write_to_cache_op()
354 spinand->oobbuf, in spinand_write_to_cache_op()
358 memcpy(spinand->oobbuf + req->ooboffs, req->oobbuf.out, in spinand_write_to_cache_op()
365 buf = spinand->oobbuf; in spinand_write_to_cache_op()
370 spinand_cache_op_adjust_colum(spinand, &adjreq, &column); in spinand_write_to_cache_op()
372 op = *spinand->op_templates.write_cache; in spinand_write_to_cache_op()
384 ret = spi_mem_adjust_op_size(spinand->slave, &op); in spinand_write_to_cache_op()
388 ret = spi_mem_exec_op(spinand->slave, &op); in spinand_write_to_cache_op()
403 op = *spinand->op_templates.update_cache; in spinand_write_to_cache_op()
411 static int spinand_program_op(struct spinand_device *spinand, in spinand_program_op() argument
414 struct nand_device *nand = spinand_to_nand(spinand); in spinand_program_op()
418 return spi_mem_exec_op(spinand->slave, &op); in spinand_program_op()
421 static int spinand_erase_op(struct spinand_device *spinand, in spinand_erase_op() argument
424 struct nand_device *nand = &spinand->base; in spinand_erase_op()
428 return spi_mem_exec_op(spinand->slave, &op); in spinand_erase_op()
431 static int spinand_wait(struct spinand_device *spinand, u8 *s) in spinand_wait() argument
440 ret = spinand_read_status(spinand, &status); in spinand_wait()
452 ret = spinand_read_status(spinand, &status); in spinand_wait()
463 static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr, in spinand_read_id_op() argument
467 naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN); in spinand_read_id_op()
470 ret = spi_mem_exec_op(spinand->slave, &op); in spinand_read_id_op()
472 memcpy(buf, spinand->scratchbuf, SPINAND_MAX_ID_LEN); in spinand_read_id_op()
478 static int spinand_reset_op(struct spinand_device *spinand) in spinand_reset_op() argument
483 ret = spi_mem_exec_op(spinand->slave, &op); in spinand_reset_op()
487 return spinand_wait(spinand, NULL); in spinand_reset_op()
491 static int spinand_lock_block(struct spinand_device *spinand, u8 lock) in spinand_lock_block() argument
493 return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock); in spinand_lock_block()
496 static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status) in spinand_check_ecc_status() argument
498 struct nand_device *nand = spinand_to_nand(spinand); in spinand_check_ecc_status()
500 if (spinand->eccinfo.get_status) in spinand_check_ecc_status()
501 return spinand->eccinfo.get_status(spinand, status); in spinand_check_ecc_status()
525 static int spinand_read_page(struct spinand_device *spinand, in spinand_read_page() argument
532 ret = spinand_load_page_op(spinand, req); in spinand_read_page()
536 ret = spinand_wait(spinand, &status); in spinand_read_page()
541 if (spinand->id.data[0] == 0x01 && status && !ret) in spinand_read_page()
542 ret = spinand_wait(spinand, &status); in spinand_read_page()
546 ret = spinand_read_from_cache_op(spinand, req); in spinand_read_page()
550 if (spinand->support_cont_read && !(spinand->slave->mode & SPI_DMA_PREPARE)) in spinand_read_page()
551 spinand_wait(spinand, &status); in spinand_read_page()
556 return spinand_check_ecc_status(spinand, status); in spinand_read_page()
559 static int spinand_write_page(struct spinand_device *spinand, in spinand_write_page() argument
565 ret = spinand_write_enable_op(spinand); in spinand_write_page()
569 ret = spinand_write_to_cache_op(spinand, req); in spinand_write_page()
573 ret = spinand_program_op(spinand, req); in spinand_write_page()
577 ret = spinand_wait(spinand, &status); in spinand_write_page()
587 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_read() local
594 bool cont_real = spinand->support_cont_read; in spinand_mtd_read()
596 if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout) in spinand_mtd_read()
600 mutex_lock(&spinand->lock); in spinand_mtd_read()
604 ret = spinand_select_target(spinand, iter.req.pos.target); in spinand_mtd_read()
608 ret = spinand_ecc_enable(spinand, enable_ecc); in spinand_mtd_read()
614 spinand->support_cont_read = false; in spinand_mtd_read()
616 spinand->support_cont_read = cont_real; in spinand_mtd_read()
618 if (spinand->support_cont_read) { in spinand_mtd_read()
622 ret = spinand_read_page(spinand, &iter.req, enable_ecc); in spinand_mtd_read()
635 if (spinand->support_cont_read) { in spinand_mtd_read()
646 mutex_unlock(&spinand->lock); in spinand_mtd_read()
651 spinand->support_cont_read = cont_real; in spinand_mtd_read()
659 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_write() local
669 mutex_lock(&spinand->lock); in spinand_mtd_write()
673 ret = spinand_select_target(spinand, iter.req.pos.target); in spinand_mtd_write()
677 ret = spinand_ecc_enable(spinand, enable_ecc); in spinand_mtd_write()
681 ret = spinand_write_page(spinand, &iter.req); in spinand_mtd_write()
690 mutex_unlock(&spinand->lock); in spinand_mtd_write()
698 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_isbad() local
708 spinand_select_target(spinand, pos->target); in spinand_isbad()
709 spinand_read_page(spinand, &req, false); in spinand_isbad()
720 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_mtd_block_isbad() local
727 mutex_lock(&spinand->lock); in spinand_mtd_block_isbad()
731 mutex_unlock(&spinand->lock); in spinand_mtd_block_isbad()
738 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_markbad() local
749 ret = spinand_select_target(spinand, pos->target); in spinand_markbad()
753 ret = spinand_write_enable_op(spinand); in spinand_markbad()
757 return spinand_write_page(spinand, &req); in spinand_markbad()
764 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_mtd_block_markbad() local
771 mutex_lock(&spinand->lock); in spinand_mtd_block_markbad()
775 mutex_unlock(&spinand->lock); in spinand_mtd_block_markbad()
782 struct spinand_device *spinand = nand_to_spinand(nand); in spinand_erase() local
786 ret = spinand_select_target(spinand, pos->target); in spinand_erase()
790 ret = spinand_write_enable_op(spinand); in spinand_erase()
794 ret = spinand_erase_op(spinand, pos); in spinand_erase()
798 ret = spinand_wait(spinand, &status); in spinand_erase()
809 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_erase() local
814 mutex_lock(&spinand->lock); in spinand_mtd_erase()
818 mutex_unlock(&spinand->lock); in spinand_mtd_erase()
827 struct spinand_device *spinand = mtd_to_spinand(mtd); in spinand_mtd_block_isreserved() local
835 mutex_lock(&spinand->lock); in spinand_mtd_block_isreserved()
839 mutex_unlock(&spinand->lock); in spinand_mtd_block_isreserved()
846 spinand_find_supported_op(struct spinand_device *spinand, in spinand_find_supported_op() argument
853 if (spi_mem_supports_op(spinand->slave, &ops[i])) in spinand_find_supported_op()
936 static int spinand_manufacturer_match(struct spinand_device *spinand, in spinand_manufacturer_match() argument
939 u8 *id = spinand->id.data; in spinand_manufacturer_match()
950 ret = spinand_match_and_init(spinand, in spinand_manufacturer_match()
957 spinand->manufacturer = manufacturer; in spinand_manufacturer_match()
963 static int spinand_id_detect(struct spinand_device *spinand) in spinand_id_detect() argument
965 u8 *id = spinand->id.data; in spinand_id_detect()
968 ret = spinand_read_id_op(spinand, 0, 0, id); in spinand_id_detect()
971 ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE); in spinand_id_detect()
975 ret = spinand_read_id_op(spinand, 1, 0, id); in spinand_id_detect()
978 ret = spinand_manufacturer_match(spinand, in spinand_id_detect()
983 ret = spinand_read_id_op(spinand, 0, 1, id); in spinand_id_detect()
986 ret = spinand_manufacturer_match(spinand, in spinand_id_detect()
992 static int spinand_manufacturer_init(struct spinand_device *spinand) in spinand_manufacturer_init() argument
994 if (spinand->manufacturer->ops->init) in spinand_manufacturer_init()
995 return spinand->manufacturer->ops->init(spinand); in spinand_manufacturer_init()
1000 static void spinand_manufacturer_cleanup(struct spinand_device *spinand) in spinand_manufacturer_cleanup() argument
1003 if (spinand->manufacturer->ops->cleanup) in spinand_manufacturer_cleanup()
1004 return spinand->manufacturer->ops->cleanup(spinand); in spinand_manufacturer_cleanup()
1008 spinand_select_op_variant(struct spinand_device *spinand, in spinand_select_op_variant() argument
1011 struct nand_device *nand = spinand_to_nand(spinand); in spinand_select_op_variant()
1024 ret = spi_mem_adjust_op_size(spinand->slave, &op); in spinand_select_op_variant()
1028 if (!spi_mem_supports_op(spinand->slave, &op)) in spinand_select_op_variant()
1056 int spinand_match_and_init(struct spinand_device *spinand, in spinand_match_and_init() argument
1061 u8 *id = spinand->id.data; in spinand_match_and_init()
1062 struct nand_device *nand = spinand_to_nand(spinand); in spinand_match_and_init()
1077 spinand->eccinfo = table[i].eccinfo; in spinand_match_and_init()
1078 spinand->flags = table[i].flags; in spinand_match_and_init()
1079 spinand->id.len = 1 + table[i].devid.len; in spinand_match_and_init()
1080 spinand->select_target = table[i].select_target; in spinand_match_and_init()
1082 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
1087 spinand->op_templates.read_cache = op; in spinand_match_and_init()
1089 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
1094 spinand->op_templates.write_cache = op; in spinand_match_and_init()
1096 op = spinand_select_op_variant(spinand, in spinand_match_and_init()
1098 spinand->op_templates.update_cache = op; in spinand_match_and_init()
1106 static int spinand_detect(struct spinand_device *spinand) in spinand_detect() argument
1108 struct nand_device *nand = spinand_to_nand(spinand); in spinand_detect()
1112 ret = spinand_reset_op(spinand); in spinand_detect()
1117 ret = spinand_id_detect(spinand); in spinand_detect()
1120 spinand->id.data[0], spinand->id.data[1], spinand->id.data[2]); in spinand_detect()
1124 spinand->id.data[0], spinand->id.data[1], spinand->id.data[2]); in spinand_detect()
1126 if (nand->memorg.ntargets > 1 && !spinand->select_target) { in spinand_detect()
1132 dev_info(spinand->slave->dev, in spinand_detect()
1133 "%s SPI NAND was found.\n", spinand->manufacturer->name); in spinand_detect()
1134 dev_info(spinand->slave->dev, in spinand_detect()
1166 static int spinand_init(struct spinand_device *spinand) in spinand_init() argument
1168 struct mtd_info *mtd = spinand_to_mtd(spinand); in spinand_init()
1176 spinand->scratchbuf = kzalloc(SPINAND_MAX_ID_LEN, GFP_KERNEL); in spinand_init()
1177 if (!spinand->scratchbuf) in spinand_init()
1180 ret = spinand_detect(spinand); in spinand_init()
1189 spinand->databuf = kzalloc(nanddev_page_size(nand) + in spinand_init()
1192 if (!spinand->databuf) { in spinand_init()
1197 spinand->oobbuf = spinand->databuf + nanddev_page_size(nand); in spinand_init()
1199 ret = spinand_init_cfg_cache(spinand); in spinand_init()
1203 ret = spinand_init_quad_enable(spinand); in spinand_init()
1207 ret = spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0); in spinand_init()
1211 ret = spinand_manufacturer_init(spinand); in spinand_init()
1221 ret = spinand_select_target(spinand, i); in spinand_init()
1226 if (spinand->id.data[0] == 0x01) { in spinand_init()
1227 ret = spinand_lock_block(spinand, HWP_EN); in spinand_init()
1232 ret = spinand_lock_block(spinand, BL_ALL_UNLOCKED); in spinand_init()
1253 if (spinand->eccinfo.ooblayout) in spinand_init()
1254 mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout); in spinand_init()
1274 spinand_manufacturer_cleanup(spinand); in spinand_init()
1277 kfree(spinand->databuf); in spinand_init()
1278 kfree(spinand->scratchbuf); in spinand_init()
1282 static void spinand_cleanup(struct spinand_device *spinand) in spinand_cleanup() argument
1284 struct nand_device *nand = spinand_to_nand(spinand); in spinand_cleanup()
1287 spinand_manufacturer_cleanup(spinand); in spinand_cleanup()
1288 kfree(spinand->databuf); in spinand_cleanup()
1289 kfree(spinand->scratchbuf); in spinand_cleanup()
1309 struct spinand_device *spinand = dev_get_priv(dev); in spinand_probe() local
1312 struct nand_device *nand = spinand_to_nand(spinand); in spinand_probe()
1316 spinand = devm_kzalloc(&mem->spi->dev, sizeof(*spinand), in spinand_probe()
1318 if (!spinand) in spinand_probe()
1321 spinand->spimem = mem; in spinand_probe()
1322 spi_mem_set_drvdata(mem, spinand); in spinand_probe()
1323 spinand_set_of_node(spinand, mem->spi->dev.of_node); in spinand_probe()
1324 mutex_init(&spinand->lock); in spinand_probe()
1326 mtd = spinand_to_mtd(spinand); in spinand_probe()
1336 spinand->slave = slave; in spinand_probe()
1337 spinand_set_of_node(spinand, dev->node.np); in spinand_probe()
1340 ret = spinand_init(spinand); in spinand_probe()
1355 spinand_cleanup(spinand); in spinand_probe()
1363 struct spinand_device *spinand; in spinand_remove() local
1367 spinand = spi_mem_get_drvdata(slave); in spinand_remove()
1368 mtd = spinand_to_mtd(spinand); in spinand_remove()
1375 spinand_cleanup(spinand); in spinand_remove()
1415 U_BOOT_DRIVER(spinand) = {