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
sfc_nand_get_info(u8 * nand_id)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
sfc_nand_write_en(void)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
sfc_nand_rw_preset(void)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
sfc_nand_read_feature(u8 addr,u8 * data)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
sfc_nand_write_feature(u32 addr,u8 status)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
sfc_nand_wait_busy(u8 * data,int timeout)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 */
sfc_nand_get_ecc_status0(void)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 */
sfc_nand_get_ecc_status1(void)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 */
sfc_nand_get_ecc_status2(void)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 */
sfc_nand_get_ecc_status3(void)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 */
sfc_nand_get_ecc_status4(void)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 */
sfc_nand_get_ecc_status5(void)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 */
sfc_nand_get_ecc_status6(void)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 */
sfc_nand_get_ecc_status7(void)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 */
sfc_nand_get_ecc_status8(void)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 */
sfc_nand_get_ecc_status9(void)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 */
sfc_nand_get_ecc_status10(void)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 */
sfc_nand_get_ecc_status11(void)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
sfc_nand_erase_block(u8 cs,u32 addr)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
sfc_nand_read_cache(u32 row,u32 * p_page_buf,u32 column,u32 len)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
sfc_nand_prog_page_raw(u8 cs,u32 addr,u32 * p_page_buf)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
sfc_nand_prog_page(u8 cs,u32 addr,u32 * p_data,u32 * p_spare)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
sfc_nand_read(u32 row,u32 * p_page_buf,u32 column,u32 len)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
sfc_nand_read_page_raw(u8 cs,u32 addr,u32 * p_page_buf)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
sfc_nand_read_page(u8 cs,u32 addr,u32 * p_data,u32 * p_spare)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
sfc_nand_check_bad_block(u8 cs,u32 addr)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
sfc_nand_mark_bad_block(u8 cs,u32 addr)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
sfc_nand_read_id(u8 * data)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 */
sfc_nand_get_bad_block_list(u16 * table,u32 die)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
sfc_nand_ftl_ops_init(void)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
sfc_nand_enable_QE(void)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
sfc_nand_init(void)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
sfc_nand_deinit(void)1385 void sfc_nand_deinit(void)
1386 {
1387 /* to-do */
1388 kfree(sfc_nand_dev.recheck_buffer);
1389 }
1390
sfc_nand_get_private_dev(void)1391 struct SFNAND_DEV *sfc_nand_get_private_dev(void)
1392 {
1393 return &sfc_nand_dev;
1394 }
1395
1396