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