1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <common.h>
18#include <asm/io.h>
19
20#ifdef DEBUG
21# define pr_stamp() printf("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__)
22#else
23# define pr_stamp()
24#endif
25
26#include <nand.h>
27
28#include <asm/blackfin.h>
29#include <asm/portmux.h>
30
31
32
33#define WR_DLY 0xf
34#define RD_DLY 0xf0
35#define NWIDTH 0x100
36#define PG_SIZE 0x200
37
38
39
40#define NBUSY 0x1
41#define WB_FULL 0x2
42#define PG_WR_STAT 0x4
43#define PG_RD_STAT 0x8
44#define WB_EMPTY 0x10
45
46
47
48#define NBUSYIRQ 0x1
49#define WB_OVF 0x2
50#define WB_EDGE 0x4
51#define RD_RDY 0x8
52#define WR_DONE 0x10
53
54#define NAND_IS_512() (CONFIG_BFIN_NFC_CTL_VAL & 0x200)
55
56
57
58
59static void bfin_nfc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
60{
61 pr_stamp();
62
63 if (cmd == NAND_CMD_NONE)
64 return;
65
66 while (bfin_read_NFC_STAT() & WB_FULL)
67 continue;
68
69 if (ctrl & NAND_CLE)
70 bfin_write_NFC_CMD(cmd);
71 else
72 bfin_write_NFC_ADDR(cmd);
73 SSYNC();
74}
75
76static int bfin_nfc_devready(struct mtd_info *mtd)
77{
78 pr_stamp();
79 return (bfin_read_NFC_STAT() & NBUSY) ? 1 : 0;
80}
81
82
83
84
85static void bfin_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
86{
87 pr_stamp();
88
89 int i;
90
91
92
93
94
95 for (i = 0; i < len; ++i) {
96 while (bfin_read_NFC_STAT() & WB_FULL)
97 if (ctrlc())
98 return;
99
100
101 bfin_write_NFC_DATA_RD(0x0000);
102 SSYNC();
103
104 while (!(bfin_read_NFC_IRQSTAT() & RD_RDY))
105 if (ctrlc())
106 return;
107
108 buf[i] = bfin_read_NFC_READ();
109
110 bfin_write_NFC_IRQSTAT(RD_RDY);
111 }
112}
113
114static uint8_t bfin_nfc_read_byte(struct mtd_info *mtd)
115{
116 pr_stamp();
117
118 uint8_t val;
119 bfin_nfc_read_buf(mtd, &val, 1);
120 return val;
121}
122
123static void bfin_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
124{
125 pr_stamp();
126
127 int i;
128
129 for (i = 0; i < len; ++i) {
130 while (bfin_read_NFC_STAT() & WB_FULL)
131 if (ctrlc())
132 return;
133
134 bfin_write_NFC_DATA_WR(buf[i]);
135 }
136
137
138 while (!(bfin_read_NFC_STAT() & WB_EMPTY))
139 if (ctrlc())
140 return;
141}
142
143
144
145
146
147
148
149
150
151
152static int bfin_nfc_correct_data_256(struct mtd_info *mtd, u_char *dat,
153 u_char *read_ecc, u_char *calc_ecc)
154{
155 u32 syndrome[5];
156 u32 calced, stored;
157 unsigned short failing_bit, failing_byte;
158 u_char data;
159
160 pr_stamp();
161
162 calced = calc_ecc[0] | (calc_ecc[1] << 8) | (calc_ecc[2] << 16);
163 stored = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16);
164
165 syndrome[0] = (calced ^ stored);
166
167
168
169
170
171
172 if (!syndrome[0] || !calced || !stored)
173 return 0;
174
175
176
177
178
179
180 if (hweight32(syndrome[0]) == 1)
181 return 1;
182
183 syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF);
184 syndrome[2] = (calced & 0x7FF) ^ ((calced >> 11) & 0x7FF);
185 syndrome[3] = (stored & 0x7FF) ^ ((stored >> 11) & 0x7FF);
186 syndrome[4] = syndrome[2] ^ syndrome[3];
187
188
189
190
191
192
193
194 if (hweight32(syndrome[0]) == 11 && syndrome[4] == 0x7FF) {
195 failing_bit = syndrome[1] & 0x7;
196 failing_byte = syndrome[1] >> 0x3;
197 data = *(dat + failing_byte);
198 data = data ^ (0x1 << failing_bit);
199 *(dat + failing_byte) = data;
200
201 return 0;
202 }
203
204
205
206
207
208
209
210 return 1;
211}
212
213static int bfin_nfc_correct_data(struct mtd_info *mtd, u_char *dat,
214 u_char *read_ecc, u_char *calc_ecc)
215{
216 int ret;
217
218 pr_stamp();
219
220 ret = bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc);
221
222
223 if (NAND_IS_512()) {
224 dat += 256;
225 read_ecc += 8;
226 calc_ecc += 8;
227 ret |= bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc);
228 }
229
230 return ret;
231}
232
233static void reset_ecc(void)
234{
235 bfin_write_NFC_RST(0x1);
236 while (bfin_read_NFC_RST() & 1)
237 continue;
238}
239
240static void bfin_nfc_enable_hwecc(struct mtd_info *mtd, int mode)
241{
242 reset_ecc();
243}
244
245static int bfin_nfc_calculate_ecc(struct mtd_info *mtd,
246 const u_char *dat, u_char *ecc_code)
247{
248 u16 ecc0, ecc1;
249 u32 code[2];
250 u8 *p;
251
252 pr_stamp();
253
254
255 ecc0 = bfin_read_NFC_ECC0();
256 ecc1 = bfin_read_NFC_ECC1();
257
258 code[0] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11);
259
260
261 p = (u8 *) code;
262 memcpy(ecc_code, p, 3);
263
264
265 if (NAND_IS_512()) {
266 ecc0 = bfin_read_NFC_ECC2();
267 ecc1 = bfin_read_NFC_ECC3();
268 code[1] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11);
269
270
271
272
273 p = (u8 *) (code + 1);
274 memcpy((ecc_code + 3), p, 3);
275 }
276
277 reset_ecc();
278
279 return 0;
280}
281
282#ifdef CONFIG_BFIN_NFC_BOOTROM_ECC
283# define BOOTROM_ECC 1
284#else
285# define BOOTROM_ECC 0
286#endif
287
288static uint8_t bbt_pattern[] = { 0xff };
289
290static struct nand_bbt_descr bootrom_bbt = {
291 .options = 0,
292 .offs = 63,
293 .len = 1,
294 .pattern = bbt_pattern,
295};
296
297static struct nand_ecclayout bootrom_ecclayout = {
298 .eccbytes = 24,
299 .eccpos = {
300 0x8 * 0, 0x8 * 0 + 1, 0x8 * 0 + 2,
301 0x8 * 1, 0x8 * 1 + 1, 0x8 * 1 + 2,
302 0x8 * 2, 0x8 * 2 + 1, 0x8 * 2 + 2,
303 0x8 * 3, 0x8 * 3 + 1, 0x8 * 3 + 2,
304 0x8 * 4, 0x8 * 4 + 1, 0x8 * 4 + 2,
305 0x8 * 5, 0x8 * 5 + 1, 0x8 * 5 + 2,
306 0x8 * 6, 0x8 * 6 + 1, 0x8 * 6 + 2,
307 0x8 * 7, 0x8 * 7 + 1, 0x8 * 7 + 2
308 },
309 .oobfree = {
310 { 0x8 * 0 + 3, 5 },
311 { 0x8 * 1 + 3, 5 },
312 { 0x8 * 2 + 3, 5 },
313 { 0x8 * 3 + 3, 5 },
314 { 0x8 * 4 + 3, 5 },
315 { 0x8 * 5 + 3, 5 },
316 { 0x8 * 6 + 3, 5 },
317 { 0x8 * 7 + 3, 5 },
318 }
319};
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339int board_nand_init(struct nand_chip *chip)
340{
341 const unsigned short pins[] = {
342 P_NAND_CE, P_NAND_RB, P_NAND_D0, P_NAND_D1, P_NAND_D2,
343 P_NAND_D3, P_NAND_D4, P_NAND_D5, P_NAND_D6, P_NAND_D7,
344 P_NAND_WE, P_NAND_RE, P_NAND_CLE, P_NAND_ALE, 0,
345 };
346
347 pr_stamp();
348
349
350 bfin_write_NFC_CTL(CONFIG_BFIN_NFC_CTL_VAL);
351
352
353 bfin_write_NFC_IRQMASK(0x0);
354 bfin_write_NFC_IRQSTAT(0xffff);
355
356
357 peripheral_request_list(pins, "bfin_nand");
358
359 chip->cmd_ctrl = bfin_nfc_cmd_ctrl;
360 chip->read_buf = bfin_nfc_read_buf;
361 chip->write_buf = bfin_nfc_write_buf;
362 chip->read_byte = bfin_nfc_read_byte;
363
364#ifdef CONFIG_BFIN_NFC_NO_HW_ECC
365# define ECC_HW 0
366#else
367# define ECC_HW 1
368#endif
369 if (ECC_HW) {
370 if (BOOTROM_ECC) {
371 chip->badblock_pattern = &bootrom_bbt;
372 chip->ecc.layout = &bootrom_ecclayout;
373 }
374 if (!NAND_IS_512()) {
375 chip->ecc.bytes = 3;
376 chip->ecc.size = 256;
377 } else {
378 chip->ecc.bytes = 6;
379 chip->ecc.size = 512;
380 }
381 chip->ecc.mode = NAND_ECC_HW;
382 chip->ecc.calculate = bfin_nfc_calculate_ecc;
383 chip->ecc.correct = bfin_nfc_correct_data;
384 chip->ecc.hwctl = bfin_nfc_enable_hwecc;
385 } else
386 chip->ecc.mode = NAND_ECC_SOFT;
387 chip->dev_ready = bfin_nfc_devready;
388 chip->chip_delay = 0;
389
390 return 0;
391}
392