]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/nand/bfin_nand.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / drivers / mtd / nand / bfin_nand.c
1 /*
2  * Driver for Blackfin on-chip NAND controller.
3  *
4  * Enter bugs at http://blackfin.uclinux.org/
5  *
6  * Copyright (c) 2007-2008 Analog Devices Inc.
7  *
8  * Licensed under the GPL-2 or later.
9  */
10
11 /* TODO:
12  * - move bit defines into mach-common/bits/nand.h
13  * - try and replace all IRQSTAT usage with STAT polling
14  * - have software ecc mode use same algo as hw ecc ?
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
30 /* Bit masks for NFC_CTL */
31
32 #define                    WR_DLY  0xf        /* Write Strobe Delay */
33 #define                    RD_DLY  0xf0       /* Read Strobe Delay */
34 #define                    NWIDTH  0x100      /* NAND Data Width */
35 #define                   PG_SIZE  0x200      /* Page Size */
36
37 /* Bit masks for NFC_STAT */
38
39 #define                     NBUSY  0x1        /* Not Busy */
40 #define                   WB_FULL  0x2        /* Write Buffer Full */
41 #define                PG_WR_STAT  0x4        /* Page Write Pending */
42 #define                PG_RD_STAT  0x8        /* Page Read Pending */
43 #define                  WB_EMPTY  0x10       /* Write Buffer Empty */
44
45 /* Bit masks for NFC_IRQSTAT */
46
47 #define                  NBUSYIRQ  0x1        /* Not Busy IRQ */
48 #define                    WB_OVF  0x2        /* Write Buffer Overflow */
49 #define                   WB_EDGE  0x4        /* Write Buffer Edge Detect */
50 #define                    RD_RDY  0x8        /* Read Data Ready */
51 #define                   WR_DONE  0x10       /* Page Write Done */
52
53 #define NAND_IS_512() (CONFIG_BFIN_NFC_CTL_VAL & 0x200)
54
55 /*
56  * hardware specific access to control-lines
57  */
58 static void bfin_nfc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
59 {
60         pr_stamp();
61
62         if (cmd == NAND_CMD_NONE)
63                 return;
64
65         while (bfin_read_NFC_STAT() & WB_FULL)
66                 continue;
67
68         if (ctrl & NAND_CLE)
69                 bfin_write_NFC_CMD(cmd);
70         else
71                 bfin_write_NFC_ADDR(cmd);
72         SSYNC();
73 }
74
75 int bfin_nfc_devready(struct mtd_info *mtd)
76 {
77         pr_stamp();
78         return (bfin_read_NFC_STAT() & NBUSY ? 1 : 0);
79 }
80
81 /*
82  * PIO mode for buffer writing and reading
83  */
84 static void bfin_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
85 {
86         pr_stamp();
87
88         int i;
89
90         /*
91          * Data reads are requested by first writing to NFC_DATA_RD
92         * and then reading back from NFC_READ.
93         */
94         for (i = 0; i < len; ++i) {
95                 while (bfin_read_NFC_STAT() & WB_FULL)
96                         if (ctrlc())
97                                 return;
98
99                 /* Contents do not matter */
100                 bfin_write_NFC_DATA_RD(0x0000);
101                 SSYNC();
102
103                 while (!(bfin_read_NFC_IRQSTAT() & RD_RDY))
104                         if (ctrlc())
105                                 return;
106
107                 buf[i] = bfin_read_NFC_READ();
108
109                 bfin_write_NFC_IRQSTAT(RD_RDY);
110         }
111 }
112
113 static uint8_t bfin_nfc_read_byte(struct mtd_info *mtd)
114 {
115         pr_stamp();
116
117         uint8_t val;
118         bfin_nfc_read_buf(mtd, &val, 1);
119         return val;
120 }
121
122 static void bfin_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
123 {
124         pr_stamp();
125
126         int i;
127
128         for (i = 0; i < len; ++i) {
129                 while (bfin_read_NFC_STAT() & WB_FULL)
130                         if (ctrlc())
131                                 return;
132
133                 bfin_write_NFC_DATA_WR(buf[i]);
134         }
135 }
136
137 /*
138  * ECC functions
139  * These allow the bfin to use the controller's ECC
140  * generator block to ECC the data as it passes through
141  */
142
143 /*
144  * ECC error correction function
145  */
146 static int bfin_nfc_correct_data_256(struct mtd_info *mtd, u_char *dat,
147                                         u_char *read_ecc, u_char *calc_ecc)
148 {
149         u32 syndrome[5];
150         u32 calced, stored;
151         unsigned short failing_bit, failing_byte;
152         u_char data;
153
154         pr_stamp();
155
156         calced = calc_ecc[0] | (calc_ecc[1] << 8) | (calc_ecc[2] << 16);
157         stored = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16);
158
159         syndrome[0] = (calced ^ stored);
160
161         /*
162          * syndrome 0: all zero
163          * No error in data
164          * No action
165          */
166         if (!syndrome[0] || !calced || !stored)
167                 return 0;
168
169         /*
170          * sysdrome 0: only one bit is one
171          * ECC data was incorrect
172          * No action
173          */
174         if (hweight32(syndrome[0]) == 1)
175                 return 1;
176
177         syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF);
178         syndrome[2] = (calced & 0x7FF) ^ ((calced >> 11) & 0x7FF);
179         syndrome[3] = (stored & 0x7FF) ^ ((stored >> 11) & 0x7FF);
180         syndrome[4] = syndrome[2] ^ syndrome[3];
181
182         /*
183          * sysdrome 0: exactly 11 bits are one, each parity
184          * and parity' pair is 1 & 0 or 0 & 1.
185          * 1-bit correctable error
186          * Correct the error
187          */
188         if (hweight32(syndrome[0]) == 11 && syndrome[4] == 0x7FF) {
189                 failing_bit = syndrome[1] & 0x7;
190                 failing_byte = syndrome[1] >> 0x3;
191                 data = *(dat + failing_byte);
192                 data = data ^ (0x1 << failing_bit);
193                 *(dat + failing_byte) = data;
194
195                 return 0;
196         }
197
198         /*
199          * sysdrome 0: random data
200          * More than 1-bit error, non-correctable error
201          * Discard data, mark bad block
202          */
203
204         return 1;
205 }
206
207 static int bfin_nfc_correct_data(struct mtd_info *mtd, u_char *dat,
208                                         u_char *read_ecc, u_char *calc_ecc)
209 {
210         int ret;
211
212         pr_stamp();
213
214         ret = bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc);
215
216         /* If page size is 512, correct second 256 bytes */
217         if (NAND_IS_512()) {
218                 dat += 256;
219                 read_ecc += 8;
220                 calc_ecc += 8;
221                 ret |= bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc);
222         }
223
224         return ret;
225 }
226
227 static void reset_ecc(void)
228 {
229         bfin_write_NFC_RST(0x1);
230         while (bfin_read_NFC_RST() & 1)
231                 continue;
232 }
233
234 static void bfin_nfc_enable_hwecc(struct mtd_info *mtd, int mode)
235 {
236         reset_ecc();
237 }
238
239 static int bfin_nfc_calculate_ecc(struct mtd_info *mtd,
240                 const u_char *dat, u_char *ecc_code)
241 {
242         u16 ecc0, ecc1;
243         u32 code[2];
244         u8 *p;
245
246         pr_stamp();
247
248         /* first 4 bytes ECC code for 256 page size */
249         ecc0 = bfin_read_NFC_ECC0();
250         ecc1 = bfin_read_NFC_ECC1();
251
252         code[0] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11);
253
254         /* first 3 bytes in ecc_code for 256 page size */
255         p = (u8 *) code;
256         memcpy(ecc_code, p, 3);
257
258         /* second 4 bytes ECC code for 512 page size */
259         if (NAND_IS_512()) {
260                 ecc0 = bfin_read_NFC_ECC2();
261                 ecc1 = bfin_read_NFC_ECC3();
262                 code[1] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11);
263
264                 /* second 3 bytes in ecc_code for second 256
265                  * bytes of 512 page size
266                  */
267                 p = (u8 *) (code + 1);
268                 memcpy((ecc_code + 3), p, 3);
269         }
270
271         reset_ecc();
272
273         return 0;
274 }
275
276 #ifdef CONFIG_BFIN_NFC_BOOTROM_ECC
277 # define BOOTROM_ECC 1
278 #else
279 # define BOOTROM_ECC 0
280 #endif
281
282 static uint8_t bbt_pattern[] = { 0xff };
283
284 static struct nand_bbt_descr bootrom_bbt = {
285         .options = 0,
286         .offs = 63,
287         .len = 1,
288         .pattern = bbt_pattern,
289 };
290
291 static struct nand_ecclayout bootrom_ecclayout = {
292         .eccbytes = 24,
293         .eccpos = {
294                 0x8 * 0, 0x8 * 0 + 1, 0x8 * 0 + 2,
295                 0x8 * 1, 0x8 * 1 + 1, 0x8 * 1 + 2,
296                 0x8 * 2, 0x8 * 2 + 1, 0x8 * 2 + 2,
297                 0x8 * 3, 0x8 * 3 + 1, 0x8 * 3 + 2,
298                 0x8 * 4, 0x8 * 4 + 1, 0x8 * 4 + 2,
299                 0x8 * 5, 0x8 * 5 + 1, 0x8 * 5 + 2,
300                 0x8 * 6, 0x8 * 6 + 1, 0x8 * 6 + 2,
301                 0x8 * 7, 0x8 * 7 + 1, 0x8 * 7 + 2
302         },
303         .oobfree = {
304                 { 0x8 * 0 + 3, 5 },
305                 { 0x8 * 1 + 3, 5 },
306                 { 0x8 * 2 + 3, 5 },
307                 { 0x8 * 3 + 3, 5 },
308                 { 0x8 * 4 + 3, 5 },
309                 { 0x8 * 5 + 3, 5 },
310                 { 0x8 * 6 + 3, 5 },
311                 { 0x8 * 7 + 3, 5 },
312         }
313 };
314
315 /*
316  * Board-specific NAND initialization. The following members of the
317  * argument are board-specific (per include/linux/mtd/nand.h):
318  * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
319  * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
320  * - cmd_ctrl: hardwarespecific function for accesing control-lines
321  * - dev_ready: hardwarespecific function for  accesing device ready/busy line
322  * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
323  *   only be provided if a hardware ECC is available
324  * - ecc.mode: mode of ecc, see defines
325  * - chip_delay: chip dependent delay for transfering data from array to
326  *   read regs (tR)
327  * - options: various chip options. They can partly be set to inform
328  *   nand_scan about special functionality. See the defines for further
329  *   explanation
330  * Members with a "?" were not set in the merged testing-NAND branch,
331  * so they are not set here either.
332  */
333 int board_nand_init(struct nand_chip *chip)
334 {
335         pr_stamp();
336
337         /* set width/ecc/timings/etc... */
338         bfin_write_NFC_CTL(CONFIG_BFIN_NFC_CTL_VAL);
339
340         /* clear interrupt status */
341         bfin_write_NFC_IRQMASK(0x0);
342         bfin_write_NFC_IRQSTAT(0xffff);
343
344         /* enable GPIO function enable register */
345 #ifdef __ADSPBF54x__
346         bfin_write_PORTJ_FER(bfin_read_PORTJ_FER() | 6);
347 #elif defined(__ADSPBF52x__)
348         bfin_write_PORTH_FER(bfin_read_PORTH_FER() | 0xFCFF);
349         bfin_write_PORTH_MUX(0);
350 #else
351 # error no support for this variant
352 #endif
353
354         chip->cmd_ctrl = bfin_nfc_cmd_ctrl;
355         chip->read_buf = bfin_nfc_read_buf;
356         chip->write_buf = bfin_nfc_write_buf;
357         chip->read_byte = bfin_nfc_read_byte;
358
359 #ifdef CONFIG_BFIN_NFC_NO_HW_ECC
360 # define ECC_HW 0
361 #else
362 # define ECC_HW 1
363 #endif
364         if (ECC_HW) {
365                 if (BOOTROM_ECC) {
366                         chip->badblock_pattern = &bootrom_bbt;
367                         chip->ecc.layout = &bootrom_ecclayout;
368                 }
369                 if (!NAND_IS_512()) {
370                         chip->ecc.bytes = 3;
371                         chip->ecc.size = 256;
372                 } else {
373                         chip->ecc.bytes = 6;
374                         chip->ecc.size = 512;
375                 }
376                 chip->ecc.mode = NAND_ECC_HW;
377                 chip->ecc.calculate = bfin_nfc_calculate_ecc;
378                 chip->ecc.correct   = bfin_nfc_correct_data;
379                 chip->ecc.hwctl     = bfin_nfc_enable_hwecc;
380         } else
381                 chip->ecc.mode = NAND_ECC_SOFT;
382         chip->dev_ready = bfin_nfc_devready;
383         chip->chip_delay = 0;
384
385         return 0;
386 }