xref: /rk3399_rockchip-uboot/drivers/rkflash/sfc_nand.c (revision e7b5bb3cc9527752c2c01acb4325fc0721fb75aa)
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.h"
12 #include "flash_com.h"
13 #include "sfc.h"
14 #include "sfc_nand.h"
15 #include "rkflash_debug.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, 0xB0, 0XFF, 4, 8, NULL},
20 	/* TC58CVG1S0HxAIx */
21 	{0x98CB, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 19, 8, 0xB0, 0XFF, 4, 8, NULL},
22 	/* MX35LF1GE4AB */
23 	{0xC212, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, 4, 8, &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, &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, NULL},
28 	/* MT29F1G01ZAC */
29 	{0x2C12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0, 4, 8, &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, &sfc_nand_ecc_status_sp3},
32 	/* GD5F1GQ4U */
33 	{0xC8D1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp3},
34 	/* IS37SML01G1 */
35 	{0xC821, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0XFF, 8, 12, &sfc_nand_ecc_status_sp1},
36 	/* W25N01GV */
37 	{0xEFAA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xFF, 0XFF, 4, 20, &sfc_nand_ecc_status_sp1},
38 	/* HYF2GQ4UAACAE */
39 	{0xC952, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 14, 0xB0, 0, 4, 36, NULL},
40 	/* HYF2GQ4UDACAE */
41 	{0xC922, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0, 4, 20, NULL},
42 	/* HYF1GQ4UDACAE */
43 	{0xC921, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, 4, 20, NULL},
44 };
45 
46 static u8 id_byte[8];
47 static struct nand_info *p_nand_info;
48 static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4];
49 static struct SFNAND_DEV sfc_nand_dev;
50 
51 static struct nand_info *spi_nand_get_info(u8 *nand_id)
52 {
53 	u32 i;
54 	u32 id = (nand_id[0] << 8) | (nand_id[1] << 0);
55 
56 	for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) {
57 		if (spi_nand_tbl[i].id == id)
58 			return &spi_nand_tbl[i];
59 	}
60 	return NULL;
61 }
62 
63 static int sfc_nand_write_en(void)
64 {
65 	int ret;
66 	union SFCCMD_DATA sfcmd;
67 
68 	sfcmd.d32 = 0;
69 	sfcmd.b.cmd = CMD_WRITE_EN;
70 	ret = sfc_request(sfcmd.d32, 0, 0, NULL);
71 	return ret;
72 }
73 
74 static int sfc_nand_rw_preset(void)
75 {
76 	int ret;
77 	union SFCCTRL_DATA sfctrl;
78 	union SFCCMD_DATA sfcmd;
79 	u8 status = 0xFF;
80 
81 	sfcmd.d32 = 0;
82 	sfcmd.b.cmd = 0;
83 	sfcmd.b.datasize = 1;
84 	sfcmd.b.rw = SFC_WRITE;
85 
86 	sfctrl.b.datalines = 2;
87 	ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, &status);
88 	return ret;
89 }
90 
91 static int sfc_nand_read_feature(u8 addr, u8 *data)
92 {
93 	int ret;
94 	union SFCCMD_DATA sfcmd;
95 
96 	sfcmd.d32 = 0;
97 	sfcmd.b.cmd = 0x0F;
98 	sfcmd.b.datasize = 1;
99 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
100 	*data = 0;
101 
102 	ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, data);
103 	if (ret != SFC_OK)
104 		return ret;
105 	return SFC_OK;
106 }
107 
108 static int sfc_nand_write_feature(u32 addr, u8 status)
109 {
110 	int ret;
111 	union SFCCMD_DATA sfcmd;
112 
113 	sfc_nand_write_en();
114 
115 	sfcmd.d32 = 0;
116 	sfcmd.b.cmd = 0x1F;
117 	sfcmd.b.datasize = 1;
118 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
119 	sfcmd.b.rw = SFC_WRITE;
120 
121 	ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, &status);
122 	if (ret != SFC_OK)
123 		return ret;
124 	return ret;
125 }
126 
127 static int sfc_nand_wait_busy(u8 *data, int timeout)
128 {
129 	int ret;
130 	int i;
131 	u8 status;
132 
133 	*data = 0;
134 	for (i = 0; i < timeout; i++) {
135 		ret = sfc_nand_read_feature(0xC0, &status);
136 		if (ret != SFC_OK)
137 			return ret;
138 		*data = status;
139 		if (!(status & (1 << 0)))
140 			return SFC_OK;
141 		sfc_delay(1);
142 	}
143 	return -1;
144 }
145 
146 /*
147  * ecc default:
148  * 0, No bit errors were detected
149  * 1, Bit errors were detected and corrected.
150  * 2, Multiple bit errors were detected and not corrected.
151  * 3, Bits errors were detected and corrected, bit error count
152  *	exceed the bit flip detection threshold
153  */
154 static u32 sfc_nand_ecc_status(void)
155 {
156 	int ret;
157 	u32 i;
158 	u8 ecc;
159 	u8 status;
160 	u32 timeout = 1000 * 1000;
161 
162 	for (i = 0; i < timeout; i++) {
163 		ret = sfc_nand_read_feature(0xC0, &status);
164 		if (ret != SFC_OK)
165 			return SFC_NAND_ECC_ERROR;
166 		if (!(status & (1 << 0)))
167 			break;
168 		sfc_delay(1);
169 	}
170 
171 	ecc = (status >> 4) & 0x03;
172 
173 	if (ecc <= 1)
174 		ret = SFC_NAND_ECC_OK;
175 	else if (ecc == 2)
176 		ret = SFC_NAND_ECC_ERROR;
177 	else
178 		ret = SFC_NAND_ECC_REFRESH;
179 
180 	return ret;
181 }
182 
183 /*
184  * ecc spectial type1:
185  * 0x00, No bit errors were detected;
186  * 0x01, Bits errors were detected and corrected, bit error count
187  *	may reach the bit flip detection threshold;
188  * 0x10, Multiple bit errors were detected and not corrected;
189  * 0x11, Reserved.
190  */
191 u32 sfc_nand_ecc_status_sp1(void)
192 {
193 	int ret;
194 	u32 i;
195 	u8 ecc;
196 	u8 status;
197 	u32 timeout = 1000 * 1000;
198 
199 	for (i = 0; i < timeout; i++) {
200 		ret = sfc_nand_read_feature(0xC0, &status);
201 		if (ret != SFC_OK)
202 			return SFC_NAND_ECC_ERROR;
203 		if (!(status & (1 << 0)))
204 			break;
205 		sfc_delay(1);
206 	}
207 
208 	ecc = (status >> 4) & 0x03;
209 
210 	if (ecc == 0)
211 		ret = SFC_NAND_ECC_OK;
212 	else if (ecc == 1)
213 		ret = SFC_NAND_ECC_REFRESH;
214 	else
215 		ret = SFC_NAND_ECC_ERROR;
216 
217 	return ret;
218 }
219 
220 /*
221  * ecc spectial type3:
222  * [0x0000, 0x0011], No bit errors were detected;
223  * [0x0100, 0x0111], Bit errors were detected and corrected. Not
224  *	reach Flipping Bits;
225  * [0x1000, 0x1011], Multiple bit errors were detected and
226  *	not corrected.
227  * [0x1100, 0x1111], Bit error count equals the bit flip
228  *	detectionthreshold
229  */
230 u32 sfc_nand_ecc_status_sp3(void)
231 {
232 	int ret;
233 	u32 i;
234 	u8 ecc;
235 	u8 status, status1;
236 	u32 timeout = 1000 * 1000;
237 
238 	for (i = 0; i < timeout; i++) {
239 		ret = sfc_nand_read_feature(0xC0, &status);
240 		if (ret != SFC_OK)
241 			return SFC_NAND_ECC_ERROR;
242 		ret = sfc_nand_read_feature(0xF0, &status1);
243 		if (ret != SFC_OK)
244 			return SFC_NAND_ECC_ERROR;
245 		if (!(status & (1 << 0)))
246 			break;
247 		sfc_delay(1);
248 	}
249 
250 	ecc = (status >> 4) & 0x03;
251 	ecc = (ecc << 2) | ((status1 >> 4) & 0x03);
252 	if (ecc < 7)
253 		ret = SFC_NAND_ECC_OK;
254 	else if (ecc == 7 || ecc >= 12)
255 		ret = SFC_NAND_ECC_REFRESH;
256 	else
257 		ret = SFC_NAND_ECC_ERROR;
258 
259 	return ret;
260 }
261 
262 static u32 sfc_nand_erase_block(u8 cs, u32 addr)
263 {
264 	int ret;
265 	union SFCCMD_DATA sfcmd;
266 	u8 status;
267 
268 	sfcmd.d32 = 0;
269 	sfcmd.b.cmd = p_nand_info->block_erase_cmd;
270 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
271 	sfc_nand_write_en();
272 	ret = sfc_request(sfcmd.d32, 0, addr, NULL);
273 	if (ret != SFC_OK)
274 		return ret;
275 	ret = sfc_nand_wait_busy(&status, 1000 * 1000);
276 	if (status & (1 << 2))
277 		return SFC_NAND_PROG_ERASE_ERROR;
278 	return ret;
279 }
280 
281 static u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
282 {
283 	int ret;
284 	union SFCCMD_DATA sfcmd;
285 	union SFCCTRL_DATA sfctrl;
286 	u8 status;
287 	u32 data_sz = 2048;
288 	u32 spare_offs_1 = p_nand_info->spare_offs_1;
289 	u32 spare_offs_2 = p_nand_info->spare_offs_2;
290 
291 	memcpy(gp_page_buf, p_data, data_sz);
292 	gp_page_buf[(data_sz + spare_offs_1) / 4] = p_spare[0];
293 	gp_page_buf[(data_sz + spare_offs_2) / 4] = p_spare[1];
294 
295 	sfc_nand_write_en();
296 	if (sfc_nand_dev.prog_lines == DATA_LINES_X4 &&
297 	    p_nand_info->QE_address == 0xFF &&
298 	    sfc_get_version() != SFC_VER_3)
299 		sfc_nand_rw_preset();
300 
301 	sfcmd.d32 = 0;
302 	sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd;
303 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
304 	sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE;
305 	sfcmd.b.rw = SFC_WRITE;
306 
307 	sfctrl.d32 = 0;
308 	sfctrl.b.datalines = sfc_nand_dev.prog_lines;
309 	sfctrl.b.addrbits = 16;
310 	sfc_request(sfcmd.d32, sfctrl.d32, 0, gp_page_buf);
311 
312 	sfcmd.d32 = 0;
313 	sfcmd.b.cmd = p_nand_info->page_prog_cmd;
314 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
315 	sfcmd.b.datasize = 0;
316 	sfcmd.b.rw = SFC_WRITE;
317 	ret = sfc_request(sfcmd.d32, 0, addr, p_data);
318 	if (ret != SFC_OK)
319 		return ret;
320 	ret = sfc_nand_wait_busy(&status, 1000 * 1000);
321 	if (status & (1 << 3))
322 		return SFC_NAND_PROG_ERASE_ERROR;
323 	return ret;
324 }
325 
326 static u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
327 {
328 	int ret;
329 	union SFCCMD_DATA sfcmd;
330 	union SFCCTRL_DATA sfctrl;
331 	u32 ecc_result;
332 	u32 data_sz = 2048;
333 	u32 spare_offs_1 = p_nand_info->spare_offs_1;
334 	u32 spare_offs_2 = p_nand_info->spare_offs_2;
335 
336 	sfcmd.d32 = 0;
337 	sfcmd.b.cmd = p_nand_info->page_read_cmd;
338 	sfcmd.b.datasize = 0;
339 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
340 	sfc_request(sfcmd.d32, 0, addr, p_data);
341 
342 	if (p_nand_info->ecc_status)
343 		ecc_result = p_nand_info->ecc_status();
344 	else
345 		ecc_result = sfc_nand_ecc_status();
346 
347 	if (sfc_nand_dev.read_lines == DATA_LINES_X4 &&
348 	    p_nand_info->QE_address == 0xFF &&
349 	    sfc_get_version() != SFC_VER_3)
350 		sfc_nand_rw_preset();
351 
352 	sfcmd.d32 = 0;
353 	sfcmd.b.cmd = sfc_nand_dev.page_read_cmd;
354 	sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE;
355 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
356 	sfctrl.d32 = 0;
357 	sfctrl.b.datalines = sfc_nand_dev.read_lines;
358 
359 	memset(gp_page_buf, 0, SFC_NAND_PAGE_MAX_SIZE);
360 	ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, gp_page_buf);
361 
362 	memcpy(p_data, gp_page_buf, data_sz);
363 	p_spare[0] = gp_page_buf[(data_sz + spare_offs_1) / 4];
364 	p_spare[1] = gp_page_buf[(data_sz + spare_offs_2) / 4];
365 	if (ret != SFC_OK)
366 		return SFC_NAND_ECC_ERROR;
367 
368 	if (ecc_result != SFC_NAND_ECC_OK) {
369 		PRINT_SFC_E("%s[0x%x], ret=0x%x\n", __func__, addr, ecc_result);
370 		if (p_data)
371 			PRINT_SFC_HEX("data:", p_data, 4, 8);
372 		if (p_spare)
373 			PRINT_SFC_HEX("spare:", p_spare, 4, 2);
374 	}
375 	return ecc_result;
376 }
377 
378 static int sfc_nand_read_id_raw(u8 *data)
379 {
380 	int ret;
381 	union SFCCMD_DATA sfcmd;
382 
383 	sfcmd.d32 = 0;
384 	sfcmd.b.cmd = CMD_READ_JEDECID;
385 	sfcmd.b.datasize = 3;
386 	sfcmd.b.addrbits = SFC_ADDR_XBITS;
387 
388 	ret = sfc_request(sfcmd.d32, 0x8 << 16, 0, data);
389 
390 	return ret;
391 }
392 
393 /*
394  * Read the 1st page's 1st byte of a phy_blk
395  * If not FF, it's bad blk
396  */
397 static int sfc_nand_get_bad_block_list(u16 *table, u32 die)
398 {
399 	u16 blk;
400 	u32 bad_cnt, page;
401 	u32 blk_per_die;
402 	u32 *pread;
403 	u32 *pspare_read;
404 
405 	PRINT_SFC_E("%s\n", __func__);
406 	pread = ftl_malloc(2048);
407 	pspare_read = ftl_malloc(8);
408 	bad_cnt = 0;
409 	blk_per_die = p_nand_info->plane_per_die *
410 			p_nand_info->blk_per_plane;
411 	for (blk = 0; blk < blk_per_die; blk++) {
412 		page = (blk + blk_per_die * die) *
413 			p_nand_info->page_per_blk;
414 		sfc_nand_read_page(0, page, pread, pspare_read);
415 
416 		if (pread[0] != 0xFFFFFFFF ||
417 		    pspare_read[0] != 0xFFFFFFFF) {
418 			table[bad_cnt++] = blk;
419 			PRINT_SFC_E("die[%d], bad_blk[%d]\n", die, blk);
420 		}
421 	}
422 	ftl_free(pread);
423 	ftl_free(pspare_read);
424 	return (int)bad_cnt;
425 }
426 
427 #if SFC_NAND_STRESS_TEST_EN
428 
429 #define SFC_NAND_PAGE_SIZE	2048
430 #define SFC_NAND_SPARE_SIZE	8
431 
432 static u16 bad_blk_list[1024];
433 static u32 pwrite[SFC_NAND_PAGE_SIZE / 4];
434 static u32 pread[SFC_NAND_PAGE_SIZE / 4];
435 static u32 pspare_write[SFC_NAND_SPARE_SIZE / 4];
436 static u32 pspare_read[SFC_NAND_SPARE_SIZE / 4];
437 static u32 bad_blk_num;
438 static u32 bad_page_num;
439 
440 static void sfc_nand_test(void)
441 {
442 	u32 i, blk, page, bad_cnt, page_addr;
443 	int ret;
444 	u32 pages_num = 64;
445 	u32 blk_addr = 64;
446 	u32 is_bad_blk = 0;
447 
448 	PRINT_SFC_E("%s\n", __func__);
449 
450 	bad_blk_num = 0;
451 	bad_page_num = 0;
452 	bad_cnt	= sfc_nand_get_bad_block_list(bad_blk_list, 0);
453 
454 	for (blk = 0; blk < 1024; blk++) {
455 		for (i = 0; i < bad_cnt; i++) {
456 			if (bad_blk_list[i] == blk)
457 				break;
458 		}
459 		if (i < bad_cnt)
460 			continue;
461 		is_bad_blk = 0;
462 		PRINT_SFC_E("Flash prog block: %x\n", blk);
463 		sfc_nand_erase_block(0, blk * blk_addr);
464 		for (page = 0; page < pages_num; page++) {
465 			page_addr = blk * blk_addr + page;
466 			for (i = 0; i < 512; i++)
467 				pwrite[i] = (page_addr << 16) + i;
468 			pspare_write[0] = pwrite[0] + 0x5AF0;
469 			pspare_write[1] = pspare_write[0] + 1;
470 			sfc_nand_prog_page(0, page_addr, pwrite, pspare_write);
471 			memset(pread, 0, 2048);
472 			memset(pspare_read, 0, 8);
473 			ret = sfc_nand_read_page(0, page_addr, pread,
474 						 pspare_read);
475 			if (ret != SFC_NAND_ECC_OK)
476 				is_bad_blk = 1;
477 			for (i = 0; i < 512; i++) {
478 				if (pwrite[i] != pread[i]) {
479 					is_bad_blk = 1;
480 					break;
481 				}
482 			}
483 			for (i = 0; i < 2; i++) {
484 				if (pspare_write[i] != pspare_read[i]) {
485 					is_bad_blk = 1;
486 					break;
487 				}
488 			}
489 			if (is_bad_blk) {
490 				bad_page_num++;
491 				PRINT_SFC_E("ERR:page%x, ret=%x\n",
492 					    page_addr, ret);
493 				PRINT_SFC_HEX("data:", pread, 4, 8);
494 				PRINT_SFC_HEX("spare:", pspare_read, 4, 2);
495 			}
496 		}
497 		sfc_nand_erase_block(0, blk * blk_addr);
498 		if (is_bad_blk)
499 			bad_blk_num++;
500 	}
501 	PRINT_SFC_E("bad_blk_num = %d, bad_page_num = %d\n",
502 		    bad_blk_num, bad_page_num);
503 
504 	PRINT_SFC_E("Flash Test Finish!!!\n");
505 	while (1)
506 		;
507 }
508 #endif
509 
510 static void ftl_flash_init(void)
511 {
512 	/* para init */
513 	g_nand_phy_info.nand_type	= 1;
514 	g_nand_phy_info.die_num		= 1;
515 	g_nand_phy_info.plane_per_die	= p_nand_info->plane_per_die;
516 	g_nand_phy_info.blk_per_plane	= p_nand_info->blk_per_plane;
517 	g_nand_phy_info.page_per_blk	= p_nand_info->page_per_blk;
518 	g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk;
519 	g_nand_phy_info.byte_per_sec	= 512;
520 	g_nand_phy_info.sec_per_page	= p_nand_info->sec_per_page;
521 	g_nand_phy_info.sec_per_blk	= p_nand_info->sec_per_page *
522 					  p_nand_info->page_per_blk;
523 	g_nand_phy_info.reserved_blk	= 8;
524 	g_nand_phy_info.blk_per_die	= p_nand_info->plane_per_die *
525 					  p_nand_info->blk_per_plane;
526 	g_nand_phy_info.ecc_bits	= p_nand_info->max_ecc_bits;
527 
528 	/* driver register */
529 	g_nand_ops.get_bad_blk_list	= sfc_nand_get_bad_block_list;
530 	g_nand_ops.erase_blk		= sfc_nand_erase_block;
531 	g_nand_ops.prog_page		= sfc_nand_prog_page;
532 	g_nand_ops.read_page		= sfc_nand_read_page;
533 }
534 
535 static int spi_nand_enable_QE(void)
536 {
537 	int ret = SFC_OK;
538 	u8 status;
539 	int bit_offset = p_nand_info->QE_bits;
540 
541 	if (bit_offset == 0xFF)
542 		return SFC_OK;
543 
544 	ret = sfc_nand_read_feature(p_nand_info->QE_address, &status);
545 	if (ret != SFC_OK)
546 		return ret;
547 
548 	if (status & (1 << bit_offset))   /* is QE bit set */
549 		return SFC_OK;
550 
551 	status |= (1 << bit_offset);
552 		return sfc_nand_write_feature(p_nand_info->QE_address, status);
553 
554 	return ret;
555 }
556 
557 u32 sfc_nand_init(void)
558 {
559 	PRINT_SFC_I("...%s enter...\n", __func__);
560 
561 	sfc_nand_read_id_raw(id_byte);
562 	PRINT_SFC_E("sfc_nand id: %x %x %x\n",
563 		    id_byte[0], id_byte[1], id_byte[2]);
564 	if (id_byte[0] == 0xFF || id_byte[0] == 0x00)
565 		return FTL_NO_FLASH;
566 
567 	p_nand_info = spi_nand_get_info(id_byte);
568 	if (!p_nand_info)
569 		return FTL_UNSUPPORTED_FLASH;
570 
571 	sfc_nand_dev.manufacturer = id_byte[0];
572 	sfc_nand_dev.mem_type = id_byte[1];
573 
574 	/* disable block lock */
575 	sfc_nand_write_feature(0xA0, 0);
576 	sfc_nand_dev.read_lines = DATA_LINES_X1;
577 	sfc_nand_dev.prog_lines = DATA_LINES_X1;
578 	sfc_nand_dev.page_read_cmd = p_nand_info->read_cache_cmd_1;
579 	sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_1;
580 	if (p_nand_info->feature & FEA_4BIT_READ) {
581 		if (spi_nand_enable_QE() == SFC_OK) {
582 			sfc_nand_dev.read_lines = DATA_LINES_X4;
583 			sfc_nand_dev.page_read_cmd =
584 				p_nand_info->read_cache_cmd_4;
585 		}
586 	}
587 
588 	if (p_nand_info->feature & FEA_4BIT_PROG &&
589 	    sfc_nand_dev.read_lines == DATA_LINES_X4) {
590 		sfc_nand_dev.prog_lines = DATA_LINES_X4;
591 		sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_4;
592 	}
593 
594 	if (1) {
595 		u8 status;
596 
597 		sfc_nand_read_feature(0xA0, &status);
598 		PRINT_SFC_I("sfc_nand A0 = 0x%x\n", status);
599 		sfc_nand_read_feature(0xB0, &status);
600 		PRINT_SFC_I("sfc_nand B0 = 0x%x\n", status);
601 		sfc_nand_read_feature(0xC0, &status);
602 		PRINT_SFC_I("sfc_nand C0 = 0x%x\n", status);
603 		PRINT_SFC_I("read_lines = %x\n", sfc_nand_dev.read_lines);
604 		PRINT_SFC_I("prog_lines = %x\n", sfc_nand_dev.prog_lines);
605 		PRINT_SFC_I("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd);
606 		PRINT_SFC_I("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd);
607 	}
608 	ftl_flash_init();
609 
610 	#if SFC_NAND_STRESS_TEST_EN
611 	sfc_nand_test();
612 	#endif
613 
614 	return SFC_OK;
615 }
616 
617 int sfc_nand_read_id(u8 *data)
618 {
619 	memcpy(data, id_byte, 3);
620 	return 0;
621 }
622