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