xref: /rk3399_rockchip-uboot/drivers/rkflash/sfc_nand.c (revision a6fcac41dcbdc77a6ec6d15768472f0f658372eb)
1 /*
2  * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0
5  */
6 
7 #include <common.h>
8 #include <linux/bug.h>
9 #include <linux/delay.h>
10 
11 #include "flash_com.h"
12 #include "rkflash_debug.h"
13 #include "rk_sftl.h"
14 #include "sfc.h"
15 #include "sfc_nand.h"
16 
17 static struct nand_info spi_nand_tbl[] = {
18 	/* TC58CVG0S0HxAIx */
19 	{0x98C2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 18, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL},
20 	/* TC58CVG1S0HxAIx */
21 	{0x98CB, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 19, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL},
22 	/* MX35LF1GE4AB */
23 	{0xC212, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
24 	/* MX35LF2GE4AB */
25 	{0xC222, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
26 	/* GD5F1GQ4UAYIG */
27 	{0xC8F1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, NULL},
28 	/* MT29F1G01ZAC */
29 	{0x2C12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
30 	/* GD5F2GQ40BY2GR */
31 	{0xC8D2, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp3},
32 	/* GD5F1GQ4RB9IGR */
33 	{0xC8D1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp3},
34 	/* IS37SML01G1 */
35 	{0xC821, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xFF, 0xFF, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
36 	/* W25N01GV */
37 	{0xEFAA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xFF, 0xFF, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
38 	/* HYF2GQ4UAACAE */
39 	{0xC952, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 14, 0xB0, 0, {4, 36, 0xff, 0xff}, NULL},
40 	/* HYF2GQ4UDACAE */
41 	{0xC922, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, NULL},
42 	/* HYF2GQ4UHCCAE */
43 	{0xC95A, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 14, 0xB0, 0, {4, 36, 0xff, 0xff}, NULL},
44 	/* HYF1GQ4UDACAE */
45 	{0xC921, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, NULL},
46 	/* F50L1G41LB */
47 	{0xC801, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xFF, 0xFF, {20, 36, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
48 	/* XT26G02A */
49 	{0x0BE2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4},
50 	/* XT26G01A */
51 	{0x0BE1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4},
52 	/* FS35ND01G-S1 */
53 	{0xCDB1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0x0, {16, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp5},
54 	/* FS35ND02G-S2 */
55 	{0xCDA2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x03, 0x02, 0xD8, 0x00, 19, 4, 0xFF, 0xFF, {16, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp5},
56 	/* DS35Q1GA-1B */
57 	{0xE571, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0x0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
58 	/* DS35Q2GA-1B */
59 	{0xE572, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0x0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
60 	/* EM73C044SNC-G */
61 	{0xD522, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0x0, {4, 20, 0xff, 0xff}, NULL},
62 	/* EM73D044SNB-G */
63 	{0xD520, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0x0, {4, 20, 0xff, 0xff}, NULL},
64 	/* ATO25D1GA */
65 	{0x9B12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x40, 18, 1, 0xB0, 0x0, {20, 36, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
66 	/* XT26G02B */
67 	{0x0BF2, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp5},
68 	/* XT26G01B */
69 	{0x0BF1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4},
70 	/* HYF4GQ4UAACBE */
71 	{0xC9D4, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 4, 0xB0, 0, {32, 64, 36, 68}, NULL},
72 	/* FM25S01 */
73 	{0xA1A1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 1, 0xB0, 0, {0, 4, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
74 	/* HYF1GQ4UPACAE */
75 	{0xC9A1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 18, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp1},
76 	/* EM73E044SNA-G */
77 	{0xD503, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 8, 0xB0, 0, {4, 40, 8, 44}, NULL},
78 	/* GD5F2GQ5UEYIG */
79 	{0xC852, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 19, 4, 0xB0, 0, {4, 20, 0xff, 0xff}, &sfc_nand_ecc_status_sp2},
80 	/* GD5F1GQ4R */
81 	{0xC8C1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0,  {4, 8, 0xff, 0xff}, &sfc_nand_ecc_status_sp3},
82 	/* TC58CVG2S0HRAIJ */
83 	{0x98ED, 8, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 20, 8, 0xFF, 0xFF, {4, 12, 8, 16}, NULL},
84 	/* TC58CVG1S3HRAIJ */
85 	{0x98EB, 4, 64, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL},
86 	/* TC58CVG0S3HRAIJ */
87 	{0x98E2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xFF, 0xFF, {4, 8, 0xff, 0xff}, NULL},
88 	/* XT26G04A */
89 	{0x0BE3, 4, 128, 1, 2048, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x4C, 20, 1, 0xB0, 0x0, {8, 12, 0xff, 0xff}, &sfc_nand_ecc_status_sp4},
90 };
91 
92 static struct nand_info *p_nand_info;
93 static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4];
94 static struct SFNAND_DEV sfc_nand_dev;
95 
96 static struct nand_info *sfc_nand_get_info(u8 *nand_id)
97 {
98 	u32 i;
99 	u32 id = (nand_id[0] << 8) | (nand_id[1] << 0);
100 
101 	for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) {
102 		if (spi_nand_tbl[i].id == id)
103 			return &spi_nand_tbl[i];
104 	}
105 	return NULL;
106 }
107 
108 static int sfc_nand_write_en(void)
109 {
110 	int ret;
111 	union SFCCMD_DATA sfcmd;
112 
113 	sfcmd.d32 = 0;
114 	sfcmd.b.cmd = CMD_WRITE_EN;
115 	ret = sfc_request(sfcmd.d32, 0, 0, NULL);
116 	return ret;
117 }
118 
119 static int sfc_nand_rw_preset(void)
120 {
121 	int ret;
122 	union SFCCTRL_DATA sfctrl;
123 	union SFCCMD_DATA sfcmd;
124 	u8 status = 0xFF;
125 
126 	sfcmd.d32 = 0;
127 	sfcmd.b.cmd = 0;
128 	sfcmd.b.datasize = 1;
129 	sfcmd.b.rw = SFC_WRITE;
130 
131 	sfctrl.b.datalines = 2;
132 	ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, &status);
133 	return ret;
134 }
135 
136 static int sfc_nand_read_feature(u8 addr, u8 *data)
137 {
138 	int ret;
139 	union SFCCMD_DATA sfcmd;
140 
141 	sfcmd.d32 = 0;
142 	sfcmd.b.cmd = 0x0F;
143 	sfcmd.b.datasize = 1;
144 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
145 	*data = 0;
146 
147 	ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, data);
148 	if (ret != SFC_OK)
149 		return ret;
150 	return SFC_OK;
151 }
152 
153 static int sfc_nand_write_feature(u32 addr, u8 status)
154 {
155 	int ret;
156 	union SFCCMD_DATA sfcmd;
157 
158 	sfc_nand_write_en();
159 
160 	sfcmd.d32 = 0;
161 	sfcmd.b.cmd = 0x1F;
162 	sfcmd.b.datasize = 1;
163 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
164 	sfcmd.b.rw = SFC_WRITE;
165 
166 	ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, &status);
167 	if (ret != SFC_OK)
168 		return ret;
169 	return ret;
170 }
171 
172 static int sfc_nand_wait_busy(u8 *data, int timeout)
173 {
174 	int ret;
175 	int i;
176 	u8 status;
177 
178 	*data = 0;
179 	for (i = 0; i < timeout; i++) {
180 		ret = sfc_nand_read_feature(0xC0, &status);
181 		if (ret != SFC_OK)
182 			return ret;
183 		*data = status;
184 		if (!(status & (1 << 0)))
185 			return SFC_OK;
186 		sfc_delay(1);
187 	}
188 	return -1;
189 }
190 
191 /*
192  * ecc default:
193  * ecc bits: 0xC0[4,5]
194  * 0x00, No bit errors were detected
195  * 0x01, Bit errors were detected and corrected.
196  * 0x10, Multiple bit errors were detected and not corrected.
197  * 0x11, Bits errors were detected and corrected, bit error count
198  *	exceed the bit flip detection threshold
199  */
200 static u32 sfc_nand_ecc_status(void)
201 {
202 	int ret;
203 	u32 i;
204 	u8 ecc;
205 	u8 status;
206 	u32 timeout = 1000 * 1000;
207 
208 	for (i = 0; i < timeout; i++) {
209 		ret = sfc_nand_read_feature(0xC0, &status);
210 		if (ret != SFC_OK)
211 			return SFC_NAND_ECC_ERROR;
212 		if (!(status & (1 << 0)))
213 			break;
214 		sfc_delay(1);
215 	}
216 
217 	ecc = (status >> 4) & 0x03;
218 
219 	if (ecc <= 1)
220 		ret = SFC_NAND_ECC_OK;
221 	else if (ecc == 2)
222 		ret = SFC_NAND_ECC_ERROR;
223 	else
224 		ret = SFC_NAND_ECC_REFRESH;
225 
226 	return ret;
227 }
228 
229 /*
230  * ecc spectial type1:
231  * ecc bits: 0xC0[4,5]
232  * 0x00, No bit errors were detected;
233  * 0x01, Bits errors were detected and corrected, bit error count
234  *	may reach the bit flip detection threshold;
235  * 0x10, Multiple bit errors were detected and not corrected;
236  * 0x11, Reserved.
237  */
238 u32 sfc_nand_ecc_status_sp1(void)
239 {
240 	int ret;
241 	u32 i;
242 	u8 ecc;
243 	u8 status;
244 	u32 timeout = 1000 * 1000;
245 
246 	for (i = 0; i < timeout; i++) {
247 		ret = sfc_nand_read_feature(0xC0, &status);
248 		if (ret != SFC_OK)
249 			return SFC_NAND_ECC_ERROR;
250 		if (!(status & (1 << 0)))
251 			break;
252 		sfc_delay(1);
253 	}
254 
255 	ecc = (status >> 4) & 0x03;
256 
257 	if (ecc == 0)
258 		ret = SFC_NAND_ECC_OK;
259 	else if (ecc == 1)
260 		ret = SFC_NAND_ECC_REFRESH;
261 	else
262 		ret = SFC_NAND_ECC_ERROR;
263 
264 	return ret;
265 }
266 
267 /*
268  * ecc spectial type2:
269  * ecc bits: 0xC0[4,5] 0xF0[4,5]
270  * [0x0000, 0x0011], No bit errors were detected;
271  * [0x0100, 0x0111], Bit errors were detected and corrected. Not
272  *	reach Flipping Bits;
273  * [0x1000, 0x1011], Multiple bit errors were detected and
274  *	not corrected.
275  * [0x1100, 0x1111], reserved.
276  */
277 u32 sfc_nand_ecc_status_sp2(void)
278 {
279 	int ret;
280 	u32 i;
281 	u8 ecc;
282 	u8 status, status1;
283 	u32 timeout = 1000 * 1000;
284 
285 	for (i = 0; i < timeout; i++) {
286 		ret = sfc_nand_read_feature(0xC0, &status);
287 		if (ret != SFC_OK)
288 			return SFC_NAND_ECC_ERROR;
289 		ret = sfc_nand_read_feature(0xF0, &status1);
290 		if (ret != SFC_OK)
291 			return SFC_NAND_ECC_ERROR;
292 		if (!(status & (1 << 0)))
293 			break;
294 		sfc_delay(1);
295 	}
296 
297 	ecc = (status >> 4) & 0x03;
298 	ecc = (ecc << 2) | ((status1 >> 4) & 0x03);
299 	if (ecc < 7)
300 		ret = SFC_NAND_ECC_OK;
301 	else if (ecc == 7)
302 		ret = SFC_NAND_ECC_REFRESH;
303 	else
304 		ret = SFC_NAND_ECC_ERROR;
305 
306 	return ret;
307 }
308 
309 /*
310  * ecc spectial type3:
311  * ecc bits: 0xC0[4,5] 0xF0[4,5]
312  * [0x0000, 0x0011], No bit errors were detected;
313  * [0x0100, 0x0111], Bit errors were detected and corrected. Not
314  *	reach Flipping Bits;
315  * [0x1000, 0x1011], Multiple bit errors were detected and
316  *	not corrected.
317  * [0x1100, 0x1111], Bit error count equals the bit flip
318  *	detectio nthreshold
319  */
320 u32 sfc_nand_ecc_status_sp3(void)
321 {
322 	int ret;
323 	u32 i;
324 	u8 ecc;
325 	u8 status, status1;
326 	u32 timeout = 1000 * 1000;
327 
328 	for (i = 0; i < timeout; i++) {
329 		ret = sfc_nand_read_feature(0xC0, &status);
330 		if (ret != SFC_OK)
331 			return SFC_NAND_ECC_ERROR;
332 		ret = sfc_nand_read_feature(0xF0, &status1);
333 		if (ret != SFC_OK)
334 			return SFC_NAND_ECC_ERROR;
335 		if (!(status & (1 << 0)))
336 			break;
337 		sfc_delay(1);
338 	}
339 
340 	ecc = (status >> 4) & 0x03;
341 	ecc = (ecc << 2) | ((status1 >> 4) & 0x03);
342 	if (ecc < 7)
343 		ret = SFC_NAND_ECC_OK;
344 	else if (ecc == 7 || ecc >= 12)
345 		ret = SFC_NAND_ECC_REFRESH;
346 	else
347 		ret = SFC_NAND_ECC_ERROR;
348 
349 	return ret;
350 }
351 
352 /*
353  * ecc spectial type4:
354  * ecc bits: 0xC0[2,5]
355  * [0x0000], No bit errors were detected;
356  * [0x0001, 0x0111], Bit errors were detected and corrected. Not
357  *	reach Flipping Bits;
358  * [0x1000], Multiple bit errors were detected and
359  *	not corrected.
360  * [0x1100], Bit error count equals the bit flip
361  *	detectionthreshold
362  * else, reserved
363  */
364 u32 sfc_nand_ecc_status_sp4(void)
365 {
366 	int ret;
367 	u32 i;
368 	u8 ecc;
369 	u8 status;
370 	u32 timeout = 1000 * 1000;
371 
372 	for (i = 0; i < timeout; i++) {
373 		ret = sfc_nand_read_feature(0xC0, &status);
374 		if (ret != SFC_OK)
375 			return SFC_NAND_ECC_ERROR;
376 		if (!(status & (1 << 0)))
377 			break;
378 		sfc_delay(1);
379 	}
380 
381 	ecc = (status >> 2) & 0x0f;
382 	if (ecc < 7)
383 		ret = SFC_NAND_ECC_OK;
384 	else if (ecc == 7 || ecc == 12)
385 		ret = SFC_NAND_ECC_REFRESH;
386 	else
387 		ret = SFC_NAND_ECC_ERROR;
388 
389 	return ret;
390 }
391 
392 /*
393  * ecc spectial type5:
394  * ecc bits: 0xC0[4,6]
395  * [0x0], No bit errors were detected;
396  * [0x001, 0x011], Bit errors were detected and corrected. Not
397  *	reach Flipping Bits;
398  * [0x100], Bit error count equals the bit flip
399  *	detectionthreshold
400  * [0x101, 0x110], Reserved;
401  * [0x111], Multiple bit errors were detected and
402  *	not corrected.
403  */
404 u32 sfc_nand_ecc_status_sp5(void)
405 {
406 	int ret;
407 	u32 i;
408 	u8 ecc;
409 	u8 status;
410 	u32 timeout = 1000 * 1000;
411 
412 	for (i = 0; i < timeout; i++) {
413 		ret = sfc_nand_read_feature(0xC0, &status);
414 		if (ret != SFC_OK)
415 			return SFC_NAND_ECC_ERROR;
416 		if (!(status & (1 << 0)))
417 			break;
418 		sfc_delay(1);
419 	}
420 
421 	ecc = (status >> 4) & 0x07;
422 	if (ecc < 4)
423 		ret = SFC_NAND_ECC_OK;
424 	else if (ecc == 4)
425 		ret = SFC_NAND_ECC_REFRESH;
426 	else
427 		ret = SFC_NAND_ECC_ERROR;
428 
429 	return ret;
430 }
431 
432 u32 sfc_nand_erase_block(u8 cs, u32 addr)
433 {
434 	int ret;
435 	union SFCCMD_DATA sfcmd;
436 	u8 status;
437 
438 	rkflash_print_dio("%s %x\n", __func__, addr);
439 	sfcmd.d32 = 0;
440 	sfcmd.b.cmd = p_nand_info->block_erase_cmd;
441 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
442 	sfcmd.b.rw = SFC_WRITE;
443 	sfc_nand_write_en();
444 	ret = sfc_request(sfcmd.d32, 0, addr, NULL);
445 	if (ret != SFC_OK)
446 		return ret;
447 	ret = sfc_nand_wait_busy(&status, 1000 * 1000);
448 	if (status & (1 << 2))
449 		return SFC_NAND_PROG_ERASE_ERROR;
450 
451 	return ret;
452 }
453 
454 static u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf)
455 {
456 	int ret;
457 	u32 plane;
458 	union SFCCMD_DATA sfcmd;
459 	union SFCCTRL_DATA sfctrl;
460 	u8 status;
461 	u32 sec_per_page = p_nand_info->sec_per_page;
462 
463 	rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]);
464 	sfc_nand_write_en();
465 	if (sfc_nand_dev.prog_lines == DATA_LINES_X4 &&
466 	    p_nand_info->feature & FEA_SOFT_QOP_BIT &&
467 	    sfc_get_version() < SFC_VER_3)
468 		sfc_nand_rw_preset();
469 
470 	sfcmd.d32 = 0;
471 	sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd;
472 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
473 	sfcmd.b.datasize = SFC_NAND_SECTOR_FULL_SIZE * sec_per_page;
474 	sfcmd.b.rw = SFC_WRITE;
475 
476 	sfctrl.d32 = 0;
477 	sfctrl.b.datalines = sfc_nand_dev.prog_lines;
478 	sfctrl.b.addrbits = 16;
479 	plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0;
480 	sfc_request(sfcmd.d32, sfctrl.d32, plane, p_page_buf);
481 
482 	sfcmd.d32 = 0;
483 	sfcmd.b.cmd = p_nand_info->page_prog_cmd;
484 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
485 	sfcmd.b.datasize = 0;
486 	sfcmd.b.rw = SFC_WRITE;
487 	ret = sfc_request(sfcmd.d32, 0, addr, p_page_buf);
488 	if (ret != SFC_OK)
489 		return ret;
490 	ret = sfc_nand_wait_busy(&status, 1000 * 1000);
491 	if (status & (1 << 3))
492 		return SFC_NAND_PROG_ERASE_ERROR;
493 
494 	return ret;
495 }
496 
497 u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
498 {
499 	int ret;
500 	u32 sec_per_page = p_nand_info->sec_per_page;
501 	u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE;
502 	struct nand_mega_area *meta = &p_nand_info->meta;
503 
504 	memcpy(gp_page_buf, p_data, data_size);
505 	memset(&gp_page_buf[data_size / 4], 0xff, sec_per_page * 16);
506 	gp_page_buf[(data_size + meta->off0) / 4] = p_spare[0];
507 	gp_page_buf[(data_size + meta->off1) / 4] = p_spare[1];
508 	if (sec_per_page == 8) {
509 		gp_page_buf[(data_size + meta->off2) / 4] = p_spare[2];
510 		gp_page_buf[(data_size + meta->off3) / 4] = p_spare[3];
511 	}
512 	ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf);
513 
514 	return ret;
515 }
516 
517 static u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf)
518 {
519 	int ret;
520 	u32 plane;
521 	union SFCCMD_DATA sfcmd;
522 	union SFCCTRL_DATA sfctrl;
523 	u32 ecc_result;
524 	u32 sec_per_page = p_nand_info->sec_per_page;
525 	u8 status;
526 
527 	sfcmd.d32 = 0;
528 	sfcmd.b.cmd = p_nand_info->page_read_cmd;
529 	sfcmd.b.datasize = 0;
530 	sfcmd.b.rw = SFC_WRITE;
531 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
532 	sfc_request(sfcmd.d32, 0, addr, p_page_buf);
533 	if (sfc_nand_dev.read_lines == DATA_LINES_X4 &&
534 	    p_nand_info->feature & FEA_SOFT_QOP_BIT &&
535 	    sfc_get_version() < SFC_VER_3)
536 		sfc_nand_rw_preset();
537 
538 	sfc_nand_wait_busy(&status, 1000 * 1000);
539 	if (p_nand_info->ecc_status)
540 		ecc_result = p_nand_info->ecc_status();
541 	else
542 		ecc_result = sfc_nand_ecc_status();
543 
544 	sfcmd.d32 = 0;
545 	sfcmd.b.cmd = sfc_nand_dev.page_read_cmd;
546 	sfcmd.b.datasize = SFC_NAND_SECTOR_FULL_SIZE * sec_per_page;
547 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
548 	sfctrl.d32 = 0;
549 	sfctrl.b.datalines = sfc_nand_dev.read_lines;
550 
551 	plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0;
552 	ret = sfc_request(sfcmd.d32, sfctrl.d32, plane << 8, p_page_buf);
553 	rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]);
554 
555 	if (ret != SFC_OK)
556 		return SFC_NAND_ECC_ERROR;
557 
558 	return ecc_result;
559 }
560 
561 u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
562 {
563 	int ret;
564 	u32 sec_per_page = p_nand_info->sec_per_page;
565 	u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE;
566 	struct nand_mega_area *meta = &p_nand_info->meta;
567 
568 	ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf);
569 	memcpy(p_data, gp_page_buf, data_size);
570 	p_spare[0] = gp_page_buf[(data_size + meta->off0) / 4];
571 	p_spare[1] = gp_page_buf[(data_size + meta->off1) / 4];
572 	if (p_nand_info->sec_per_page == 8) {
573 		p_spare[2] = gp_page_buf[(data_size + meta->off2) / 4];
574 		p_spare[3] = gp_page_buf[(data_size + meta->off3) / 4];
575 	}
576 
577 	if (ret != SFC_NAND_ECC_OK) {
578 		rkflash_print_error("%s[0x%x], ret=0x%x\n", __func__, addr, ret);
579 		if (p_data)
580 			rkflash_print_hex("data:", p_data, 4, 8);
581 		if (p_spare)
582 			rkflash_print_hex("spare:", p_spare, 4, 2);
583 	}
584 
585 	return ret;
586 }
587 
588 u32 sfc_nand_check_bad_block(u8 cs, u32 addr)
589 {
590 	u32 ret;
591 	u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE;
592 
593 	ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf);
594 	if (ret == SFC_NAND_ECC_ERROR)
595 		return true;
596 	/* Original bad block */
597 	if ((gp_page_buf[data_size / 4] & 0xFF) != 0xFF)
598 		return true;
599 
600 	return false;
601 }
602 
603 u32 sfc_nand_mark_bad_block(u8 cs, u32 addr)
604 {
605 	u32 ret;
606 	u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE;
607 
608 	ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf);
609 	if (ret)
610 		return SFC_NAND_HW_ERROR;
611 	gp_page_buf[data_size / 4] = 0x0;
612 	ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf);
613 	if (ret)
614 		return SFC_NAND_HW_ERROR;
615 
616 	return ret;
617 }
618 
619 int sfc_nand_read_id(u8 *data)
620 {
621 	int ret;
622 	union SFCCMD_DATA sfcmd;
623 
624 	sfcmd.d32 = 0;
625 	sfcmd.b.cmd = CMD_READ_JEDECID;
626 	sfcmd.b.datasize = 3;
627 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
628 
629 	ret = sfc_request(sfcmd.d32, 0x8 << 16, 0, data);
630 
631 	return ret;
632 }
633 
634 /*
635  * Read the 1st page's 1st byte of a phy_blk
636  * If not FF, it's bad blk
637  */
638 static int sfc_nand_get_bad_block_list(u16 *table, u32 die)
639 {
640 	u16 blk;
641 	u32 bad_cnt, page;
642 	u32 blk_per_die;
643 	u32 *pread;
644 	u32 *pspare_read;
645 
646 	rkflash_print_info("%s\n", __func__);
647 	pread = ftl_malloc(SFC_NAND_PAGE_MAX_SIZE);
648 	pspare_read = ftl_malloc(8);
649 	if (!pread || !pspare_read) {
650 		kfree(pread);
651 		kfree(pspare_read);
652 		return -1;
653 	}
654 
655 	bad_cnt = 0;
656 	blk_per_die = p_nand_info->plane_per_die *
657 			p_nand_info->blk_per_plane;
658 	for (blk = 0; blk < blk_per_die; blk++) {
659 		page = (blk + blk_per_die * die) *
660 			p_nand_info->page_per_blk;
661 		sfc_nand_read_page(0, page, pread, pspare_read);
662 
663 		if (pread[0] != 0xFFFFFFFF ||
664 		    pspare_read[0] != 0xFFFFFFFF) {
665 			table[bad_cnt++] = blk;
666 			rkflash_print_error("die[%d], bad_blk[%d]\n", die, blk);
667 		}
668 	}
669 	ftl_free(pread);
670 	ftl_free(pspare_read);
671 
672 	return (int)bad_cnt;
673 }
674 
675 void sfc_nand_ftl_ops_init(void)
676 {
677 	/* para init */
678 	g_nand_phy_info.nand_type	= 1;
679 	g_nand_phy_info.die_num		= 1;
680 	g_nand_phy_info.plane_per_die	= p_nand_info->plane_per_die;
681 	g_nand_phy_info.blk_per_plane	= p_nand_info->blk_per_plane;
682 	g_nand_phy_info.page_per_blk	= p_nand_info->page_per_blk;
683 	g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk;
684 	g_nand_phy_info.byte_per_sec	= SFC_NAND_SECTOR_SIZE;
685 	g_nand_phy_info.sec_per_page	= p_nand_info->sec_per_page;
686 	g_nand_phy_info.sec_per_blk	= p_nand_info->sec_per_page *
687 					  p_nand_info->page_per_blk;
688 	g_nand_phy_info.reserved_blk	= 8;
689 	g_nand_phy_info.blk_per_die	= p_nand_info->plane_per_die *
690 					  p_nand_info->blk_per_plane;
691 	g_nand_phy_info.ecc_bits	= p_nand_info->max_ecc_bits;
692 
693 	/* driver register */
694 	g_nand_ops.get_bad_blk_list	= sfc_nand_get_bad_block_list;
695 	g_nand_ops.erase_blk		= sfc_nand_erase_block;
696 	g_nand_ops.prog_page		= sfc_nand_prog_page;
697 	g_nand_ops.read_page		= sfc_nand_read_page;
698 	g_nand_ops.bch_sel		= NULL;
699 }
700 
701 static int sfc_nand_enable_QE(void)
702 {
703 	int ret = SFC_OK;
704 	u8 status;
705 	int bit_offset = p_nand_info->QE_bits;
706 
707 	if (bit_offset == 0xFF)
708 		return SFC_OK;
709 
710 	ret = sfc_nand_read_feature(p_nand_info->QE_address, &status);
711 	if (ret != SFC_OK)
712 		return ret;
713 
714 	if (status & (1 << bit_offset))   /* is QE bit set */
715 		return SFC_OK;
716 
717 	status |= (1 << bit_offset);
718 		return sfc_nand_write_feature(p_nand_info->QE_address, status);
719 
720 	return ret;
721 }
722 
723 u32 sfc_nand_init(void)
724 {
725 	u8 status, id_byte[8];
726 
727 	sfc_nand_read_id(id_byte);
728 	rkflash_print_error("sfc_nand id: %x %x %x\n",
729 			    id_byte[0], id_byte[1], id_byte[2]);
730 	if (id_byte[0] == 0xFF || id_byte[0] == 0x00)
731 		return FTL_NO_FLASH;
732 
733 	p_nand_info = sfc_nand_get_info(id_byte);
734 	if (!p_nand_info)
735 		return FTL_UNSUPPORTED_FLASH;
736 
737 	sfc_nand_dev.manufacturer = id_byte[0];
738 	sfc_nand_dev.mem_type = id_byte[1];
739 	sfc_nand_dev.capacity = p_nand_info->density;
740 	sfc_nand_dev.block_size = p_nand_info->page_per_blk * p_nand_info->sec_per_page;
741 	sfc_nand_dev.page_size = p_nand_info->sec_per_page;
742 
743 	/* disable block lock */
744 	sfc_nand_write_feature(0xA0, 0);
745 	sfc_nand_dev.read_lines = DATA_LINES_X1;
746 	sfc_nand_dev.prog_lines = DATA_LINES_X1;
747 	sfc_nand_dev.page_read_cmd = p_nand_info->read_cache_cmd_1;
748 	sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_1;
749 	if (p_nand_info->feature & FEA_4BIT_READ) {
750 		if (sfc_nand_enable_QE() == SFC_OK) {
751 			sfc_nand_dev.read_lines = DATA_LINES_X4;
752 			sfc_nand_dev.page_read_cmd =
753 				p_nand_info->read_cache_cmd_4;
754 		}
755 	}
756 
757 	if (p_nand_info->feature & FEA_4BIT_PROG &&
758 	    sfc_nand_dev.read_lines == DATA_LINES_X4) {
759 		sfc_nand_dev.prog_lines = DATA_LINES_X4;
760 		sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_4;
761 	}
762 
763 	sfc_nand_read_feature(0xA0, &status);
764 	rkflash_print_info("sfc_nand A0 = 0x%x\n", status);
765 	sfc_nand_read_feature(0xB0, &status);
766 	rkflash_print_info("sfc_nand B0 = 0x%x\n", status);
767 	rkflash_print_info("read_lines = %x\n", sfc_nand_dev.read_lines);
768 	rkflash_print_info("prog_lines = %x\n", sfc_nand_dev.prog_lines);
769 	rkflash_print_info("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd);
770 	rkflash_print_info("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd);
771 
772 	return SFC_OK;
773 }
774 
775 void sfc_nand_deinit(void)
776 {
777 	/* to-do */
778 }
779 
780 struct SFNAND_DEV *sfc_nand_get_private_dev(void)
781 {
782 	return &sfc_nand_dev;
783 }
784 
785