xref: /rk3399_rockchip-uboot/drivers/rkflash/sfc_nand.c (revision 6cef3c7b7cc45a9c882fc64e5496a416c99313b8)
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 u32 sfc_nand_get_ecc_status0(void);
18 static u32 sfc_nand_get_ecc_status1(void);
19 static u32 sfc_nand_get_ecc_status2(void);
20 static u32 sfc_nand_get_ecc_status3(void);
21 static u32 sfc_nand_get_ecc_status4(void);
22 static u32 sfc_nand_get_ecc_status5(void);
23 static u32 sfc_nand_get_ecc_status6(void);
24 static u32 sfc_nand_get_ecc_status7(void);
25 static u32 sfc_nand_get_ecc_status8(void);
26 static u32 sfc_nand_get_ecc_status9(void);
27 static u32 sfc_nand_get_ecc_status10(void);
28 static u32 sfc_nand_get_ecc_status11(void);
29 
30 static struct nand_info spi_nand_tbl[] = {
31 	/* TC58CVG0S0HxAIx */
32 	{ 0x98, 0xC2, 0x00, 4, 0x40, 1, 1024, 0x00, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
33 	/* TC58CVG1S0HxAIx */
34 	{ 0x98, 0xCB, 0x00, 4, 0x40, 2, 1024, 0x00, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
35 	/* TC58CVG2S0HRAIJ */
36 	{ 0x98, 0xED, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 0, { 0x04, 0x0C, 0x08, 0x10 }, &sfc_nand_get_ecc_status0 },
37 	/* TC58CVG1S3HRAIJ */
38 	{ 0x98, 0xEB, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
39 	/* TC58CVG0S3HRAIJ */
40 	{ 0x98, 0xE2, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
41 
42 	/* MX35LF1GE4AB */
43 	{ 0xC2, 0x12, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
44 	/* MX35LF2GE4AB */
45 	{ 0xC2, 0x22, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
46 	/* MX35LF2GE4AD */
47 	{ 0xC2, 0x26, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
48 	/* MX35LF4GE4AD */
49 	{ 0xC2, 0x37, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 },
50 	/* MX35UF1GE4AC */
51 	{ 0xC2, 0x92, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
52 	/* MX35UF2GE4AC */
53 	{ 0xC2, 0xA2, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
54 	/* MX35UF1GE4AD */
55 	{ 0xC2, 0x96, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
56 	/* MX35UF2GE4AD */
57 	{ 0xC2, 0xA6, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
58 	/* MX35UF4GE4AD */
59 	{ 0xC2, 0xB7, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 },
60 
61 	/* GD5F1GQ4UAYIG */
62 	{ 0xC8, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
63 	/* GD5F1GQ4RB9IGR */
64 	{ 0xC8, 0xD1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
65 	/* GD5F2GQ40BY2GR */
66 	{ 0xC8, 0xD2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
67 	/* GD5F1GQ5UEYIG */
68 	{ 0xC8, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 },
69 	/* GD5F2GQ5UEYIG */
70 	{ 0xC8, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 },
71 	/* GD5F1GQ4R */
72 	{ 0xC8, 0xC1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
73 	/* GD5F4GQ6RExxG 1*4096 */
74 	{ 0xC8, 0x45, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status2 },
75 	/* GD5F4GQ6UExxG 1*4096 */
76 	{ 0xC8, 0x55, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status2 },
77 	/* GD5F1GQ4UExxH */
78 	{ 0xC8, 0xD9, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
79 	/* GD5F1GQ5REYIG Add 3rd code to distingush with F50L2G41KA */
80 	{ 0xC8, 0x41, 0xC8, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 },
81 	/* GD5F2GQ5REYIG */
82 	{ 0xC8, 0x42, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 },
83 	/* GD5F2GM7RxG */
84 	{ 0xC8, 0x82, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
85 	/* GD5F2GM7UxG */
86 	{ 0xC8, 0x92, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
87 	/* GD5F1GM7UxG */
88 	{ 0xC8, 0x91, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
89 	/* GD5F4GQ4UAYIG 1*4096 */
90 	{ 0xC8, 0xF4, 0x00, 4, 0x40, 2, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 },
91 	/* GD5F1GM7REYIGR */
92 	{ 0xC8, 0x81, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 },
93 	/* GD5F4GM8UEYIGR */
94 	{ 0xC8, 0x95, 0x00, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status3 },
95 
96 	/* W25N01GV */
97 	{ 0xEF, 0xAA, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 },
98 	/* W25N02KVZEIR */
99 	{ 0xEF, 0xAA, 0x22, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status0 },
100 	/* W25N04KVZEIR */
101 	{ 0xEF, 0xAA, 0x23, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 0, { 0x04, 0x14, 0x24, 0x34 }, &sfc_nand_get_ecc_status0 },
102 	/* W25N01GW */
103 	{ 0xEF, 0xBA, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 },
104 	/* W25N02KW */
105 	{ 0xEF, 0xBA, 0x22, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status0 },
106 	/* W25N512GVEIG */
107 	{ 0xEF, 0xAA, 0x20, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 },
108 	/* W25N01KV */
109 	{ 0xEF, 0xAE, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
110 	/* W25N01JWZEIG */
111 	{ 0xEF, 0xBC, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
112 	/* W25N01KWZPIG */
113 	{ 0xEF, 0xBE, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
114 
115 	/* HYF2GQ4UAACAE */
116 	{ 0xC9, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
117 	/* HYF1GQ4UDACAE */
118 	{ 0xC9, 0x21, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
119 	/* HYF1GQ4UPACAE */
120 	{ 0xC9, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
121 	/* HYF2GQ4UDACAE */
122 	{ 0xC9, 0x22, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
123 	/* HYF2GQ4UHCCAE */
124 	{ 0xC9, 0x5A, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
125 	/* HYF4GQ4UAACBE */
126 	{ 0xC9, 0xD4, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0xE, 1, { 0x20, 0x40, 0x24, 0x44 }, &sfc_nand_get_ecc_status0 },
127 	/* HYF2GQ4IAACAE */
128 	{ 0xC9, 0x82, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
129 	/* HYF1GQ4IDACAE */
130 	{ 0xC9, 0x81, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
131 
132 	/* FS35ND01G-S1 */
133 	{ 0xCD, 0xB1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x10, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 },
134 	/* FS35ND02G-S2 */
135 	{ 0xCD, 0xA2, 0x00, 4, 0x40, 1, 2048, 0x00, 19, 0x4, 0, { 0x10, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 },
136 	/* FS35ND01G-S1Y2 */
137 	{ 0xCD, 0xEA, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
138 	/* FS35ND02G-S3Y2 */
139 	{ 0xCD, 0xEB, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
140 	/* FS35ND04G-S2Y2 1*4096 */
141 	{ 0xCD, 0xEC, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 0, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status1 },
142 	/* F35SQA001G */
143 	{ 0xCD, 0x71, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
144 	/* F35SQA002G */
145 	{ 0xCD, 0x72, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
146 	/* F35SQA512M */
147 	{ 0xCD, 0x70, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
148 	/* F35UQA512M */
149 	{ 0xCD, 0x60, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
150 	/* F35UQA002G-WWT */
151 	{ 0xCD, 0x62, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
152 	/* F35SQB004G-WWT */
153 	{ 0xCD, 0x61, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
154 	/* F35SQB004G */
155 	{ 0xCD, 0x53, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status10 },
156 	/* F35SQB002G */
157 	{ 0xCD, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status10 },
158 
159 	/* DS35Q1GA-IB */
160 	{ 0xE5, 0x71, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
161 	/* DS35Q2GA-IB */
162 	{ 0xE5, 0x72, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
163 	/* DS35M1GA-1B */
164 	{ 0xE5, 0x21, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
165 	/* DS35M2GA-IB */
166 	{ 0xE5, 0x22, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
167 	/* DS35Q1GB-IB */
168 	{ 0xE5, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
169 	/* DS35Q2GB-IB */
170 	{ 0xE5, 0xF2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
171 	/* DS35Q4GM */
172 	{ 0xE5, 0xF4, 0x00, 4, 0x40, 2, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x14, 0x0C, 0x10 }, &sfc_nand_get_ecc_status6 },
173 	/* DS35M1GB-IB */
174 	{ 0xE5, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
175 	/* DS35Q12B-IB */
176 	{ 0xE5, 0xF5, 0x00, 4, 0x40, 1, 512, 0x0C, 17, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
177 	/* DS35M12B-IB */
178 	{ 0xE5, 0xA5, 0x00, 4, 0x40, 1, 512, 0x0C, 17, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
179 	/* DS35Q1GD-IB */
180 	{ 0xE5, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
181 	/* DS35M4GB-IB */
182 	{ 0xE5, 0x64, 0x00, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status6 },
183 	/* DS35Q4GB-IB */
184 	{ 0xE5, 0xB4, 0x00, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status6 },
185 	/* DS35M12C-IB */
186 	{ 0xE5, 0x25, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
187 	/* DS35Q12C-IB */
188 	{ 0xE5, 0x75, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
189 	/* DS35Q2GBS */
190 	{ 0xE5, 0xB2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
191 
192 	/* EM73C044VCC-H */
193 	{ 0xD5, 0x22, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
194 	/* EM73D044VCE-H */
195 	{ 0xD5, 0x20, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
196 	/* EM73E044SNA-G */
197 	{ 0xD5, 0x03, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x28, 0x08, 0x2C }, &sfc_nand_get_ecc_status0 },
198 	/* EM73C044VCF-H */
199 	{ 0xD5, 0x25, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
200 	/* EM73E044VCE-H */
201 	{ 0xD5, 0x3B, 0x00, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status0 },
202 
203 	/* XT26G02A */
204 	{ 0x0B, 0xE2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 },
205 	/* XT26G01A */
206 	{ 0x0B, 0xE1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 },
207 	/* XT26G04A */
208 	{ 0x0B, 0xE3, 0x00, 4, 0x80, 1, 2048, 0x4C, 20, 0x8, 1, { 0x08, 0x0C, 0x0C, 0x10 }, &sfc_nand_get_ecc_status4 },
209 	/* XT26G01B */
210 	{ 0x0B, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 },
211 	/* XT26G02B */
212 	{ 0x0B, 0xF2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 },
213 	/* XT26G01C */
214 	{ 0x0B, 0x11, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 },
215 	/* XT26G02C */
216 	{ 0x0B, 0x12, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 },
217 	/* XT26G04C */
218 	{ 0x0B, 0x13, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status7 },
219 	/* XT26G11C */
220 	{ 0x0B, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
221 	/* XT26Q02DWSIGA */
222 	{ 0x0B, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
223 	/* XT26Q01DWSIGA */
224 	{ 0x0B, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
225 	/* XT26Q04DWSIGA */
226 	{ 0x0B, 0x53, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status0 },
227 	/* XT26G01DWSIGA */
228 	{ 0x0B, 0x31, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
229 	/* XT26G02DWSIGA */
230 	{ 0x0B, 0x32, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
231 	/* XT26G04DWSIGA */
232 	{ 0x0B, 0x33, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status0 },
233 	/* XT26Q04DWSIGT-B */
234 	{ 0x0B, 0x53, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x14, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status0 },
235 	/* XT26Q01DWSIGA */
236 	{ 0x0B, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
237 
238 	/* MT29F2G01ABA, XT26G02E, F50L2G41XA */
239 	{ 0x2C, 0x24, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
240 	/* MT29F1G01ABA, F50L1G41XA */
241 	{ 0x2C, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
242 
243 	/* FM25S01 */
244 	{ 0xA1, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x00, 0x04, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
245 	/* FM25S01A */
246 	{ 0xA1, 0xE4, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
247 	/* FM25S02A */
248 	{ 0xA1, 0xE5, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
249 	/* FM25LS01 */
250 	{ 0xA1, 0xA5, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
251 	/* FM25S01BI3 */
252 	{ 0xA1, 0xD4, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
253 	/* FM25G02BI3 */
254 	{ 0xA1, 0xD2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
255 	/* FM25S02BI3-DND-A-G3 */
256 	{ 0xA1, 0xD6, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
257 	/* FM25G02D */
258 	{ 0xA1, 0xF2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 },
259 
260 	/* IS37SML01G1 */
261 	{ 0xC8, 0x21, 0x00, 4, 0x40, 1, 1024, 0x00, 18, 0x1, 0, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
262 	/* F50L1G41LB */
263 	{ 0xC8, 0x01, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
264 	/* F50L2G41KA */
265 	{ 0xC8, 0x41, 0x7F, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
266 
267 	/* UM19A1HISW */
268 	{ 0xB0, 0x24, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
269 	/* UM19A0HCSW */
270 	{ 0xB0, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
271 	/* UM19A0LCSW */
272 	{ 0xB0, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
273 	/* UM19A1LISW */
274 	{ 0xB0, 0x25, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 },
275 	/* UM19A9LISW */
276 	{ 0xB0, 0x0D, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
277 	/* UM19A9HISW */
278 	{ 0xB0, 0x0C, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
279 	/* UM19A0HISW */
280 	{ 0xB0, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status11 },
281 	/* UM19A0LISW */
282 	{ 0xB0, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status11 },
283 
284 	/* ATO25D1GA */
285 	{ 0x9B, 0x12, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x1, 1, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
286 	/* BWJX08K-2Gb */
287 	{ 0xBC, 0xB3, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x10, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
288 	/* JS28U1GQSCAHG-83 */
289 	{ 0xBF, 0x21, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status8 },
290 	/* SGM7000I-S24W1GH */
291 	{ 0xEA, 0xC1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
292 	/* TX25G01 */
293 	{ 0xA1, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status8 },
294 
295 	/* S35ML01G3, ANV1GCP0CLG, HYF1GQ4UTXCAE, YX25G1E, GSS01GSAM0 */
296 	{ 0x01, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status9 },
297 	/* S35ML02G3, ANV2GCP0CLG, HYF2GQ4UTXCAE, YX25G2E */
298 	{ 0x01, 0x25, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status9 },
299 	/* S35ML04G3 */
300 	{ 0x01, 0x35, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 0, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status9 },
301 
302 	/* GSS01GSAK1 */
303 	{ 0x52, 0xBA, 0x13, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
304 	/* GSS02GSAK1 */
305 	{ 0x52, 0xBA, 0x23, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
306 	/* GSS02GSAX1 */
307 	{ 0x52, 0xCA, 0x23, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
308 	/* GSS01GSAX1 */
309 	{ 0x52, 0xCA, 0x13, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
310 
311 	/* XCSP2AAPK */
312 	{ 0x8C, 0xA1, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
313 	/* XCSP1AAPK */
314 	{ 0x8C, 0x01, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 },
315 	/* F50L1G41LC */
316 	{ 0x8C, 0x2C, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x1, 0, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
317 
318 	/* ZB35Q01BYIG */
319 	{ 0x5E, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
320 	/* ZB35Q04BYIG */
321 	{ 0x5E, 0xA3, 0x00, 4, 0x80, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status1 },
322 
323 	/* HSESYHDSW2G */
324 	{ 0x3C, 0xD2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 },
325 };
326 
327 static struct nand_info *p_nand_info;
328 static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4];
329 static struct SFNAND_DEV sfc_nand_dev;
330 
331 static struct nand_info *sfc_nand_get_info(u8 *nand_id)
332 {
333 	u32 i;
334 
335 	for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) {
336 		if (spi_nand_tbl[i].id0 == nand_id[0] &&
337 		    spi_nand_tbl[i].id1 == nand_id[1]) {
338 			if (spi_nand_tbl[i].id2 &&
339 			    spi_nand_tbl[i].id2 != nand_id[2])
340 				continue;
341 
342 			return &spi_nand_tbl[i];
343 		}
344 	}
345 
346 	return NULL;
347 }
348 
349 static int sfc_nand_write_en(void)
350 {
351 	int ret;
352 	struct rk_sfc_op op;
353 
354 	op.sfcmd.d32 = 0;
355 	op.sfcmd.b.cmd = CMD_WRITE_EN;
356 
357 	op.sfctrl.d32 = 0;
358 
359 	ret = sfc_request(&op, 0, NULL, 0);
360 	return ret;
361 }
362 
363 static int sfc_nand_rw_preset(void)
364 {
365 	int ret;
366 	struct rk_sfc_op op;
367 
368 	op.sfcmd.d32 = 0;
369 	op.sfcmd.b.cmd = 0xff;
370 	op.sfcmd.b.cs = 2;
371 
372 	op.sfctrl.d32 = 0;
373 	op.sfctrl.b.datalines = 2;
374 	op.sfctrl.b.cmdlines = 2;
375 	op.sfctrl.b.addrlines = 2;
376 
377 	ret = sfc_request(&op, 0, NULL, 0);
378 	return ret;
379 }
380 
381 static int sfc_nand_read_feature(u8 addr, u8 *data)
382 {
383 	int ret;
384 	struct rk_sfc_op op;
385 
386 	op.sfcmd.d32 = 0;
387 	op.sfcmd.b.cmd = 0x0F;
388 	op.sfcmd.b.addrbits = SFC_ADDR_XBITS;
389 
390 	op.sfctrl.d32 = 0;
391 	op.sfctrl.b.addrbits = 8;
392 
393 	*data = 0;
394 
395 	ret = sfc_request(&op, addr, data, 1);
396 
397 	if (ret != SFC_OK)
398 		return ret;
399 
400 	return SFC_OK;
401 }
402 
403 static int sfc_nand_write_feature(u32 addr, u8 status)
404 {
405 	int ret;
406 	struct rk_sfc_op op;
407 
408 	sfc_nand_write_en();
409 
410 	op.sfcmd.d32 = 0;
411 	op.sfcmd.b.cmd = 0x1F;
412 	op.sfcmd.b.addrbits = SFC_ADDR_XBITS;
413 	op.sfcmd.b.rw = SFC_WRITE;
414 
415 	op.sfctrl.d32 = 0;
416 	op.sfctrl.b.addrbits = 8;
417 
418 	ret = sfc_request(&op, addr, &status, 1);
419 
420 	if (ret != SFC_OK)
421 		return ret;
422 
423 	return ret;
424 }
425 
426 static int sfc_nand_wait_busy(u8 *data, int timeout)
427 {
428 	int ret;
429 	int i;
430 	u8 status;
431 
432 	*data = 0;
433 
434 	for (i = 0; i < timeout; i++) {
435 		ret = sfc_nand_read_feature(0xC0, &status);
436 
437 		if (ret != SFC_OK)
438 			return ret;
439 
440 		*data = status;
441 
442 		if (!(status & (1 << 0)))
443 			return SFC_OK;
444 
445 		sfc_delay(1);
446 	}
447 
448 	return SFC_NAND_WAIT_TIME_OUT;
449 }
450 
451 /*
452  * ecc default:
453  * ecc bits: 0xC0[4,5]
454  * 0b00, No bit errors were detected
455  * 0b01, Bit errors were detected and corrected.
456  * 0b10, Multiple bit errors were detected and not corrected.
457  * 0b11, Bits errors were detected and corrected, bit error count
458  *	reach the bit flip detection threshold
459  */
460 static u32 sfc_nand_get_ecc_status0(void)
461 {
462 	u32 ret;
463 	u32 i;
464 	u8 ecc;
465 	u8 status;
466 	u32 timeout = 1000 * 1000;
467 
468 	for (i = 0; i < timeout; i++) {
469 		ret = sfc_nand_read_feature(0xC0, &status);
470 
471 		if (ret != SFC_OK)
472 			return SFC_NAND_ECC_ERROR;
473 
474 		if (!(status & (1 << 0)))
475 			break;
476 
477 		sfc_delay(1);
478 	}
479 
480 	ecc = (status >> 4) & 0x03;
481 
482 	if (ecc <= 1)
483 		ret = SFC_NAND_ECC_OK;
484 	else if (ecc == 2)
485 		ret = (u32)SFC_NAND_ECC_ERROR;
486 	else
487 		ret = SFC_NAND_ECC_REFRESH;
488 
489 	return ret;
490 }
491 
492 /*
493  * ecc spectial type1:
494  * ecc bits: 0xC0[4,5]
495  * 0b00, No bit errors were detected;
496  * 0b01, Bits errors were detected and corrected, bit error count
497  *	may reach the bit flip detection threshold;
498  * 0b10, Multiple bit errors were detected and not corrected;
499  * 0b11, Reserved.
500  */
501 static u32 sfc_nand_get_ecc_status1(void)
502 {
503 	u32 ret;
504 	u32 i;
505 	u8 ecc;
506 	u8 status;
507 	u32 timeout = 1000 * 1000;
508 
509 	for (i = 0; i < timeout; i++) {
510 		ret = sfc_nand_read_feature(0xC0, &status);
511 
512 		if (ret != SFC_OK)
513 			return SFC_NAND_ECC_ERROR;
514 
515 		if (!(status & (1 << 0)))
516 			break;
517 
518 		sfc_delay(1);
519 	}
520 
521 	ecc = (status >> 4) & 0x03;
522 
523 	if (ecc == 0)
524 		ret = SFC_NAND_ECC_OK;
525 	else if (ecc == 1)
526 		ret = SFC_NAND_ECC_REFRESH;
527 	else
528 		ret = (u32)SFC_NAND_ECC_ERROR;
529 
530 	return ret;
531 }
532 
533 /*
534  * ecc spectial type2:
535  * ecc bits: 0xC0[4,5] 0xF0[4,5]
536  * [0b0000, 0b0011], No bit errors were detected;
537  * [0b0100, 0b0111], Bit errors were detected and corrected. Not
538  *	reach Flipping Bits;
539  * [0b1000, 0b1011], Multiple bit errors were detected and
540  *	not corrected.
541  * [0b1100, 0b1111], reserved.
542  */
543 static u32 sfc_nand_get_ecc_status2(void)
544 {
545 	u32 ret;
546 	u32 i;
547 	u8 ecc;
548 	u8 status, status1;
549 	u32 timeout = 1000 * 1000;
550 
551 	for (i = 0; i < timeout; i++) {
552 		ret = sfc_nand_read_feature(0xC0, &status);
553 
554 		if (ret != SFC_OK)
555 			return SFC_NAND_ECC_ERROR;
556 
557 		ret = sfc_nand_read_feature(0xF0, &status1);
558 
559 		if (ret != SFC_OK)
560 			return SFC_NAND_ECC_ERROR;
561 
562 		if (!(status & (1 << 0)))
563 			break;
564 
565 		sfc_delay(1);
566 	}
567 
568 	ecc = (status >> 4) & 0x03;
569 	ecc = (ecc << 2) | ((status1 >> 4) & 0x03);
570 
571 	if (ecc < 7)
572 		ret = SFC_NAND_ECC_OK;
573 	else if (ecc == 7)
574 		ret = SFC_NAND_ECC_REFRESH;
575 	else
576 		ret = (u32)SFC_NAND_ECC_ERROR;
577 
578 	return ret;
579 }
580 
581 /*
582  * ecc spectial type3:
583  * ecc bits: 0xC0[4,5] 0xF0[4,5]
584  * [0b0000, 0b0011], No bit errors were detected;
585  * [0b0100, 0b0111], Bit errors were detected and corrected. Not
586  *	reach Flipping Bits;
587  * [0b1000, 0b1011], Multiple bit errors were detected and
588  *	not corrected.
589  * [0b1100, 0b1111], Bit error count equals the bit flip
590  *	detectio nthreshold
591  */
592 static u32 sfc_nand_get_ecc_status3(void)
593 {
594 	u32 ret;
595 	u32 i;
596 	u8 ecc;
597 	u8 status, status1;
598 	u32 timeout = 1000 * 1000;
599 
600 	for (i = 0; i < timeout; i++) {
601 		ret = sfc_nand_read_feature(0xC0, &status);
602 
603 		if (ret != SFC_OK)
604 			return SFC_NAND_ECC_ERROR;
605 
606 		ret = sfc_nand_read_feature(0xF0, &status1);
607 
608 		if (ret != SFC_OK)
609 			return SFC_NAND_ECC_ERROR;
610 
611 		if (!(status & (1 << 0)))
612 			break;
613 
614 		sfc_delay(1);
615 	}
616 
617 	ecc = (status >> 4) & 0x03;
618 	ecc = (ecc << 2) | ((status1 >> 4) & 0x03);
619 
620 	if (ecc < 7)
621 		ret = SFC_NAND_ECC_OK;
622 	else if (ecc == 7 || ecc >= 12)
623 		ret = SFC_NAND_ECC_REFRESH;
624 	else
625 		ret = (u32)SFC_NAND_ECC_ERROR;
626 
627 	return ret;
628 }
629 
630 /*
631  * ecc spectial type4:
632  * ecc bits: 0xC0[2,5]
633  * [0b0000], No bit errors were detected;
634  * [0b0001, 0b0111], Bit errors were detected and corrected. Not
635  *	reach Flipping Bits;
636  * [0b1000], Multiple bit errors were detected and
637  *	not corrected.
638  * [0b1100], Bit error count equals the bit flip
639  *	detection threshold
640  * else, reserved
641  */
642 static u32 sfc_nand_get_ecc_status4(void)
643 {
644 	u32 ret;
645 	u32 i;
646 	u8 ecc;
647 	u8 status;
648 	u32 timeout = 1000 * 1000;
649 
650 	for (i = 0; i < timeout; i++) {
651 		ret = sfc_nand_read_feature(0xC0, &status);
652 
653 		if (ret != SFC_OK)
654 			return SFC_NAND_ECC_ERROR;
655 
656 		if (!(status & (1 << 0)))
657 			break;
658 
659 		sfc_delay(1);
660 	}
661 
662 	ecc = (status >> 2) & 0x0f;
663 
664 	if (ecc < 7)
665 		ret = SFC_NAND_ECC_OK;
666 	else if (ecc == 7 || ecc == 12)
667 		ret = SFC_NAND_ECC_REFRESH;
668 	else
669 		ret = (u32)SFC_NAND_ECC_ERROR;
670 
671 	return ret;
672 }
673 
674 /*
675  * ecc spectial type5:
676  * ecc bits: 0xC0[4,6]
677  * [0b000], No bit errors were detected;
678  * [0b001, 0b011], Bit errors were detected and corrected. Not
679  *	reach Flipping Bits;
680  * [0b100], Bit error count equals the bit flip
681  *	detection threshold
682  * [0b101, 0b110], Reserved;
683  * [0b111], Multiple bit errors were detected and
684  *	not corrected.
685  */
686 static u32 sfc_nand_get_ecc_status5(void)
687 {
688 	u32 ret;
689 	u32 i;
690 	u8 ecc;
691 	u8 status;
692 	u32 timeout = 1000 * 1000;
693 
694 	for (i = 0; i < timeout; i++) {
695 		ret = sfc_nand_read_feature(0xC0, &status);
696 
697 		if (ret != SFC_OK)
698 			return SFC_NAND_ECC_ERROR;
699 
700 		if (!(status & (1 << 0)))
701 			break;
702 
703 		sfc_delay(1);
704 	}
705 
706 	ecc = (status >> 4) & 0x07;
707 
708 	if (ecc < 4)
709 		ret = SFC_NAND_ECC_OK;
710 	else if (ecc == 4)
711 		ret = SFC_NAND_ECC_REFRESH;
712 	else
713 		ret = (u32)SFC_NAND_ECC_ERROR;
714 
715 	return ret;
716 }
717 
718 /*
719  * ecc spectial type6:
720  * ecc bits: 0xC0[4,6]
721  * [0b000], No bit errors were detected;
722  * [0b001], 1-3 Bit errors were detected and corrected. Not
723  *	reach Flipping Bits;
724  * [0b010], Multiple bit errors were detected and
725  *	not corrected.
726  * [0b011], 4-6 Bit errors were detected and corrected. Not
727  *	reach Flipping Bits;
728  * [0b101], Bit error count equals the bit flip
729  *	detectionthreshold
730  * others, Reserved.
731  */
732 static u32 sfc_nand_get_ecc_status6(void)
733 {
734 	u32 ret;
735 	u32 i;
736 	u8 ecc;
737 	u8 status;
738 	u32 timeout = 1000 * 1000;
739 
740 	for (i = 0; i < timeout; i++) {
741 		ret = sfc_nand_read_feature(0xC0, &status);
742 
743 		if (ret != SFC_OK)
744 			return SFC_NAND_ECC_ERROR;
745 
746 		if (!(status & (1 << 0)))
747 			break;
748 
749 		sfc_delay(1);
750 	}
751 
752 	ecc = (status >> 4) & 0x07;
753 
754 	if (ecc == 0 || ecc == 1 || ecc == 3)
755 		ret = SFC_NAND_ECC_OK;
756 	else if (ecc == 5)
757 		ret = SFC_NAND_ECC_REFRESH;
758 	else
759 		ret = (u32)SFC_NAND_ECC_ERROR;
760 
761 	return ret;
762 }
763 
764 /*
765  * ecc spectial type7:
766  * ecc bits: 0xC0[4,7]
767  * [0b0000], No bit errors were detected;
768  * [0b0001, 0b0111], 1-7 Bit errors were detected and corrected. Not
769  *	reach Flipping Bits;
770  * [0b1000], 8 Bit errors were detected and corrected. Bit error count
771  * 	equals the bit flip detectionthreshold;
772  * [0b1111], Bit errors greater than ECC capability(8 bits) and not corrected;
773  * others, Reserved.
774  */
775 static u32 sfc_nand_get_ecc_status7(void)
776 {
777 	u32 ret;
778 	u32 i;
779 	u8 ecc;
780 	u8 status;
781 	u32 timeout = 1000 * 1000;
782 
783 	for (i = 0; i < timeout; i++) {
784 		ret = sfc_nand_read_feature(0xC0, &status);
785 
786 		if (ret != SFC_OK)
787 			return SFC_NAND_ECC_ERROR;
788 
789 		if (!(status & (1 << 0)))
790 			break;
791 
792 		sfc_delay(1);
793 	}
794 
795 	ecc = (status >> 4) & 0xf;
796 
797 	if (ecc < 7)
798 		ret = SFC_NAND_ECC_OK;
799 	else if (ecc == 7 || ecc == 8)
800 		ret = SFC_NAND_ECC_REFRESH;
801 	else
802 		ret = (u32)SFC_NAND_ECC_ERROR;
803 
804 	return ret;
805 }
806 
807 /*
808  * ecc spectial type8:
809  * ecc bits: 0xC0[4,6]
810  * [0b000], No bit errors were detected;
811  * [0b001, 0b011], 1~3 Bit errors were detected and corrected. Not
812  *	reach Flipping Bits;
813  * [0b100], Bit error count equals the bit flip
814  *	detection threshold
815  * others, Reserved.
816  */
817 static u32 sfc_nand_get_ecc_status8(void)
818 {
819 	u32 ret;
820 	u32 i;
821 	u8 ecc;
822 	u8 status;
823 	u32 timeout = 1000 * 1000;
824 
825 	for (i = 0; i < timeout; i++) {
826 		ret = sfc_nand_read_feature(0xC0, &status);
827 
828 		if (ret != SFC_OK)
829 			return SFC_NAND_ECC_ERROR;
830 
831 		if (!(status & (1 << 0)))
832 			break;
833 
834 		sfc_delay(1);
835 	}
836 
837 	ecc = (status >> 4) & 0x07;
838 
839 	if (ecc < 4)
840 		ret = SFC_NAND_ECC_OK;
841 	else if (ecc == 4)
842 		ret = SFC_NAND_ECC_REFRESH;
843 	else
844 		ret = (u32)SFC_NAND_ECC_ERROR;
845 
846 	return ret;
847 }
848 
849 /*
850  * ecc spectial type9:
851  * ecc bits: 0xC0[4,5]
852  * 0b00, No bit errors were detected
853  * 0b01, 1-2Bit errors were detected and corrected.
854  * 0b10, 3-4Bit errors were detected and corrected.
855  * 0b11, 11 can be used as uncorrectable
856  */
857 static u32 sfc_nand_get_ecc_status9(void)
858 {
859 	u32 ret;
860 	u32 i;
861 	u8 ecc;
862 	u8 status;
863 	u32 timeout = 1000 * 1000;
864 
865 	for (i = 0; i < timeout; i++) {
866 		ret = sfc_nand_read_feature(0xC0, &status);
867 
868 		if (ret != SFC_OK)
869 			return SFC_NAND_ECC_ERROR;
870 
871 		if (!(status & (1 << 0)))
872 			break;
873 
874 		sfc_delay(1);
875 	}
876 
877 	ecc = (status >> 4) & 0x03;
878 
879 	if (ecc <= 1)
880 		ret = SFC_NAND_ECC_OK;
881 	else if (ecc == 2)
882 		ret = SFC_NAND_ECC_REFRESH;
883 	else
884 		ret = (u32)SFC_NAND_ECC_ERROR;
885 
886 	return ret;
887 }
888 
889 /*
890  * ecc spectial type10:
891  * ecc bits: 0xC0[4,6]
892  * [0b000], No bit errors were detected;
893  * [0b001, 0b101], 3~7 Bit errors were detected and corrected. Not
894  *	reach Flipping Bits;
895  * [0b110], Bit error count equals the bit flip detection threshold
896  * [0b111], Bit errors greater than ECC capability(8 bits) and not corrected;
897  */
898 static u32 sfc_nand_get_ecc_status10(void)
899 {
900 	u32 ret;
901 	u32 i;
902 	u8 ecc;
903 	u8 status;
904 	u32 timeout = 1000 * 1000;
905 
906 	for (i = 0; i < timeout; i++) {
907 		ret = sfc_nand_read_feature(0xC0, &status);
908 
909 		if (ret != SFC_OK)
910 			return SFC_NAND_ECC_ERROR;
911 
912 		if (!(status & (1 << 0)))
913 			break;
914 
915 		sfc_delay(1);
916 	}
917 
918 	ecc = (status >> 4) & 0x07;
919 
920 	if (ecc < 6)
921 		ret = SFC_NAND_ECC_OK;
922 	else if (ecc == 6)
923 		ret = SFC_NAND_ECC_REFRESH;
924 	else
925 		ret = (u32)SFC_NAND_ECC_ERROR;
926 
927 	return ret;
928 }
929 
930 /*
931  * ecc spectial type11:
932  * ecc bits: 0xC0[4,6]
933  * [0b000], No bit errors were detected;
934  * [0b001, 0b101], 3~7 Bit errors were detected and corrected. Not
935  *	reach Flipping Bits;
936  * [0b110], Bit error count equals the bit flip detection threshold
937  * [0b111], Bit errors greater than ECC capability(8 bits) and not corrected;
938  */
939 static u32 sfc_nand_get_ecc_status11(void)
940 {
941 	u32 ret;
942 	u32 i;
943 	u8 ecc;
944 	u8 status;
945 	u32 timeout = 1000 * 1000;
946 
947 	for (i = 0; i < timeout; i++) {
948 		ret = sfc_nand_read_feature(0xC0, &status);
949 
950 		if (ret != SFC_OK)
951 			return SFC_NAND_ECC_ERROR;
952 
953 		if (!(status & (1 << 0)))
954 			break;
955 
956 		sfc_delay(1);
957 	}
958 
959 	ecc = (status >> 4) & 0x07;
960 
961 	if (ecc <= 1)
962 		ret = SFC_NAND_ECC_OK;
963 	else if (ecc == 3 || ecc == 5)
964 		ret = SFC_NAND_ECC_REFRESH;
965 	else
966 		ret = (u32)SFC_NAND_ECC_ERROR;
967 
968 	return ret;
969 }
970 
971 u32 sfc_nand_erase_block(u8 cs, u32 addr)
972 {
973 	int ret;
974 	struct rk_sfc_op op;
975 	u8 status;
976 
977 	rkflash_print_dio("%s %x\n", __func__, addr);
978 	op.sfcmd.d32 = 0;
979 	op.sfcmd.b.cmd = 0xd8;
980 	op.sfcmd.b.addrbits = SFC_ADDR_24BITS;
981 	op.sfcmd.b.rw = SFC_WRITE;
982 
983 	op.sfctrl.d32 = 0;
984 
985 	sfc_nand_write_en();
986 	ret = sfc_request(&op, addr, NULL, 0);
987 
988 	if (ret != SFC_OK)
989 		return ret;
990 
991 	ret = sfc_nand_wait_busy(&status, 1000 * 1000);
992 
993 	if (status & (1 << 2))
994 		return SFC_NAND_PROG_ERASE_ERROR;
995 
996 	return ret;
997 }
998 
999 static u32 sfc_nand_read_cache(u32 row, u32 *p_page_buf, u32 column, u32 len)
1000 {
1001 	int ret;
1002 	u32 plane;
1003 	struct rk_sfc_op op;
1004 
1005 	op.sfcmd.d32 = 0;
1006 	op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd;
1007 	op.sfcmd.b.addrbits = SFC_ADDR_XBITS;
1008 	op.sfcmd.b.dummybits = 8;
1009 
1010 	op.sfctrl.d32 = 0;
1011 	op.sfctrl.b.datalines = sfc_nand_dev.read_lines;
1012 	op.sfctrl.b.addrbits = 16;
1013 
1014 	plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0;
1015 
1016 	ret = sfc_request(&op, plane | column, p_page_buf, len);
1017 	if (ret != SFC_OK)
1018 		return SFC_NAND_HW_ERROR;
1019 
1020 	return ret;
1021 }
1022 
1023 u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf)
1024 {
1025 	int ret;
1026 	u32 plane;
1027 	struct rk_sfc_op op;
1028 	u8 status;
1029 	u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page;
1030 	u32 data_area_size = SFC_NAND_SECTOR_SIZE * p_nand_info->sec_per_page;
1031 
1032 	rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]);
1033 	sfc_nand_write_en();
1034 
1035 	if (sfc_nand_dev.prog_lines == DATA_LINES_X4 &&
1036 	    p_nand_info->feature & FEA_SOFT_QOP_BIT &&
1037 	    sfc_get_version() < SFC_VER_3)
1038 		sfc_nand_rw_preset();
1039 
1040 	op.sfcmd.d32 = 0;
1041 	op.sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd;
1042 	op.sfcmd.b.addrbits = SFC_ADDR_XBITS;
1043 	op.sfcmd.b.rw = SFC_WRITE;
1044 
1045 	op.sfctrl.d32 = 0;
1046 	op.sfctrl.b.datalines = sfc_nand_dev.prog_lines;
1047 	op.sfctrl.b.addrbits = 16;
1048 	plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0;
1049 	sfc_request(&op, plane, p_page_buf, page_size);
1050 
1051 	/*
1052 	 * At the moment of power lost or dev running in harsh environment, flash
1053 	 * maybe work in a unkonw state and result in bit flip, when this situation
1054 	 * is detected by cache recheck, it's better to wait a second for a reliable
1055 	 * hardware environment to avoid abnormal data written to flash array.
1056 	 */
1057 	if (p_nand_info->id0 == MID_GIGADEV) {
1058 		sfc_nand_read_cache(addr, (u32 *)sfc_nand_dev.recheck_buffer, 0, data_area_size);
1059 		if (memcmp(sfc_nand_dev.recheck_buffer, p_page_buf, data_area_size)) {
1060 			rkflash_print_error("%s %x cache bitflip\n", __func__, addr);
1061 			mdelay(1000);
1062 			sfc_request(&op, plane, p_page_buf, page_size);
1063 		}
1064 	}
1065 
1066 	op.sfcmd.d32 = 0;
1067 	op.sfcmd.b.cmd = 0x10;
1068 	op.sfcmd.b.addrbits = SFC_ADDR_24BITS;
1069 	op.sfcmd.b.rw = SFC_WRITE;
1070 
1071 	op.sfctrl.d32 = 0;
1072 	ret = sfc_request(&op, addr, p_page_buf, 0);
1073 
1074 	if (ret != SFC_OK)
1075 		return ret;
1076 
1077 	ret = sfc_nand_wait_busy(&status, 1000 * 1000);
1078 	if (status & (1 << 3))
1079 		return SFC_NAND_PROG_ERASE_ERROR;
1080 
1081 	return ret;
1082 }
1083 
1084 u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
1085 {
1086 	int ret;
1087 	u32 sec_per_page = p_nand_info->sec_per_page;
1088 	u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE;
1089 	struct nand_mega_area *meta = &p_nand_info->meta;
1090 
1091 	memcpy(gp_page_buf, p_data, data_size);
1092 	memset(&gp_page_buf[data_size / 4], 0xff, sec_per_page * 16);
1093 	gp_page_buf[(data_size + meta->off0) / 4] = p_spare[0];
1094 	gp_page_buf[(data_size + meta->off1) / 4] = p_spare[1];
1095 
1096 	if (sec_per_page == 8) {
1097 		gp_page_buf[(data_size + meta->off2) / 4] = p_spare[2];
1098 		gp_page_buf[(data_size + meta->off3) / 4] = p_spare[3];
1099 	}
1100 
1101 	ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf);
1102 
1103 	return ret;
1104 }
1105 
1106 u32 sfc_nand_read(u32 row, u32 *p_page_buf, u32 column, u32 len)
1107 {
1108 	int ret;
1109 	u32 plane;
1110 	struct rk_sfc_op op;
1111 	u32 ecc_result;
1112 	u8 status;
1113 
1114 	op.sfcmd.d32 = 0;
1115 	op.sfcmd.b.cmd = 0x13;
1116 	op.sfcmd.b.rw = SFC_WRITE;
1117 	op.sfcmd.b.addrbits = SFC_ADDR_24BITS;
1118 
1119 	op.sfctrl.d32 = 0;
1120 
1121 	sfc_request(&op, row, p_page_buf, 0);
1122 
1123 	if (sfc_nand_dev.read_lines == DATA_LINES_X4 &&
1124 	    p_nand_info->feature & FEA_SOFT_QOP_BIT &&
1125 	    sfc_get_version() < SFC_VER_3)
1126 		sfc_nand_rw_preset();
1127 
1128 	sfc_nand_wait_busy(&status, 1000 * 1000);
1129 	if (sfc_nand_dev.manufacturer == 0x01 && status)
1130 		sfc_nand_wait_busy(&status, 1000 * 1000);
1131 
1132 	ecc_result = p_nand_info->ecc_status();
1133 
1134 	op.sfcmd.d32 = 0;
1135 	op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd;
1136 	op.sfcmd.b.addrbits = SFC_ADDR_XBITS;
1137 	op.sfcmd.b.dummybits = 8;
1138 
1139 	op.sfctrl.d32 = 0;
1140 	op.sfctrl.b.datalines = sfc_nand_dev.read_lines;
1141 	op.sfctrl.b.addrbits = 16;
1142 
1143 	plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0;
1144 	ret = sfc_request(&op, plane | column, p_page_buf, len);
1145 	rkflash_print_dio("%s %x %x\n", __func__, row, p_page_buf[0]);
1146 
1147 	if (ret != SFC_OK)
1148 		return SFC_NAND_HW_ERROR;
1149 
1150 	return ecc_result;
1151 }
1152 
1153 u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf)
1154 {
1155 	u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page;
1156 
1157 	return sfc_nand_read(addr, p_page_buf, 0, page_size);
1158 }
1159 
1160 u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)
1161 {
1162 	u32 ret;
1163 	u32 sec_per_page = p_nand_info->sec_per_page;
1164 	u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE;
1165 	struct nand_mega_area *meta = &p_nand_info->meta;
1166 
1167 	ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf);
1168 	memcpy(p_data, gp_page_buf, data_size);
1169 	p_spare[0] = gp_page_buf[(data_size + meta->off0) / 4];
1170 	p_spare[1] = gp_page_buf[(data_size + meta->off1) / 4];
1171 
1172 	if (p_nand_info->sec_per_page == 8) {
1173 		p_spare[2] = gp_page_buf[(data_size + meta->off2) / 4];
1174 		p_spare[3] = gp_page_buf[(data_size + meta->off3) / 4];
1175 	}
1176 
1177 	if (ret == SFC_NAND_HW_ERROR)
1178 		ret = SFC_NAND_ECC_ERROR;
1179 
1180 	if (ret != SFC_NAND_ECC_OK) {
1181 		rkflash_print_error("%s[0x%x], ret=0x%x\n", __func__, addr, ret);
1182 
1183 		if (p_data)
1184 			rkflash_print_hex("data:", p_data, 4, 8);
1185 
1186 		if (p_spare)
1187 			rkflash_print_hex("spare:", p_spare, 4, 2);
1188 	}
1189 
1190 	return ret;
1191 }
1192 
1193 u32 sfc_nand_check_bad_block(u8 cs, u32 addr)
1194 {
1195 	u32 ret;
1196 	u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE;
1197 	u32 marker = 0;
1198 
1199 	ret = sfc_nand_read(addr, &marker, data_size, 2);
1200 
1201 	/* unify with mtd framework */
1202 	if (ret == SFC_NAND_ECC_ERROR || (u16)marker != 0xffff)
1203 		rkflash_print_error("%s page= %x ret= %x spare= %x\n",
1204 				    __func__, addr, ret, marker);
1205 
1206 	/* Original bad block */
1207 	if ((u16)marker != 0xffff)
1208 		return true;
1209 
1210 	return false;
1211 }
1212 
1213 u32 sfc_nand_mark_bad_block(u8 cs, u32 addr)
1214 {
1215 	u32 ret;
1216 	u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE;
1217 
1218 	ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf);
1219 
1220 	if (ret)
1221 		return SFC_NAND_HW_ERROR;
1222 
1223 	gp_page_buf[data_size / 4] = 0x0;
1224 	ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf);
1225 
1226 	if (ret)
1227 		return SFC_NAND_HW_ERROR;
1228 
1229 	return ret;
1230 }
1231 
1232 int sfc_nand_read_id(u8 *data)
1233 {
1234 	int ret;
1235 	struct rk_sfc_op op;
1236 
1237 	op.sfcmd.d32 = 0;
1238 	op.sfcmd.b.cmd = CMD_READ_JEDECID;
1239 	op.sfcmd.b.addrbits = SFC_ADDR_XBITS;
1240 
1241 	op.sfctrl.d32 = 0;
1242 	op.sfctrl.b.addrbits = 8;
1243 
1244 	ret = sfc_request(&op, 0, data, 3);
1245 
1246 	return ret;
1247 }
1248 
1249 /*
1250  * Read the 1st page's 1st byte of a phy_blk
1251  * If not FF, it's bad blk
1252  */
1253 static int sfc_nand_get_bad_block_list(u16 *table, u32 die)
1254 {
1255 	u32 bad_cnt, page;
1256 	u32 blk_per_die;
1257 	u16 blk;
1258 
1259 	rkflash_print_info("%s\n", __func__);
1260 
1261 	bad_cnt = 0;
1262 	blk_per_die = p_nand_info->plane_per_die *
1263 		      p_nand_info->blk_per_plane;
1264 
1265 	for (blk = 0; blk < blk_per_die; blk++) {
1266 		page = (blk + blk_per_die * die) *
1267 		       p_nand_info->page_per_blk;
1268 
1269 		if (sfc_nand_check_bad_block(die, page)) {
1270 			table[bad_cnt++] = blk;
1271 			rkflash_print_error("die[%d], bad_blk[%d]\n", die, blk);
1272 		}
1273 	}
1274 
1275 	return (int)bad_cnt;
1276 }
1277 
1278 void sfc_nand_ftl_ops_init(void)
1279 {
1280 	/* para init */
1281 	g_nand_phy_info.nand_type	= 1;
1282 	g_nand_phy_info.die_num		= 1;
1283 	g_nand_phy_info.plane_per_die	= p_nand_info->plane_per_die;
1284 	g_nand_phy_info.blk_per_plane	= p_nand_info->blk_per_plane;
1285 	g_nand_phy_info.page_per_blk	= p_nand_info->page_per_blk;
1286 	g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk;
1287 	g_nand_phy_info.byte_per_sec	= SFC_NAND_SECTOR_SIZE;
1288 	g_nand_phy_info.sec_per_page	= p_nand_info->sec_per_page;
1289 	g_nand_phy_info.sec_per_blk	= p_nand_info->sec_per_page *
1290 					  p_nand_info->page_per_blk;
1291 	g_nand_phy_info.reserved_blk	= 8;
1292 	g_nand_phy_info.blk_per_die	= p_nand_info->plane_per_die *
1293 					  p_nand_info->blk_per_plane;
1294 	g_nand_phy_info.ecc_bits	= p_nand_info->max_ecc_bits;
1295 
1296 	/* driver register */
1297 	g_nand_ops.get_bad_blk_list	= sfc_nand_get_bad_block_list;
1298 	g_nand_ops.erase_blk		= sfc_nand_erase_block;
1299 	g_nand_ops.prog_page		= sfc_nand_prog_page;
1300 	g_nand_ops.read_page		= sfc_nand_read_page;
1301 	g_nand_ops.bch_sel		= NULL;
1302 }
1303 
1304 static int sfc_nand_enable_QE(void)
1305 {
1306 	int ret = SFC_OK;
1307 	u8 status;
1308 
1309 	ret = sfc_nand_read_feature(0xB0, &status);
1310 
1311 	if (ret != SFC_OK)
1312 		return ret;
1313 
1314 	if (status & 1)   /* is QE bit set */
1315 		return SFC_OK;
1316 
1317 	status |= 1;
1318 
1319 	return sfc_nand_write_feature(0xB0, status);
1320 }
1321 
1322 u32 sfc_nand_init(void)
1323 {
1324 	u8 status, id_byte[8];
1325 
1326 	sfc_nand_read_id(id_byte);
1327 	rkflash_print_error("sfc_nand id: %x %x %x\n",
1328 			    id_byte[0], id_byte[1], id_byte[2]);
1329 
1330 	if (id_byte[0] == 0xFF || id_byte[0] == 0x00)
1331 		return (u32)FTL_NO_FLASH;
1332 
1333 	p_nand_info = sfc_nand_get_info(id_byte);
1334 
1335 	if (!p_nand_info) {
1336 		pr_err("The device not support yet!\n");
1337 
1338 		return (u32)FTL_UNSUPPORTED_FLASH;
1339 	}
1340 
1341 	sfc_nand_dev.manufacturer = id_byte[0];
1342 	sfc_nand_dev.mem_type = id_byte[1];
1343 	sfc_nand_dev.capacity = p_nand_info->density;
1344 	sfc_nand_dev.block_size = p_nand_info->page_per_blk * p_nand_info->sec_per_page;
1345 	sfc_nand_dev.page_size = p_nand_info->sec_per_page;
1346 
1347 	/* disable block lock */
1348 	sfc_nand_write_feature(0xA0, 0);
1349 	sfc_nand_dev.read_lines = DATA_LINES_X1;
1350 	sfc_nand_dev.prog_lines = DATA_LINES_X1;
1351 	sfc_nand_dev.page_read_cmd = 0x03;
1352 	sfc_nand_dev.page_prog_cmd = 0x02;
1353 	sfc_nand_dev.recheck_buffer = ftl_malloc(SFC_NAND_PAGE_MAX_SIZE);
1354 	if (!sfc_nand_dev.recheck_buffer) {
1355 		rkflash_print_error("%s recheck_buffer alloc failed\n", __func__);
1356 		return -1;
1357 	}
1358 
1359 	if (p_nand_info->feature & FEA_4BIT_READ) {
1360 		if ((p_nand_info->has_qe_bits && sfc_nand_enable_QE() == SFC_OK) ||
1361 		    !p_nand_info->has_qe_bits) {
1362 			sfc_nand_dev.read_lines = DATA_LINES_X4;
1363 			sfc_nand_dev.page_read_cmd = 0x6b;
1364 		}
1365 	}
1366 
1367 	if (p_nand_info->feature & FEA_4BIT_PROG &&
1368 	    sfc_nand_dev.read_lines == DATA_LINES_X4) {
1369 		sfc_nand_dev.prog_lines = DATA_LINES_X4;
1370 		sfc_nand_dev.page_prog_cmd = 0x32;
1371 	}
1372 
1373 	sfc_nand_read_feature(0xA0, &status);
1374 	rkflash_print_info("sfc_nand A0 = 0x%x\n", status);
1375 	sfc_nand_read_feature(0xB0, &status);
1376 	rkflash_print_info("sfc_nand B0 = 0x%x\n", status);
1377 	rkflash_print_info("read_lines = %x\n", sfc_nand_dev.read_lines);
1378 	rkflash_print_info("prog_lines = %x\n", sfc_nand_dev.prog_lines);
1379 	rkflash_print_info("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd);
1380 	rkflash_print_info("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd);
1381 
1382 	return SFC_OK;
1383 }
1384 
1385 void sfc_nand_deinit(void)
1386 {
1387 	/* to-do */
1388 	kfree(sfc_nand_dev.recheck_buffer);
1389 }
1390 
1391 struct SFNAND_DEV *sfc_nand_get_private_dev(void)
1392 {
1393 	return &sfc_nand_dev;
1394 }
1395 
1396