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