xref: /rk3399_rockchip-uboot/drivers/rkflash/sfc_nor.c (revision 008ec9b4bc06f98dd7efdc7d2f44eb066be036e6)
1 /*
2  * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0
5  */
6 #include <linux/compat.h>
7 #include <linux/delay.h>
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10 
11 #include "rkflash_debug.h"
12 #include "sfc_nor.h"
13 
14 static struct flash_info spi_flash_tbl[] = {
15 	/* GD25Q32B */
16 	{ 0xc84016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 13, 9, 0 },
17 	/* GD25Q64B */
18 	{ 0xc84017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 },
19 	/* GD25Q127C and GD25Q128C*/
20 	{ 0xc84018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 },
21 	/* GD25Q256B/C/D */
22 	{ 0xc84019, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x3C, 16, 6, 0 },
23 	/* GD25Q512MC */
24 	{ 0xc84020, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x3C, 17, 6, 0 },
25 	/* 25Q64JVSSIQ */
26 	{ 0xef4017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 },
27 	/* 25Q128FV and 25Q128JV*/
28 	{ 0xef4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 },
29 	/* 25Q256F/J */
30 	{ 0xef4019, 128, 8, 0x13, 0x02, 0x6C, 0x32, 0x20, 0xD8, 0x3C, 16, 9, 0 },
31 	/* 25Q64FWSSIG */
32 	{ 0xef6017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 },
33 	/* MX25L6433F */
34 	{ 0xc22017, 128, 8, 0x03, 0x02, 0x6B, 0x38, 0x20, 0xD8, 0x0E, 14, 6, 0 },
35 	/* MX25L12835E/F MX25L12833FMI-10G */
36 	{ 0xc22018, 128, 8, 0x03, 0x02, 0x6B, 0x38, 0x20, 0xD8, 0x0E, 15, 6, 0 },
37 	/* MX25L25635E/F MX25L25645G MX25L25645GMI-08G*/
38 	{ 0xc22019, 128, 8, 0x13, 0x12, 0x6C, 0x38, 0x21, 0xDC, 0x3E, 16, 6, 0 },
39 	/* MX25L51245GMI */
40 	{ 0xc2201a, 128, 8, 0x13, 0x12, 0x6C, 0x38, 0x21, 0xDC, 0x3E, 17, 6, 0 },
41 	/* XM25QH32C */
42 	{ 0x204016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 9, 0 },
43 	/* XM25QH64B */
44 	{ 0x206017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 6, 0 },
45 	/* XM25QH128B */
46 	{ 0x206018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 15, 6, 0 },
47 	/* XM25QH(QU)256B */
48 	{ 0x206019, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1D, 16, 6, 0 },
49 	/* XM25QH64A */
50 	{ 0x207017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 0, 0 },
51 	/* XT25F128A XM25QH128A */
52 	{ 0x207018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x00, 15, 0, 0 },
53 	/* XT25F64BSSIGU-5 */
54 	{ 0x0b4017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 },
55 	/* XT25F128BSSIGU */
56 	{ 0x0b4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 15, 9, 0 },
57 	/* EN25QH64A */
58 	{ 0x1c7017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 0, 0 },
59 	/* EN25QH128A */
60 	{ 0x1c7018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 0, 0 },
61 	/* EN25QH32B */
62 	{ 0x1c7016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 0, 0 },
63 	/* EN25S32A */
64 	{ 0x1c3816, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 0, 0 },
65 	/* EN25S64A */
66 	{ 0x1c3817, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 0, 0 },
67 	/* P25Q64H */
68 	{ 0x856017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 },
69 	/* EN25QH256A */
70 	{ 0x1c7019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x3C, 16, 0, 0 },
71 	/* FM25Q64A */
72 	{ 0xf83217, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 },
73 	/* ZB25VQ64 */
74 	{ 0x5e4017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 },
75 	/* ZB25VQ128 */
76 	{ 0x5e4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 },
77 	/* 25Q256JVEM */
78 	{ 0xef7019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x3C, 16, 9, 0 },
79 	/* BH25Q128AS */
80 	{ 0x684018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x04, 15, 9, 0 },
81 	/* BH25Q64BS */
82 	{ 0x684017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x04, 14, 9, 0 },
83 };
84 
85 static int snor_write_en(void)
86 {
87 	int ret;
88 	union SFCCMD_DATA     sfcmd;
89 
90 	sfcmd.d32 = 0;
91 	sfcmd.b.cmd = CMD_WRITE_EN;
92 
93 	ret = sfc_request(sfcmd.d32, 0, 0, NULL);
94 
95 	return ret;
96 }
97 
98 int snor_reset_device(void)
99 {
100 	int ret;
101 	union SFCCMD_DATA sfcmd;
102 
103 	sfcmd.d32 = 0;
104 	sfcmd.b.cmd = CMD_ENABLE_RESER;
105 	sfc_request(sfcmd.d32, 0, 0, NULL);
106 
107 	sfcmd.d32 = 0;
108 	sfcmd.b.cmd = CMD_RESET_DEVICE;
109 	ret = sfc_request(sfcmd.d32, 0, 0, NULL);
110 	/* tRST=30us , delay 1ms here */
111 	mdelay(1);
112 	return ret;
113 }
114 
115 static int snor_enter_4byte_mode(void)
116 {
117 	int ret;
118 	union SFCCMD_DATA sfcmd;
119 
120 	sfcmd.d32 = 0;
121 	sfcmd.b.cmd = CMD_ENTER_4BYTE_MODE;
122 
123 	ret = sfc_request(sfcmd.d32, 0, 0, NULL);
124 	return ret;
125 }
126 
127 static int snor_read_status(u32 reg_index, u8 *status)
128 {
129 	int ret;
130 	union SFCCMD_DATA sfcmd;
131 	u8 read_stat_cmd[] = {CMD_READ_STATUS,
132 				CMD_READ_STATUS2, CMD_READ_STATUS3};
133 	sfcmd.d32 = 0;
134 	sfcmd.b.cmd = read_stat_cmd[reg_index];
135 	sfcmd.b.datasize = 1;
136 
137 	ret = sfc_request(sfcmd.d32, 0, 0, status);
138 
139 	return ret;
140 }
141 
142 static int snor_wait_busy(int timeout)
143 {
144 	int ret;
145 	union SFCCMD_DATA sfcmd;
146 	int i;
147 	u32 status;
148 
149 	sfcmd.d32 = 0;
150 	sfcmd.b.cmd = CMD_READ_STATUS;
151 	sfcmd.b.datasize = 1;
152 
153 	for (i = 0; i < timeout; i++) {
154 		ret = sfc_request(sfcmd.d32, 0, 0, &status);
155 		if (ret != SFC_OK)
156 			return ret;
157 
158 		if ((status & 0x01) == 0)
159 			return SFC_OK;
160 
161 		sfc_delay(1);
162 	}
163 	rkflash_print_error("%s  error %x\n", __func__, timeout);
164 
165 	return SFC_BUSY_TIMEOUT;
166 }
167 
168 static int snor_write_status2(u32 reg_index, u8 status)
169 {
170 	int ret;
171 	union SFCCMD_DATA sfcmd;
172 	u8 status2[2];
173 	u8 read_index;
174 
175 	status2[reg_index] = status;
176 	read_index = (reg_index == 0) ? 2 : 0;
177 	ret = snor_read_status(read_index, &status2[read_index]);
178 	if (ret != SFC_OK)
179 		return ret;
180 
181 	snor_write_en();
182 
183 	sfcmd.d32 = 0;
184 	sfcmd.b.cmd = CMD_WRITE_STATUS;
185 	sfcmd.b.datasize = 2;
186 	sfcmd.b.rw = SFC_WRITE;
187 
188 	ret = sfc_request(sfcmd.d32, 0, 0, &status2[0]);
189 	if (ret != SFC_OK)
190 		return ret;
191 
192 	ret = snor_wait_busy(10000);    /* 10ms */
193 
194 	return ret;
195 }
196 
197 static int snor_write_status1(u32 reg_index, u8 status)
198 {
199 	int ret;
200 	union SFCCMD_DATA sfcmd;
201 	u8 status2[2];
202 	u8 read_index;
203 
204 	status2[reg_index] = status;
205 	read_index = (reg_index == 0) ? 1 : 0;
206 	ret = snor_read_status(read_index, &status2[read_index]);
207 	if (ret != SFC_OK)
208 		return ret;
209 
210 	snor_write_en();
211 
212 	sfcmd.d32 = 0;
213 	sfcmd.b.cmd = CMD_WRITE_STATUS;
214 	sfcmd.b.datasize = 2;
215 	sfcmd.b.rw = SFC_WRITE;
216 
217 	ret = sfc_request(sfcmd.d32, 0, 0, &status2[0]);
218 	if (ret != SFC_OK)
219 		return ret;
220 
221 	ret = snor_wait_busy(10000);    /* 10ms */
222 
223 	return ret;
224 }
225 
226 static int snor_write_status(u32 reg_index, u8 status)
227 {
228 	int ret;
229 	union SFCCMD_DATA sfcmd;
230 	u8 write_stat_cmd[] = {CMD_WRITE_STATUS,
231 			       CMD_WRITE_STATUS2, CMD_WRITE_STATUS3};
232 	snor_write_en();
233 	sfcmd.d32 = 0;
234 	sfcmd.b.cmd = write_stat_cmd[reg_index];
235 	sfcmd.b.datasize = 1;
236 	sfcmd.b.rw = SFC_WRITE;
237 
238 	ret = sfc_request(sfcmd.d32, 0, 0, &status);
239 	if (ret != SFC_OK)
240 		return ret;
241 
242 	ret = snor_wait_busy(10000);    /* 10ms */
243 
244 	return ret;
245 }
246 
247 int snor_erase(struct SFNOR_DEV *p_dev,
248 	       u32 addr,
249 	       enum NOR_ERASE_TYPE erase_type)
250 {
251 	int ret;
252 	union SFCCMD_DATA sfcmd;
253 	int timeout[] = {400, 2000, 40000};   /* ms */
254 
255 	rkflash_print_dio("%s %x\n", __func__, addr);
256 
257 	if (erase_type > ERASE_CHIP)
258 		return SFC_PARAM_ERR;
259 
260 	sfcmd.d32 = 0;
261 	if (erase_type == ERASE_BLOCK64K)
262 		sfcmd.b.cmd = p_dev->blk_erase_cmd;
263 	else if (erase_type == ERASE_SECTOR)
264 		sfcmd.b.cmd = p_dev->sec_erase_cmd;
265 	else
266 		sfcmd.b.cmd = CMD_CHIP_ERASE;
267 
268 	sfcmd.b.addrbits = (erase_type != ERASE_CHIP) ?
269 				SFC_ADDR_24BITS : SFC_ADDR_0BITS;
270 	if (p_dev->addr_mode == ADDR_MODE_4BYTE && erase_type != ERASE_CHIP)
271 		sfcmd.b.addrbits = SFC_ADDR_32BITS;
272 
273 	snor_write_en();
274 
275 	ret = sfc_request(sfcmd.d32, 0, addr, NULL);
276 	if (ret != SFC_OK)
277 		return ret;
278 
279 	ret = snor_wait_busy(timeout[erase_type] * 1000);
280 	return ret;
281 }
282 
283 int snor_prog_page(struct SFNOR_DEV *p_dev,
284 		   u32 addr,
285 		   void *p_data,
286 		   u32 size)
287 {
288 	int ret;
289 	union SFCCMD_DATA sfcmd;
290 	union SFCCTRL_DATA sfctrl;
291 
292 	rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data));
293 
294 	sfcmd.d32 = 0;
295 	sfcmd.b.cmd = p_dev->prog_cmd;
296 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
297 	sfcmd.b.datasize = size;
298 	sfcmd.b.rw = SFC_WRITE;
299 
300 	sfctrl.d32 = 0;
301 	sfctrl.b.datalines = p_dev->prog_lines;
302 	sfctrl.b.enbledma = 0;
303 	if (p_dev->prog_cmd == CMD_PAGE_PROG_A4)
304 		sfctrl.b.addrlines = SFC_4BITS_LINE;
305 
306 	if (p_dev->addr_mode == ADDR_MODE_4BYTE)
307 		sfcmd.b.addrbits = SFC_ADDR_32BITS;
308 
309 	snor_write_en();
310 
311 	ret = sfc_request(sfcmd.d32, sfctrl.d32, addr, p_data);
312 	if (ret != SFC_OK)
313 		return ret;
314 
315 	ret = snor_wait_busy(10000);
316 
317 	return ret;
318 }
319 
320 static int snor_prog(struct SFNOR_DEV *p_dev, u32 addr, void *p_data, u32 size)
321 {
322 	int ret = SFC_OK;
323 	u32 page_size, len;
324 	u8 *p_buf =  (u8 *)p_data;
325 
326 	page_size = NOR_PAGE_SIZE;
327 	while (size) {
328 		len = page_size < size ? page_size : size;
329 		ret = snor_prog_page(p_dev, addr, p_buf, len);
330 		if (ret != SFC_OK)
331 			return ret;
332 
333 		size -= len;
334 		addr += len;
335 		p_buf += len;
336 	}
337 
338 	return ret;
339 }
340 
341 static int snor_enable_QE(struct SFNOR_DEV *p_dev)
342 {
343 	int ret = SFC_OK;
344 	int reg_index;
345 	int bit_offset;
346 	u8 status;
347 
348 	reg_index = p_dev->QE_bits >> 3;
349 	bit_offset = p_dev->QE_bits & 0x7;
350 	ret = snor_read_status(reg_index, &status);
351 	if (ret != SFC_OK)
352 		return ret;
353 
354 	if (status & (1 << bit_offset))   /* is QE bit set */
355 		return SFC_OK;
356 
357 	status |= (1 << bit_offset);
358 
359 	return p_dev->write_status(reg_index, status);
360 }
361 
362 int snor_disable_QE(struct SFNOR_DEV *p_dev)
363 {
364 	int ret = SFC_OK;
365 	int reg_index;
366 	int bit_offset;
367 	u8 status;
368 
369 	reg_index = p_dev->QE_bits >> 3;
370 	bit_offset = p_dev->QE_bits & 0x7;
371 	ret = snor_read_status(reg_index, &status);
372 	if (ret != SFC_OK)
373 		return ret;
374 
375 	if (!(status & (1 << bit_offset)))
376 		return SFC_OK;
377 
378 	status &= ~(1 << bit_offset);
379 
380 	return p_dev->write_status(reg_index, status);
381 }
382 
383 int snor_read_data(struct SFNOR_DEV *p_dev,
384 		   u32 addr,
385 		   void *p_data,
386 		   u32 size)
387 {
388 	int ret;
389 	union SFCCMD_DATA sfcmd;
390 	union SFCCTRL_DATA sfctrl;
391 
392 	sfcmd.d32 = 0;
393 	sfcmd.b.cmd = p_dev->read_cmd;
394 	sfcmd.b.datasize = size;
395 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
396 
397 	sfctrl.d32 = 0;
398 	sfctrl.b.datalines = p_dev->read_lines;
399 	if (!(size & 0x3) && size >= 4)
400 		sfctrl.b.enbledma = 0;
401 
402 	if (p_dev->read_cmd == CMD_FAST_READ_X1 ||
403 	    p_dev->read_cmd == CMD_FAST_READ_X4 ||
404 	    p_dev->read_cmd == CMD_FAST_READ_X2 ||
405 	    p_dev->read_cmd == CMD_FAST_4READ_X4) {
406 		sfcmd.b.dummybits = 8;
407 	} else if (p_dev->read_cmd == CMD_FAST_READ_A4) {
408 		sfcmd.b.addrbits = SFC_ADDR_32BITS;
409 		addr = (addr << 8) | 0xFF;	/* Set M[7:0] = 0xFF */
410 		sfcmd.b.dummybits = 4;
411 		sfctrl.b.addrlines = SFC_4BITS_LINE;
412 	}
413 
414 	if (p_dev->addr_mode == ADDR_MODE_4BYTE)
415 		sfcmd.b.addrbits = SFC_ADDR_32BITS;
416 
417 	ret = sfc_request(sfcmd.d32, sfctrl.d32, addr, p_data);
418 	rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data));
419 
420 	return ret;
421 }
422 
423 int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data)
424 {
425 	int ret = SFC_OK;
426 	u32 addr, size, len;
427 	u8 *p_buf =  (u8 *)p_data;
428 
429 	rkflash_print_dio("%s %x %x\n", __func__, sec, n_sec);
430 
431 	if ((sec + n_sec) > p_dev->capacity)
432 		return SFC_PARAM_ERR;
433 
434 	addr = sec << 9;
435 	size = n_sec << 9;
436 	while (size) {
437 		len = size < SFC_MAX_IOSIZE ? size : SFC_MAX_IOSIZE;
438 		ret = snor_read_data(p_dev, addr, p_buf, len);
439 		if (ret != SFC_OK) {
440 			rkflash_print_error("snor_read_data %x ret= %x\n",
441 					    addr >> 9, ret);
442 			goto out;
443 		}
444 
445 		size -= len;
446 		addr += len;
447 		p_buf += len;
448 	}
449 out:
450 	if (!ret)
451 		ret = n_sec;
452 
453 	return ret;
454 }
455 
456 int snor_write(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data)
457 {
458 	int ret = SFC_OK;
459 	u32 len, blk_size, offset;
460 	u8 *p_buf =  (u8 *)p_data;
461 	u32 total_sec = n_sec;
462 
463 	rkflash_print_dio("%s %x %x\n", __func__, sec, n_sec);
464 
465 	if ((sec + n_sec) > p_dev->capacity)
466 		return SFC_PARAM_ERR;
467 
468 	while (n_sec) {
469 		if (sec < 512 || sec >= p_dev->capacity  - 512)
470 			blk_size = 8;
471 		else
472 			blk_size = p_dev->blk_size;
473 
474 		offset = (sec & (blk_size - 1));
475 		if (!offset) {
476 			ret = snor_erase(p_dev, sec << 9, (blk_size == 8) ?
477 				ERASE_SECTOR : ERASE_BLOCK64K);
478 			if (ret != SFC_OK) {
479 				rkflash_print_error("snor_erase %x ret= %x\n",
480 						    sec, ret);
481 				goto out;
482 			}
483 		}
484 		len = (blk_size - offset) < n_sec ?
485 		      (blk_size - offset) : n_sec;
486 		ret = snor_prog(p_dev, sec << 9, p_buf, len << 9);
487 		if (ret != SFC_OK) {
488 			rkflash_print_error("snor_prog %x ret= %x\n", sec, ret);
489 			goto out;
490 		}
491 		n_sec -= len;
492 		sec += len;
493 		p_buf += len << 9;
494 	}
495 out:
496 	if (!ret)
497 		ret = total_sec;
498 
499 	return ret;
500 }
501 
502 int snor_read_id(u8 *data)
503 {
504 	int ret;
505 	union SFCCMD_DATA     sfcmd;
506 
507 	sfcmd.d32 = 0;
508 	sfcmd.b.cmd = CMD_READ_JEDECID;
509 	sfcmd.b.datasize = 3;
510 
511 	ret = sfc_request(sfcmd.d32, 0, 0, data);
512 
513 	return ret;
514 }
515 
516 static int snor_read_parameter(u32 addr, u8 *data)
517 {
518 	int ret;
519 	union SFCCMD_DATA     sfcmd;
520 
521 	sfcmd.d32 = 0;
522 	sfcmd.b.cmd = CMD_READ_PARAMETER;
523 	sfcmd.b.datasize = 1;
524 	sfcmd.b.addrbits = SFC_ADDR_24BITS;
525 	sfcmd.b.dummybits = 8;
526 
527 	ret = sfc_request(sfcmd.d32, 0, addr, data);
528 
529 	return ret;
530 }
531 
532 u32 snor_get_capacity(struct SFNOR_DEV *p_dev)
533 {
534 	return p_dev->capacity;
535 }
536 
537 static struct flash_info *snor_get_flash_info(u8 *flash_id)
538 {
539 	u32 i;
540 	u32 id = (flash_id[0] << 16) | (flash_id[1] << 8) | (flash_id[2] << 0);
541 
542 	for (i = 0; i < ARRAY_SIZE(spi_flash_tbl); i++) {
543 		if (spi_flash_tbl[i].id == id)
544 			return &spi_flash_tbl[i];
545 	}
546 	return NULL;
547 }
548 
549 /* Adjust flash info in ram base on parameter */
550 static void *snor_flash_info_adjust(struct flash_info *spi_flash_info)
551 {
552 	u32 addr;
553 	u8 para_version;
554 
555 	if (spi_flash_info->id == 0xc84019) {
556 		addr = 0x09;
557 		snor_read_parameter(addr, &para_version);
558 		if (para_version == 0x06) {
559 			spi_flash_info->QE_bits = 9;
560 			spi_flash_info->prog_cmd_4 = 0x34;
561 		}
562 	}
563 	return 0;
564 }
565 
566 int snor_init(struct SFNOR_DEV *p_dev)
567 {
568 	struct flash_info *g_spi_flash_info;
569 	u32 i, ret;
570 	u8 id_byte[5];
571 
572 	if (!p_dev)
573 		return SFC_PARAM_ERR;
574 
575 	memset(p_dev, 0, sizeof(struct SFNOR_DEV));
576 	snor_read_id(id_byte);
577 	rkflash_print_error("sfc nor id: %x %x %x\n",
578 			    id_byte[0], id_byte[1], id_byte[2]);
579 	if (0xFF == id_byte[0] || 0x00 == id_byte[0])
580 		return SFC_ERROR;
581 
582 	p_dev->manufacturer = id_byte[0];
583 	p_dev->mem_type = id_byte[1];
584 
585 	g_spi_flash_info = snor_get_flash_info(id_byte);
586 	if (g_spi_flash_info) {
587 		snor_flash_info_adjust(g_spi_flash_info);
588 		p_dev->capacity = 1 << g_spi_flash_info->density;
589 		p_dev->blk_size = g_spi_flash_info->block_size;
590 		p_dev->page_size = NOR_SECS_PAGE;
591 		p_dev->read_cmd = g_spi_flash_info->read_cmd;
592 		p_dev->prog_cmd = g_spi_flash_info->prog_cmd;
593 		p_dev->sec_erase_cmd = g_spi_flash_info->sector_erase_cmd;
594 		p_dev->blk_erase_cmd = g_spi_flash_info->block_erase_cmd;
595 		p_dev->prog_lines = DATA_LINES_X1;
596 		p_dev->read_lines = DATA_LINES_X1;
597 		p_dev->QE_bits = g_spi_flash_info->QE_bits;
598 		p_dev->addr_mode = ADDR_MODE_3BYTE;
599 
600 		i = g_spi_flash_info->feature & FEA_READ_STATUE_MASK;
601 		if (i == 0)
602 			p_dev->write_status = snor_write_status;
603 		else if (i == 1)
604 			p_dev->write_status = snor_write_status1;
605 		else if (i == 2)
606 			p_dev->write_status = snor_write_status2;
607 		if (g_spi_flash_info->feature & FEA_4BIT_READ) {
608 			ret = SFC_OK;
609 			if (g_spi_flash_info->QE_bits)
610 				ret = snor_enable_QE(p_dev);
611 			if (ret == SFC_OK) {
612 				p_dev->read_lines = DATA_LINES_X4;
613 				p_dev->read_cmd = g_spi_flash_info->read_cmd_4;
614 			}
615 		}
616 		if (g_spi_flash_info->feature & FEA_4BIT_PROG &&
617 		    p_dev->read_lines == DATA_LINES_X4) {
618 			p_dev->prog_lines = DATA_LINES_X4;
619 			p_dev->prog_cmd = g_spi_flash_info->prog_cmd_4;
620 		}
621 
622 		if (g_spi_flash_info->feature & FEA_4BYTE_ADDR)
623 			p_dev->addr_mode = ADDR_MODE_4BYTE;
624 
625 		if ((g_spi_flash_info->feature & FEA_4BYTE_ADDR_MODE))
626 			snor_enter_4byte_mode();
627 	} else {
628 		p_dev->capacity = 1 << id_byte[2] >> 3;
629 		p_dev->QE_bits = 0;
630 		p_dev->blk_size = NOR_SECS_BLK;
631 		p_dev->page_size = NOR_SECS_PAGE;
632 		p_dev->read_cmd = CMD_READ_DATA;
633 		p_dev->prog_cmd = CMD_PAGE_PROG;
634 		p_dev->sec_erase_cmd = CMD_SECTOR_ERASE;
635 		p_dev->blk_erase_cmd = CMD_BLOCK_ERASE;
636 		p_dev->prog_lines = DATA_LINES_X1;
637 		p_dev->read_lines = DATA_LINES_X1;
638 		p_dev->write_status = snor_write_status;
639 	}
640 
641 	rkflash_print_info("addr_mode: %x\n", p_dev->addr_mode);
642 	rkflash_print_info("read_lines: %x\n", p_dev->read_lines);
643 	rkflash_print_info("prog_lines: %x\n", p_dev->prog_lines);
644 	rkflash_print_info("read_cmd: %x\n", p_dev->read_cmd);
645 	rkflash_print_info("prog_cmd: %x\n", p_dev->prog_cmd);
646 	rkflash_print_info("blk_erase_cmd: %x\n", p_dev->blk_erase_cmd);
647 	rkflash_print_info("sec_erase_cmd: %x\n", p_dev->sec_erase_cmd);
648 
649 	return SFC_OK;
650 }
651 
652