xref: /rk3399_rockchip-uboot/drivers/mtd/nand/spi/foresee.c (revision 1a9d1d0db00bb2fdb5cd966f648297faabe92fe4)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Grandstream Networks, Inc
4  *
5  * Authors:
6  *	Carl <xjxia@grandstream.cn>
7  */
8 
9 #ifndef __UBOOT__
10 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #endif
13 #include <linux/mtd/spinand.h>
14 
15 #define SPINAND_MFR_FORESEE		0xCD
16 
17 static SPINAND_OP_VARIANTS(read_cache_variants,
18 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
19 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
20 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
21 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
22 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
23 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
24 
25 static SPINAND_OP_VARIANTS(write_cache_variants,
26 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
27 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
28 
29 static SPINAND_OP_VARIANTS(update_cache_variants,
30 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
31 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
32 
33 static int fsxxndxxg_ooblayout_ecc(struct mtd_info *mtd, int section,
34 				   struct mtd_oob_region *region)
35 {
36 	return -ERANGE;
37 }
38 
39 static int fsxxndxxg_ooblayout_free(struct mtd_info *mtd, int section,
40 				    struct mtd_oob_region *region)
41 {
42 	if (section)
43 		return -ERANGE;
44 
45 	region->offset = 2;
46 	region->length = mtd->oobsize - 2;
47 
48 	return 0;
49 }
50 
51 static const struct mtd_ooblayout_ops fsxxndxxg_ooblayout = {
52 	.ecc = fsxxndxxg_ooblayout_ecc,
53 	.rfree = fsxxndxxg_ooblayout_free,
54 };
55 
56 static int f35sqb00xg_ooblayout_ecc(struct mtd_info *mtd, int section,
57 				    struct mtd_oob_region *region)
58 {
59 	if (section > 0)
60 		return -ERANGE;
61 
62 	region->offset = mtd->oobsize / 2;
63 	region->length = mtd->oobsize / 2;
64 
65 	return 0;
66 }
67 
68 static int f35sqb00xg_ooblayout_free(struct mtd_info *mtd, int section,
69 				     struct mtd_oob_region *region)
70 {
71 	if (section)
72 		return -ERANGE;
73 
74 	/* 2 bytes reserved for BBM */
75 	region->offset = 2;
76 	region->length = mtd->oobsize / 2 - 2;
77 
78 	return 0;
79 }
80 
81 static const struct mtd_ooblayout_ops f35sqb00xg_ooblayout = {
82 	.ecc = f35sqb00xg_ooblayout_ecc,
83 	.rfree = f35sqb00xg_ooblayout_free,
84 };
85 
86 /*
87  * ecc bits: 0xC0[4,6]
88  * [0b000], No bit errors were detected;
89  * [0b001, 0b101], 3~7 Bit errors were detected and corrected. Not
90  *	reach Flipping Bits;
91  * [0b110], Bit error count equals the bit flip detection threshold
92  * [0b111], Bit errors greater than ECC capability(8 bits) and not corrected;
93  */
94 static int f35sqb00xg_ecc_get_status(struct spinand_device *spinand, u8 status)
95 {
96 	struct nand_device *nand = spinand_to_nand(spinand);
97 	u8 eccsr = (status & GENMASK(6, 4)) >> 4;
98 
99 	if (eccsr < 6)
100 		return 0;
101 	else if (eccsr == 6)
102 		return nand->eccreq.strength;
103 	else
104 		return -EBADMSG;
105 }
106 
107 static const struct spinand_info foresee_spinand_table[] = {
108 	SPINAND_INFO("FS35ND01G-S1Y2",
109 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEA),
110 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
111 		     NAND_ECCREQ(4, 512),
112 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
113 					      &write_cache_variants,
114 					      &update_cache_variants),
115 		     0,
116 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
117 	SPINAND_INFO("FS35ND02G-S3Y2",
118 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
119 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
120 		     NAND_ECCREQ(4, 512),
121 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
122 					      &write_cache_variants,
123 					      &update_cache_variants),
124 		     0,
125 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
126 	SPINAND_INFO("FS35ND04G-S2Y2",
127 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEC),
128 		     NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
129 		     NAND_ECCREQ(4, 512),
130 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
131 					      &write_cache_variants,
132 					      &update_cache_variants),
133 		     0,
134 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
135 	SPINAND_INFO("F35SQA001G",
136 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71),
137 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
138 		     NAND_ECCREQ(1, 512),
139 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
140 					      &write_cache_variants,
141 					      &update_cache_variants),
142 		     SPINAND_HAS_QE_BIT,
143 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
144 	SPINAND_INFO("F35SQA002G",
145 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x72),
146 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
147 		     NAND_ECCREQ(1, 512),
148 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
149 					      &write_cache_variants,
150 					      &update_cache_variants),
151 		     SPINAND_HAS_QE_BIT,
152 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
153 	SPINAND_INFO("F35SQA512M",
154 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x70),
155 		     NAND_MEMORG(1, 2048, 64, 64, 512, 1, 1, 1),
156 		     NAND_ECCREQ(1, 512),
157 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
158 					      &write_cache_variants,
159 					      &update_cache_variants),
160 		     SPINAND_HAS_QE_BIT,
161 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
162 	SPINAND_INFO("F35UQA512M",
163 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x60),
164 		     NAND_MEMORG(1, 2048, 64, 64, 512, 1, 1, 1),
165 		     NAND_ECCREQ(1, 512),
166 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
167 					      &write_cache_variants,
168 					      &update_cache_variants),
169 		     SPINAND_HAS_QE_BIT,
170 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
171 	SPINAND_INFO("F35UQA002G-WWT",
172 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x62),
173 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
174 		     NAND_ECCREQ(1, 512),
175 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
176 					      &write_cache_variants,
177 					      &update_cache_variants),
178 		     SPINAND_HAS_QE_BIT,
179 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
180 	SPINAND_INFO("F35UQA001G-WWT",
181 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x61),
182 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
183 		     NAND_ECCREQ(1, 512),
184 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
185 					      &write_cache_variants,
186 					      &update_cache_variants),
187 		     SPINAND_HAS_QE_BIT,
188 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)),
189 	SPINAND_INFO("F35SQB004G",
190 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x53),
191 		     NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
192 		     NAND_ECCREQ(8, 512),
193 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
194 					      &write_cache_variants,
195 					      &update_cache_variants),
196 		     SPINAND_HAS_QE_BIT,
197 		     SPINAND_ECCINFO(&f35sqb00xg_ooblayout, f35sqb00xg_ecc_get_status)),
198 	SPINAND_INFO("F35SQB002G",
199 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
200 		     NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
201 		     NAND_ECCREQ(8, 512),
202 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
203 					      &write_cache_variants,
204 					      &update_cache_variants),
205 		     SPINAND_HAS_QE_BIT,
206 		     SPINAND_ECCINFO(&fsxxndxxg_ooblayout, f35sqb00xg_ecc_get_status)),
207 };
208 
209 static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = {
210 };
211 
212 const struct spinand_manufacturer foresee_spinand_manufacturer = {
213 	.id = SPINAND_MFR_FORESEE,
214 	.name = "foresee",
215 	.chips = foresee_spinand_table,
216 	.nchips = ARRAY_SIZE(foresee_spinand_table),
217 	.ops = &foresee_spinand_manuf_ops,
218 };
219