xref: /linux/drivers/mtd/nand/spi/micron.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1a508e887SPeter Pan // SPDX-License-Identifier: GPL-2.0
2a508e887SPeter Pan /*
3a508e887SPeter Pan  * Copyright (c) 2016-2017 Micron Technology, Inc.
4a508e887SPeter Pan  *
5a508e887SPeter Pan  * Authors:
6a508e887SPeter Pan  *	Peter Pan <peterpandong@micron.com>
7a508e887SPeter Pan  */
8a508e887SPeter Pan 
9a508e887SPeter Pan #include <linux/device.h>
10a508e887SPeter Pan #include <linux/kernel.h>
11a508e887SPeter Pan #include <linux/mtd/spinand.h>
12a508e887SPeter Pan 
13a508e887SPeter Pan #define SPINAND_MFR_MICRON		0x2c
14a508e887SPeter Pan 
15*9836a987SMartin Kurbanov #define MICRON_STATUS_ECC_MASK		GENMASK(6, 4)
16a508e887SPeter Pan #define MICRON_STATUS_ECC_NO_BITFLIPS	(0 << 4)
17a508e887SPeter Pan #define MICRON_STATUS_ECC_1TO3_BITFLIPS	(1 << 4)
18a508e887SPeter Pan #define MICRON_STATUS_ECC_4TO6_BITFLIPS	(3 << 4)
19a508e887SPeter Pan #define MICRON_STATUS_ECC_7TO8_BITFLIPS	(5 << 4)
20a508e887SPeter Pan 
210bc68af9SShivamurthy Shastri #define MICRON_CFG_CR			BIT(0)
220bc68af9SShivamurthy Shastri 
239f9ae0c2SShivamurthy Shastri /*
249f9ae0c2SShivamurthy Shastri  * As per datasheet, die selection is done by the 6th bit of Die
259f9ae0c2SShivamurthy Shastri  * Select Register (Address 0xD0).
269f9ae0c2SShivamurthy Shastri  */
279f9ae0c2SShivamurthy Shastri #define MICRON_DIE_SELECT_REG	0xD0
289f9ae0c2SShivamurthy Shastri 
299f9ae0c2SShivamurthy Shastri #define MICRON_SELECT_DIE(x)	((x) << 6)
309f9ae0c2SShivamurthy Shastri 
31bdb84a22SThirumalesha Narasimhappa static SPINAND_OP_VARIANTS(quadio_read_cache_variants,
32a508e887SPeter Pan 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
33a508e887SPeter Pan 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
34a508e887SPeter Pan 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
35a508e887SPeter Pan 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
36a508e887SPeter Pan 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
37a508e887SPeter Pan 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
38a508e887SPeter Pan 
39bdb84a22SThirumalesha Narasimhappa static SPINAND_OP_VARIANTS(x4_write_cache_variants,
40a508e887SPeter Pan 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
41a508e887SPeter Pan 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
42a508e887SPeter Pan 
43bdb84a22SThirumalesha Narasimhappa static SPINAND_OP_VARIANTS(x4_update_cache_variants,
44a508e887SPeter Pan 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
45a508e887SPeter Pan 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
46a508e887SPeter Pan 
478c573d94SThirumalesha Narasimhappa /* Micron  MT29F2G01AAAED Device */
488c573d94SThirumalesha Narasimhappa static SPINAND_OP_VARIANTS(x4_read_cache_variants,
498c573d94SThirumalesha Narasimhappa 			   SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
508c573d94SThirumalesha Narasimhappa 			   SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
518c573d94SThirumalesha Narasimhappa 			   SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
528c573d94SThirumalesha Narasimhappa 			   SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
538c573d94SThirumalesha Narasimhappa 
548c573d94SThirumalesha Narasimhappa static SPINAND_OP_VARIANTS(x1_write_cache_variants,
558c573d94SThirumalesha Narasimhappa 			   SPINAND_PROG_LOAD(true, 0, NULL, 0));
568c573d94SThirumalesha Narasimhappa 
578c573d94SThirumalesha Narasimhappa static SPINAND_OP_VARIANTS(x1_update_cache_variants,
588c573d94SThirumalesha Narasimhappa 			   SPINAND_PROG_LOAD(false, 0, NULL, 0));
598c573d94SThirumalesha Narasimhappa 
micron_8_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)60d3137043SShivamurthy Shastri static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
61a508e887SPeter Pan 				  struct mtd_oob_region *region)
62a508e887SPeter Pan {
63a508e887SPeter Pan 	if (section)
64a508e887SPeter Pan 		return -ERANGE;
65a508e887SPeter Pan 
66d3137043SShivamurthy Shastri 	region->offset = mtd->oobsize / 2;
67d3137043SShivamurthy Shastri 	region->length = mtd->oobsize / 2;
68a508e887SPeter Pan 
69a508e887SPeter Pan 	return 0;
70a508e887SPeter Pan }
71a508e887SPeter Pan 
micron_8_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)72d3137043SShivamurthy Shastri static int micron_8_ooblayout_free(struct mtd_info *mtd, int section,
73a508e887SPeter Pan 				   struct mtd_oob_region *region)
74a508e887SPeter Pan {
75a508e887SPeter Pan 	if (section)
76a508e887SPeter Pan 		return -ERANGE;
77a508e887SPeter Pan 
78a508e887SPeter Pan 	/* Reserve 2 bytes for the BBM. */
79a508e887SPeter Pan 	region->offset = 2;
80d3137043SShivamurthy Shastri 	region->length = (mtd->oobsize / 2) - 2;
81a508e887SPeter Pan 
82a508e887SPeter Pan 	return 0;
83a508e887SPeter Pan }
84a508e887SPeter Pan 
85d3137043SShivamurthy Shastri static const struct mtd_ooblayout_ops micron_8_ooblayout = {
86d3137043SShivamurthy Shastri 	.ecc = micron_8_ooblayout_ecc,
87d3137043SShivamurthy Shastri 	.free = micron_8_ooblayout_free,
88a508e887SPeter Pan };
89a508e887SPeter Pan 
micron_4_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)908c573d94SThirumalesha Narasimhappa static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section,
918c573d94SThirumalesha Narasimhappa 				  struct mtd_oob_region *region)
928c573d94SThirumalesha Narasimhappa {
938c573d94SThirumalesha Narasimhappa 	struct spinand_device *spinand = mtd_to_spinand(mtd);
948c573d94SThirumalesha Narasimhappa 
958c573d94SThirumalesha Narasimhappa 	if (section >= spinand->base.memorg.pagesize /
968c573d94SThirumalesha Narasimhappa 			mtd->ecc_step_size)
978c573d94SThirumalesha Narasimhappa 		return -ERANGE;
988c573d94SThirumalesha Narasimhappa 
998c573d94SThirumalesha Narasimhappa 	region->offset = (section * 16) + 8;
1008c573d94SThirumalesha Narasimhappa 	region->length = 8;
1018c573d94SThirumalesha Narasimhappa 
1028c573d94SThirumalesha Narasimhappa 	return 0;
1038c573d94SThirumalesha Narasimhappa }
1048c573d94SThirumalesha Narasimhappa 
micron_4_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)1058c573d94SThirumalesha Narasimhappa static int micron_4_ooblayout_free(struct mtd_info *mtd, int section,
1068c573d94SThirumalesha Narasimhappa 				   struct mtd_oob_region *region)
1078c573d94SThirumalesha Narasimhappa {
1088c573d94SThirumalesha Narasimhappa 	struct spinand_device *spinand = mtd_to_spinand(mtd);
1098c573d94SThirumalesha Narasimhappa 
1108c573d94SThirumalesha Narasimhappa 	if (section >= spinand->base.memorg.pagesize /
1118c573d94SThirumalesha Narasimhappa 			mtd->ecc_step_size)
1128c573d94SThirumalesha Narasimhappa 		return -ERANGE;
1138c573d94SThirumalesha Narasimhappa 
1148c573d94SThirumalesha Narasimhappa 	if (section) {
1158c573d94SThirumalesha Narasimhappa 		region->offset = 16 * section;
1168c573d94SThirumalesha Narasimhappa 		region->length = 8;
1178c573d94SThirumalesha Narasimhappa 	} else {
1188c573d94SThirumalesha Narasimhappa 		/* section 0 has two bytes reserved for the BBM */
1198c573d94SThirumalesha Narasimhappa 		region->offset = 2;
1208c573d94SThirumalesha Narasimhappa 		region->length = 6;
1218c573d94SThirumalesha Narasimhappa 	}
1228c573d94SThirumalesha Narasimhappa 
1238c573d94SThirumalesha Narasimhappa 	return 0;
1248c573d94SThirumalesha Narasimhappa }
1258c573d94SThirumalesha Narasimhappa 
1268c573d94SThirumalesha Narasimhappa static const struct mtd_ooblayout_ops micron_4_ooblayout = {
1278c573d94SThirumalesha Narasimhappa 	.ecc = micron_4_ooblayout_ecc,
1288c573d94SThirumalesha Narasimhappa 	.free = micron_4_ooblayout_free,
1298c573d94SThirumalesha Narasimhappa };
1308c573d94SThirumalesha Narasimhappa 
micron_select_target(struct spinand_device * spinand,unsigned int target)1319f9ae0c2SShivamurthy Shastri static int micron_select_target(struct spinand_device *spinand,
1329f9ae0c2SShivamurthy Shastri 				unsigned int target)
1339f9ae0c2SShivamurthy Shastri {
1349f9ae0c2SShivamurthy Shastri 	struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MICRON_DIE_SELECT_REG,
1359f9ae0c2SShivamurthy Shastri 						      spinand->scratchbuf);
1369f9ae0c2SShivamurthy Shastri 
1379f9ae0c2SShivamurthy Shastri 	if (target > 1)
1389f9ae0c2SShivamurthy Shastri 		return -EINVAL;
1399f9ae0c2SShivamurthy Shastri 
1409f9ae0c2SShivamurthy Shastri 	*spinand->scratchbuf = MICRON_SELECT_DIE(target);
1419f9ae0c2SShivamurthy Shastri 
1429f9ae0c2SShivamurthy Shastri 	return spi_mem_exec_op(spinand->spimem, &op);
1439f9ae0c2SShivamurthy Shastri }
1449f9ae0c2SShivamurthy Shastri 
micron_8_ecc_get_status(struct spinand_device * spinand,u8 status)145d3137043SShivamurthy Shastri static int micron_8_ecc_get_status(struct spinand_device *spinand,
146a508e887SPeter Pan 				   u8 status)
147a508e887SPeter Pan {
148a508e887SPeter Pan 	switch (status & MICRON_STATUS_ECC_MASK) {
149a508e887SPeter Pan 	case STATUS_ECC_NO_BITFLIPS:
150a508e887SPeter Pan 		return 0;
151a508e887SPeter Pan 
152a508e887SPeter Pan 	case STATUS_ECC_UNCOR_ERROR:
153a508e887SPeter Pan 		return -EBADMSG;
154a508e887SPeter Pan 
155a508e887SPeter Pan 	case MICRON_STATUS_ECC_1TO3_BITFLIPS:
156a508e887SPeter Pan 		return 3;
157a508e887SPeter Pan 
158a508e887SPeter Pan 	case MICRON_STATUS_ECC_4TO6_BITFLIPS:
159a508e887SPeter Pan 		return 6;
160a508e887SPeter Pan 
161a508e887SPeter Pan 	case MICRON_STATUS_ECC_7TO8_BITFLIPS:
162a508e887SPeter Pan 		return 8;
163a508e887SPeter Pan 
164a508e887SPeter Pan 	default:
165a508e887SPeter Pan 		break;
166a508e887SPeter Pan 	}
167a508e887SPeter Pan 
168a508e887SPeter Pan 	return -EINVAL;
169a508e887SPeter Pan }
170a508e887SPeter Pan 
171a508e887SPeter Pan static const struct spinand_info micron_spinand_table[] = {
1728511a3a9SShivamurthy Shastri 	/* M79A 2Gb 3.3V */
173f1541773SChuanhong Guo 	SPINAND_INFO("MT29F2G01ABAGD",
174f1541773SChuanhong Guo 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
175377e517bSBoris Brezillon 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
176a508e887SPeter Pan 		     NAND_ECCREQ(8, 512),
177bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
178bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
179bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
180a508e887SPeter Pan 		     0,
181d3137043SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
182d3137043SShivamurthy Shastri 				     micron_8_ecc_get_status)),
183a15335a1SShivamurthy Shastri 	/* M79A 2Gb 1.8V */
184a15335a1SShivamurthy Shastri 	SPINAND_INFO("MT29F2G01ABBGD",
185a15335a1SShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
186a15335a1SShivamurthy Shastri 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
187a15335a1SShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
188bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
189bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
190bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
191a15335a1SShivamurthy Shastri 		     0,
192a15335a1SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
193a15335a1SShivamurthy Shastri 				     micron_8_ecc_get_status)),
194a15335a1SShivamurthy Shastri 	/* M78A 1Gb 3.3V */
195a15335a1SShivamurthy Shastri 	SPINAND_INFO("MT29F1G01ABAFD",
196a15335a1SShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
197a15335a1SShivamurthy Shastri 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
198a15335a1SShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
199bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
200bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
201bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
202a15335a1SShivamurthy Shastri 		     0,
203a15335a1SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
204a15335a1SShivamurthy Shastri 				     micron_8_ecc_get_status)),
205a15335a1SShivamurthy Shastri 	/* M78A 1Gb 1.8V */
206a15335a1SShivamurthy Shastri 	SPINAND_INFO("MT29F1G01ABAFD",
207a15335a1SShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
208a15335a1SShivamurthy Shastri 		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
209a15335a1SShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
210bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
211bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
212bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
213a15335a1SShivamurthy Shastri 		     0,
214a15335a1SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
215a15335a1SShivamurthy Shastri 				     micron_8_ecc_get_status)),
2169f9ae0c2SShivamurthy Shastri 	/* M79A 4Gb 3.3V */
2179f9ae0c2SShivamurthy Shastri 	SPINAND_INFO("MT29F4G01ADAGD",
2189f9ae0c2SShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
2199f9ae0c2SShivamurthy Shastri 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2),
2209f9ae0c2SShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
221bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
222bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
223bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
2249f9ae0c2SShivamurthy Shastri 		     0,
2259f9ae0c2SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
2269f9ae0c2SShivamurthy Shastri 				     micron_8_ecc_get_status),
2279f9ae0c2SShivamurthy Shastri 		     SPINAND_SELECT_TARGET(micron_select_target)),
228a7e5daccSShivamurthy Shastri 	/* M70A 4Gb 3.3V */
229a7e5daccSShivamurthy Shastri 	SPINAND_INFO("MT29F4G01ABAFD",
230a7e5daccSShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
231a7e5daccSShivamurthy Shastri 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
232a7e5daccSShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
233bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
234bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
235bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
236a7e5daccSShivamurthy Shastri 		     SPINAND_HAS_CR_FEAT_BIT,
237a7e5daccSShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
238a7e5daccSShivamurthy Shastri 				     micron_8_ecc_get_status)),
239a7e5daccSShivamurthy Shastri 	/* M70A 4Gb 1.8V */
240a7e5daccSShivamurthy Shastri 	SPINAND_INFO("MT29F4G01ABBFD",
241a7e5daccSShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
242a7e5daccSShivamurthy Shastri 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
243a7e5daccSShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
244bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
245bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
246bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
247a7e5daccSShivamurthy Shastri 		     SPINAND_HAS_CR_FEAT_BIT,
248a7e5daccSShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
249a7e5daccSShivamurthy Shastri 				     micron_8_ecc_get_status)),
2509f9ae0c2SShivamurthy Shastri 	/* M70A 8Gb 3.3V */
2519f9ae0c2SShivamurthy Shastri 	SPINAND_INFO("MT29F8G01ADAFD",
2529f9ae0c2SShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
2539f9ae0c2SShivamurthy Shastri 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
2549f9ae0c2SShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
255bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
256bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
257bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
2589f9ae0c2SShivamurthy Shastri 		     SPINAND_HAS_CR_FEAT_BIT,
2599f9ae0c2SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
2609f9ae0c2SShivamurthy Shastri 				     micron_8_ecc_get_status),
2619f9ae0c2SShivamurthy Shastri 		     SPINAND_SELECT_TARGET(micron_select_target)),
2629f9ae0c2SShivamurthy Shastri 	/* M70A 8Gb 1.8V */
2639f9ae0c2SShivamurthy Shastri 	SPINAND_INFO("MT29F8G01ADBFD",
2649f9ae0c2SShivamurthy Shastri 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
2659f9ae0c2SShivamurthy Shastri 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
2669f9ae0c2SShivamurthy Shastri 		     NAND_ECCREQ(8, 512),
267bdb84a22SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
268bdb84a22SThirumalesha Narasimhappa 					      &x4_write_cache_variants,
269bdb84a22SThirumalesha Narasimhappa 					      &x4_update_cache_variants),
2709f9ae0c2SShivamurthy Shastri 		     SPINAND_HAS_CR_FEAT_BIT,
2719f9ae0c2SShivamurthy Shastri 		     SPINAND_ECCINFO(&micron_8_ooblayout,
2729f9ae0c2SShivamurthy Shastri 				     micron_8_ecc_get_status),
2739f9ae0c2SShivamurthy Shastri 		     SPINAND_SELECT_TARGET(micron_select_target)),
2748c573d94SThirumalesha Narasimhappa 	/* M69A 2Gb 3.3V */
2758c573d94SThirumalesha Narasimhappa 	SPINAND_INFO("MT29F2G01AAAED",
2768c573d94SThirumalesha Narasimhappa 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F),
2778c573d94SThirumalesha Narasimhappa 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1),
2788c573d94SThirumalesha Narasimhappa 		     NAND_ECCREQ(4, 512),
2798c573d94SThirumalesha Narasimhappa 		     SPINAND_INFO_OP_VARIANTS(&x4_read_cache_variants,
2808c573d94SThirumalesha Narasimhappa 					      &x1_write_cache_variants,
2818c573d94SThirumalesha Narasimhappa 					      &x1_update_cache_variants),
2828c573d94SThirumalesha Narasimhappa 		     0,
2838c573d94SThirumalesha Narasimhappa 		     SPINAND_ECCINFO(&micron_4_ooblayout, NULL)),
284a508e887SPeter Pan };
285a508e887SPeter Pan 
micron_spinand_init(struct spinand_device * spinand)2860bc68af9SShivamurthy Shastri static int micron_spinand_init(struct spinand_device *spinand)
2870bc68af9SShivamurthy Shastri {
2880bc68af9SShivamurthy Shastri 	/*
2890bc68af9SShivamurthy Shastri 	 * M70A device series enable Continuous Read feature at Power-up,
2900bc68af9SShivamurthy Shastri 	 * which is not supported. Disable this bit to avoid any possible
2910bc68af9SShivamurthy Shastri 	 * failure.
2920bc68af9SShivamurthy Shastri 	 */
2930bc68af9SShivamurthy Shastri 	if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT)
2940bc68af9SShivamurthy Shastri 		return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0);
2950bc68af9SShivamurthy Shastri 
2960bc68af9SShivamurthy Shastri 	return 0;
2970bc68af9SShivamurthy Shastri }
2980bc68af9SShivamurthy Shastri 
299a508e887SPeter Pan static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
3000bc68af9SShivamurthy Shastri 	.init = micron_spinand_init,
301a508e887SPeter Pan };
302a508e887SPeter Pan 
303a508e887SPeter Pan const struct spinand_manufacturer micron_spinand_manufacturer = {
304a508e887SPeter Pan 	.id = SPINAND_MFR_MICRON,
305a508e887SPeter Pan 	.name = "Micron",
306f1541773SChuanhong Guo 	.chips = micron_spinand_table,
307f1541773SChuanhong Guo 	.nchips = ARRAY_SIZE(micron_spinand_table),
308a508e887SPeter Pan 	.ops = &micron_spinand_manuf_ops,
309a508e887SPeter Pan };
310