]> git.sur5r.net Git - u-boot/blob - drivers/mtd/nand/vf610_nfc.c
f99bdaf94da2be3dc216ff05f9580105a8049163
[u-boot] / drivers / mtd / nand / vf610_nfc.c
1 /*
2  * Copyright 2009-2015 Freescale Semiconductor, Inc. and others
3  *
4  * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
5  * Ported to U-Boot by Stefan Agner
6  * Based on RFC driver posted on Kernel Mailing list by Bill Pringlemeir
7  * Jason ported to M54418TWR and MVFA5.
8  * Authors: Stefan Agner <stefan.agner@toradex.com>
9  *          Bill Pringlemeir <bpringlemeir@nbsps.com>
10  *          Shaohui Xie <b21989@freescale.com>
11  *          Jason Jin <Jason.jin@freescale.com>
12  *
13  * Based on original driver mpc5121_nfc.c.
14  *
15  * SPDX-License-Identifier:     GPL-2.0+
16  *
17  * Limitations:
18  * - Untested on MPC5125 and M54418.
19  * - DMA and pipelining not used.
20  * - 2K pages or less.
21  * - HW ECC: Only 2K page with 64+ OOB.
22  * - HW ECC: Only 24 and 32-bit error correction implemented.
23  */
24
25 #include <common.h>
26 #include <malloc.h>
27
28 #include <linux/mtd/mtd.h>
29 #include <linux/mtd/nand.h>
30 #include <linux/mtd/partitions.h>
31
32 #include <nand.h>
33 #include <errno.h>
34 #include <asm/io.h>
35
36 /* Register Offsets */
37 #define NFC_FLASH_CMD1                  0x3F00
38 #define NFC_FLASH_CMD2                  0x3F04
39 #define NFC_COL_ADDR                    0x3F08
40 #define NFC_ROW_ADDR                    0x3F0c
41 #define NFC_ROW_ADDR_INC                0x3F14
42 #define NFC_FLASH_STATUS1               0x3F18
43 #define NFC_FLASH_STATUS2               0x3F1c
44 #define NFC_CACHE_SWAP                  0x3F28
45 #define NFC_SECTOR_SIZE                 0x3F2c
46 #define NFC_FLASH_CONFIG                0x3F30
47 #define NFC_IRQ_STATUS                  0x3F38
48
49 /* Addresses for NFC MAIN RAM BUFFER areas */
50 #define NFC_MAIN_AREA(n)                ((n) *  0x1000)
51
52 #define PAGE_2K                         0x0800
53 #define OOB_64                          0x0040
54 #define OOB_MAX                         0x0100
55
56 /*
57  * NFC_CMD2[CODE] values. See section:
58  *  - 31.4.7 Flash Command Code Description, Vybrid manual
59  *  - 23.8.6 Flash Command Sequencer, MPC5125 manual
60  *
61  * Briefly these are bitmasks of controller cycles.
62  */
63 #define READ_PAGE_CMD_CODE              0x7EE0
64 #define READ_ONFI_PARAM_CMD_CODE        0x4860
65 #define PROGRAM_PAGE_CMD_CODE           0x7FC0
66 #define ERASE_CMD_CODE                  0x4EC0
67 #define READ_ID_CMD_CODE                0x4804
68 #define RESET_CMD_CODE                  0x4040
69 #define STATUS_READ_CMD_CODE            0x4068
70
71 /* NFC ECC mode define */
72 #define ECC_BYPASS                      0
73 #define ECC_45_BYTE                     6
74 #define ECC_60_BYTE                     7
75
76 /*** Register Mask and bit definitions */
77
78 /* NFC_FLASH_CMD1 Field */
79 #define CMD_BYTE2_MASK                          0xFF000000
80 #define CMD_BYTE2_SHIFT                         24
81
82 /* NFC_FLASH_CM2 Field */
83 #define CMD_BYTE1_MASK                          0xFF000000
84 #define CMD_BYTE1_SHIFT                         24
85 #define CMD_CODE_MASK                           0x00FFFF00
86 #define CMD_CODE_SHIFT                          8
87 #define BUFNO_MASK                              0x00000006
88 #define BUFNO_SHIFT                             1
89 #define START_BIT                               (1<<0)
90
91 /* NFC_COL_ADDR Field */
92 #define COL_ADDR_MASK                           0x0000FFFF
93 #define COL_ADDR_SHIFT                          0
94
95 /* NFC_ROW_ADDR Field */
96 #define ROW_ADDR_MASK                           0x00FFFFFF
97 #define ROW_ADDR_SHIFT                          0
98 #define ROW_ADDR_CHIP_SEL_RB_MASK               0xF0000000
99 #define ROW_ADDR_CHIP_SEL_RB_SHIFT              28
100 #define ROW_ADDR_CHIP_SEL_MASK                  0x0F000000
101 #define ROW_ADDR_CHIP_SEL_SHIFT                 24
102
103 /* NFC_FLASH_STATUS2 Field */
104 #define STATUS_BYTE1_MASK                       0x000000FF
105
106 /* NFC_FLASH_CONFIG Field */
107 #define CONFIG_ECC_SRAM_ADDR_MASK               0x7FC00000
108 #define CONFIG_ECC_SRAM_ADDR_SHIFT              22
109 #define CONFIG_ECC_SRAM_REQ_BIT                 (1<<21)
110 #define CONFIG_DMA_REQ_BIT                      (1<<20)
111 #define CONFIG_ECC_MODE_MASK                    0x000E0000
112 #define CONFIG_ECC_MODE_SHIFT                   17
113 #define CONFIG_FAST_FLASH_BIT                   (1<<16)
114 #define CONFIG_16BIT                            (1<<7)
115 #define CONFIG_BOOT_MODE_BIT                    (1<<6)
116 #define CONFIG_ADDR_AUTO_INCR_BIT               (1<<5)
117 #define CONFIG_BUFNO_AUTO_INCR_BIT              (1<<4)
118 #define CONFIG_PAGE_CNT_MASK                    0xF
119 #define CONFIG_PAGE_CNT_SHIFT                   0
120
121 /* NFC_IRQ_STATUS Field */
122 #define IDLE_IRQ_BIT                            (1<<29)
123 #define IDLE_EN_BIT                             (1<<20)
124 #define CMD_DONE_CLEAR_BIT                      (1<<18)
125 #define IDLE_CLEAR_BIT                          (1<<17)
126
127 #define NFC_TIMEOUT     (1000)
128
129 /*
130  * ECC status - seems to consume 8 bytes (double word). The documented
131  * status byte is located in the lowest byte of the second word (which is
132  * the 4th or 7th byte depending on endianness).
133  * Calculate an offset to store the ECC status at the end of the buffer.
134  */
135 #define ECC_SRAM_ADDR           (PAGE_2K + OOB_MAX - 8)
136
137 #define ECC_STATUS              0x4
138 #define ECC_STATUS_MASK         0x80
139 #define ECC_STATUS_ERR_COUNT    0x3F
140
141 enum vf610_nfc_alt_buf {
142         ALT_BUF_DATA = 0,
143         ALT_BUF_ID = 1,
144         ALT_BUF_STAT = 2,
145         ALT_BUF_ONFI = 3,
146 };
147
148 struct vf610_nfc {
149         struct nand_chip chip;
150         void __iomem *regs;
151         uint buf_offset;
152         int write_sz;
153         /* Status and ID are in alternate locations. */
154         enum vf610_nfc_alt_buf alt_buf;
155 };
156
157 #define mtd_to_nfc(_mtd) nand_get_controller_data(mtd_to_nand(_mtd))
158
159 #if defined(CONFIG_SYS_NAND_VF610_NFC_45_ECC_BYTES)
160 #define ECC_HW_MODE ECC_45_BYTE
161
162 static struct nand_ecclayout vf610_nfc_ecc = {
163         .eccbytes = 45,
164         .eccpos = {19, 20, 21, 22, 23,
165                    24, 25, 26, 27, 28, 29, 30, 31,
166                    32, 33, 34, 35, 36, 37, 38, 39,
167                    40, 41, 42, 43, 44, 45, 46, 47,
168                    48, 49, 50, 51, 52, 53, 54, 55,
169                    56, 57, 58, 59, 60, 61, 62, 63},
170         .oobfree = {
171                 {.offset = 2,
172                  .length = 17} }
173 };
174 #elif defined(CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES)
175 #define ECC_HW_MODE ECC_60_BYTE
176
177 static struct nand_ecclayout vf610_nfc_ecc = {
178         .eccbytes = 60,
179         .eccpos = { 4,  5,  6,  7,  8,  9, 10, 11,
180                    12, 13, 14, 15, 16, 17, 18, 19,
181                    20, 21, 22, 23, 24, 25, 26, 27,
182                    28, 29, 30, 31, 32, 33, 34, 35,
183                    36, 37, 38, 39, 40, 41, 42, 43,
184                    44, 45, 46, 47, 48, 49, 50, 51,
185                    52, 53, 54, 55, 56, 57, 58, 59,
186                    60, 61, 62, 63 },
187         .oobfree = {
188                 {.offset = 2,
189                  .length = 2} }
190 };
191 #endif
192
193 static inline u32 vf610_nfc_read(struct mtd_info *mtd, uint reg)
194 {
195         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
196
197         return readl(nfc->regs + reg);
198 }
199
200 static inline void vf610_nfc_write(struct mtd_info *mtd, uint reg, u32 val)
201 {
202         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
203
204         writel(val, nfc->regs + reg);
205 }
206
207 static inline void vf610_nfc_set(struct mtd_info *mtd, uint reg, u32 bits)
208 {
209         vf610_nfc_write(mtd, reg, vf610_nfc_read(mtd, reg) | bits);
210 }
211
212 static inline void vf610_nfc_clear(struct mtd_info *mtd, uint reg, u32 bits)
213 {
214         vf610_nfc_write(mtd, reg, vf610_nfc_read(mtd, reg) & ~bits);
215 }
216
217 static inline void vf610_nfc_set_field(struct mtd_info *mtd, u32 reg,
218                                        u32 mask, u32 shift, u32 val)
219 {
220         vf610_nfc_write(mtd, reg,
221                         (vf610_nfc_read(mtd, reg) & (~mask)) | val << shift);
222 }
223
224 static inline void vf610_nfc_memcpy(void *dst, const void *src, size_t n)
225 {
226         /*
227          * Use this accessor for the internal SRAM buffers. On the ARM
228          * Freescale Vybrid SoC it's known that the driver can treat
229          * the SRAM buffer as if it's memory. Other platform might need
230          * to treat the buffers differently.
231          *
232          * For the time being, use memcpy
233          */
234         memcpy(dst, src, n);
235 }
236
237 /* Clear flags for upcoming command */
238 static inline void vf610_nfc_clear_status(void __iomem *regbase)
239 {
240         void __iomem *reg = regbase + NFC_IRQ_STATUS;
241         u32 tmp = __raw_readl(reg);
242         tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT;
243         __raw_writel(tmp, reg);
244 }
245
246 /* Wait for complete operation */
247 static void vf610_nfc_done(struct mtd_info *mtd)
248 {
249         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
250         uint start;
251
252         /*
253          * Barrier is needed after this write. This write need
254          * to be done before reading the next register the first
255          * time.
256          * vf610_nfc_set implicates such a barrier by using writel
257          * to write to the register.
258          */
259         vf610_nfc_set(mtd, NFC_FLASH_CMD2, START_BIT);
260
261         start = get_timer(0);
262
263         while (!(vf610_nfc_read(mtd, NFC_IRQ_STATUS) & IDLE_IRQ_BIT)) {
264                 if (get_timer(start) > NFC_TIMEOUT) {
265                         printf("Timeout while waiting for IDLE.\n");
266                         return;
267                 }
268         }
269         vf610_nfc_clear_status(nfc->regs);
270 }
271
272 static u8 vf610_nfc_get_id(struct mtd_info *mtd, int col)
273 {
274         u32 flash_id;
275
276         if (col < 4) {
277                 flash_id = vf610_nfc_read(mtd, NFC_FLASH_STATUS1);
278                 flash_id >>= (3 - col) * 8;
279         } else {
280                 flash_id = vf610_nfc_read(mtd, NFC_FLASH_STATUS2);
281                 flash_id >>= 24;
282         }
283
284         return flash_id & 0xff;
285 }
286
287 static u8 vf610_nfc_get_status(struct mtd_info *mtd)
288 {
289         return vf610_nfc_read(mtd, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
290 }
291
292 /* Single command */
293 static void vf610_nfc_send_command(void __iomem *regbase, u32 cmd_byte1,
294                                    u32 cmd_code)
295 {
296         void __iomem *reg = regbase + NFC_FLASH_CMD2;
297         u32 tmp;
298         vf610_nfc_clear_status(regbase);
299
300         tmp = __raw_readl(reg);
301         tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
302         tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
303         tmp |= cmd_code << CMD_CODE_SHIFT;
304         __raw_writel(tmp, reg);
305 }
306
307 /* Two commands */
308 static void vf610_nfc_send_commands(void __iomem *regbase, u32 cmd_byte1,
309                               u32 cmd_byte2, u32 cmd_code)
310 {
311         void __iomem *reg = regbase + NFC_FLASH_CMD1;
312         u32 tmp;
313         vf610_nfc_send_command(regbase, cmd_byte1, cmd_code);
314
315         tmp = __raw_readl(reg);
316         tmp &= ~CMD_BYTE2_MASK;
317         tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
318         __raw_writel(tmp, reg);
319 }
320
321 static void vf610_nfc_addr_cycle(struct mtd_info *mtd, int column, int page)
322 {
323         if (column != -1) {
324                 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
325                 if (nfc->chip.options & NAND_BUSWIDTH_16)
326                         column = column / 2;
327                 vf610_nfc_set_field(mtd, NFC_COL_ADDR, COL_ADDR_MASK,
328                                     COL_ADDR_SHIFT, column);
329         }
330         if (page != -1)
331                 vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
332                                     ROW_ADDR_SHIFT, page);
333 }
334
335 static inline void vf610_nfc_ecc_mode(struct mtd_info *mtd, int ecc_mode)
336 {
337         vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
338                             CONFIG_ECC_MODE_MASK,
339                             CONFIG_ECC_MODE_SHIFT, ecc_mode);
340 }
341
342 static inline void vf610_nfc_transfer_size(void __iomem *regbase, int size)
343 {
344         __raw_writel(size, regbase + NFC_SECTOR_SIZE);
345 }
346
347 /* Send command to NAND chip */
348 static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
349                               int column, int page)
350 {
351         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
352         int trfr_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
353
354         nfc->buf_offset = max(column, 0);
355         nfc->alt_buf = ALT_BUF_DATA;
356
357         switch (command) {
358         case NAND_CMD_SEQIN:
359                 /* Use valid column/page from preread... */
360                 vf610_nfc_addr_cycle(mtd, column, page);
361                 nfc->buf_offset = 0;
362
363                 /*
364                  * SEQIN => data => PAGEPROG sequence is done by the controller
365                  * hence we do not need to issue the command here...
366                  */
367                 return;
368         case NAND_CMD_PAGEPROG:
369                 trfr_sz += nfc->write_sz;
370                 vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
371                 vf610_nfc_transfer_size(nfc->regs, trfr_sz);
372                 vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
373                                         command, PROGRAM_PAGE_CMD_CODE);
374                 break;
375
376         case NAND_CMD_RESET:
377                 vf610_nfc_transfer_size(nfc->regs, 0);
378                 vf610_nfc_send_command(nfc->regs, command, RESET_CMD_CODE);
379                 break;
380
381         case NAND_CMD_READOOB:
382                 trfr_sz += mtd->oobsize;
383                 column = mtd->writesize;
384                 vf610_nfc_transfer_size(nfc->regs, trfr_sz);
385                 vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
386                                         NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
387                 vf610_nfc_addr_cycle(mtd, column, page);
388                 vf610_nfc_ecc_mode(mtd, ECC_BYPASS);
389                 break;
390
391         case NAND_CMD_READ0:
392                 trfr_sz += mtd->writesize + mtd->oobsize;
393                 vf610_nfc_transfer_size(nfc->regs, trfr_sz);
394                 vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
395                 vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
396                                         NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
397                 vf610_nfc_addr_cycle(mtd, column, page);
398                 break;
399
400         case NAND_CMD_PARAM:
401                 nfc->alt_buf = ALT_BUF_ONFI;
402                 trfr_sz = 3 * sizeof(struct nand_onfi_params);
403                 vf610_nfc_transfer_size(nfc->regs, trfr_sz);
404                 vf610_nfc_send_command(nfc->regs, NAND_CMD_PARAM,
405                                        READ_ONFI_PARAM_CMD_CODE);
406                 vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
407                                     ROW_ADDR_SHIFT, column);
408                 vf610_nfc_ecc_mode(mtd, ECC_BYPASS);
409                 break;
410
411         case NAND_CMD_ERASE1:
412                 vf610_nfc_transfer_size(nfc->regs, 0);
413                 vf610_nfc_send_commands(nfc->regs, command,
414                                         NAND_CMD_ERASE2, ERASE_CMD_CODE);
415                 vf610_nfc_addr_cycle(mtd, column, page);
416                 break;
417
418         case NAND_CMD_READID:
419                 nfc->alt_buf = ALT_BUF_ID;
420                 nfc->buf_offset = 0;
421                 vf610_nfc_transfer_size(nfc->regs, 0);
422                 vf610_nfc_send_command(nfc->regs, command, READ_ID_CMD_CODE);
423                 vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
424                                     ROW_ADDR_SHIFT, column);
425                 break;
426
427         case NAND_CMD_STATUS:
428                 nfc->alt_buf = ALT_BUF_STAT;
429                 vf610_nfc_transfer_size(nfc->regs, 0);
430                 vf610_nfc_send_command(nfc->regs, command, STATUS_READ_CMD_CODE);
431                 break;
432         default:
433                 return;
434         }
435
436         vf610_nfc_done(mtd);
437
438         nfc->write_sz = 0;
439 }
440
441 /* Read data from NFC buffers */
442 static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
443 {
444         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
445         uint c = nfc->buf_offset;
446
447         /* Alternate buffers are only supported through read_byte */
448         if (nfc->alt_buf)
449                 return;
450
451         vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
452
453         nfc->buf_offset += len;
454 }
455
456 /* Write data to NFC buffers */
457 static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
458                                 int len)
459 {
460         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
461         uint c = nfc->buf_offset;
462         uint l;
463
464         l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
465         vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
466
467         nfc->write_sz += l;
468         nfc->buf_offset += l;
469 }
470
471 /* Read byte from NFC buffers */
472 static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
473 {
474         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
475         u8 tmp;
476         uint c = nfc->buf_offset;
477
478         switch (nfc->alt_buf) {
479         case ALT_BUF_ID:
480                 tmp = vf610_nfc_get_id(mtd, c);
481                 break;
482         case ALT_BUF_STAT:
483                 tmp = vf610_nfc_get_status(mtd);
484                 break;
485 #ifdef __LITTLE_ENDIAN
486         case ALT_BUF_ONFI:
487                 /* Reverse byte since the controller uses big endianness */
488                 c = nfc->buf_offset ^ 0x3;
489                 /* fall-through */
490 #endif
491         default:
492                 tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
493                 break;
494         }
495         nfc->buf_offset++;
496         return tmp;
497 }
498
499 /* Read word from NFC buffers */
500 static u16 vf610_nfc_read_word(struct mtd_info *mtd)
501 {
502         u16 tmp;
503
504         vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
505         return tmp;
506 }
507
508 /* If not provided, upper layers apply a fixed delay. */
509 static int vf610_nfc_dev_ready(struct mtd_info *mtd)
510 {
511         /* NFC handles R/B internally; always ready.  */
512         return 1;
513 }
514
515 /*
516  * This function supports Vybrid only (MPC5125 would have full RB and four CS)
517  */
518 static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
519 {
520 #ifdef CONFIG_VF610
521         u32 tmp = vf610_nfc_read(mtd, NFC_ROW_ADDR);
522         tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
523
524         if (chip >= 0) {
525                 tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
526                 tmp |= (1 << chip) << ROW_ADDR_CHIP_SEL_SHIFT;
527         }
528
529         vf610_nfc_write(mtd, NFC_ROW_ADDR, tmp);
530 #endif
531 }
532
533 /* Count the number of 0's in buff upto max_bits */
534 static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
535 {
536         uint32_t *buff32 = (uint32_t *)buff;
537         int k, written_bits = 0;
538
539         for (k = 0; k < (size / 4); k++) {
540                 written_bits += hweight32(~buff32[k]);
541                 if (written_bits > max_bits)
542                         break;
543         }
544
545         return written_bits;
546 }
547
548 static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
549                                          uint8_t *oob, int page)
550 {
551         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
552         u32 ecc_status_off = NFC_MAIN_AREA(0) + ECC_SRAM_ADDR + ECC_STATUS;
553         u8 ecc_status;
554         u8 ecc_count;
555         int flips;
556         int flips_threshold = nfc->chip.ecc.strength / 2;
557
558         ecc_status = vf610_nfc_read(mtd, ecc_status_off) & 0xff;
559         ecc_count = ecc_status & ECC_STATUS_ERR_COUNT;
560
561         if (!(ecc_status & ECC_STATUS_MASK))
562                 return ecc_count;
563
564         /* Read OOB without ECC unit enabled */
565         vf610_nfc_command(mtd, NAND_CMD_READOOB, 0, page);
566         vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
567
568         /*
569          * On an erased page, bit count (including OOB) should be zero or
570          * at least less then half of the ECC strength.
571          */
572         flips = count_written_bits(dat, nfc->chip.ecc.size, flips_threshold);
573         flips += count_written_bits(oob, mtd->oobsize, flips_threshold);
574
575         if (unlikely(flips > flips_threshold))
576                 return -EINVAL;
577
578         /* Erased page. */
579         memset(dat, 0xff, nfc->chip.ecc.size);
580         memset(oob, 0xff, mtd->oobsize);
581         return flips;
582 }
583
584 static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
585                                 uint8_t *buf, int oob_required, int page)
586 {
587         int eccsize = chip->ecc.size;
588         int stat;
589
590         vf610_nfc_read_buf(mtd, buf, eccsize);
591         if (oob_required)
592                 vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
593
594         stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
595
596         if (stat < 0) {
597                 mtd->ecc_stats.failed++;
598                 return 0;
599         } else {
600                 mtd->ecc_stats.corrected += stat;
601                 return stat;
602         }
603 }
604
605 /*
606  * ECC will be calculated automatically
607  */
608 static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
609                                const uint8_t *buf, int oob_required, int page)
610 {
611         struct vf610_nfc *nfc = mtd_to_nfc(mtd);
612
613         vf610_nfc_write_buf(mtd, buf, mtd->writesize);
614         if (oob_required)
615                 vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
616
617         /* Always write whole page including OOB due to HW ECC */
618         nfc->write_sz = mtd->writesize + mtd->oobsize;
619
620         return 0;
621 }
622
623 struct vf610_nfc_config {
624         int hardware_ecc;
625         int width;
626         int flash_bbt;
627 };
628
629 static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
630 {
631         struct mtd_info *mtd;
632         struct nand_chip *chip;
633         struct vf610_nfc *nfc;
634         int err = 0;
635         struct vf610_nfc_config cfg = {
636                 .hardware_ecc = 1,
637 #ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT
638                 .width = 16,
639 #else
640                 .width = 8,
641 #endif
642                 .flash_bbt = 1,
643         };
644
645         nfc = malloc(sizeof(*nfc));
646         if (!nfc) {
647                 printf(KERN_ERR "%s: Memory exhausted!\n", __func__);
648                 return -ENOMEM;
649         }
650
651         chip = &nfc->chip;
652         nfc->regs = addr;
653
654         mtd = nand_to_mtd(chip);
655         nand_set_controller_data(chip, nfc);
656
657         if (cfg.width == 16)
658                 chip->options |= NAND_BUSWIDTH_16;
659
660         chip->dev_ready = vf610_nfc_dev_ready;
661         chip->cmdfunc = vf610_nfc_command;
662         chip->read_byte = vf610_nfc_read_byte;
663         chip->read_word = vf610_nfc_read_word;
664         chip->read_buf = vf610_nfc_read_buf;
665         chip->write_buf = vf610_nfc_write_buf;
666         chip->select_chip = vf610_nfc_select_chip;
667
668         chip->options |= NAND_NO_SUBPAGE_WRITE;
669
670         chip->ecc.size = PAGE_2K;
671
672         /* Set configuration register. */
673         vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
674         vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
675         vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
676         vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT);
677         vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
678         vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
679
680         /* Disable virtual pages, only one elementary transfer unit */
681         vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
682                             CONFIG_PAGE_CNT_SHIFT, 1);
683
684         /* first scan to find the device and get the page size */
685         if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL)) {
686                 err = -ENXIO;
687                 goto error;
688         }
689
690         if (cfg.width == 16)
691                 vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
692
693         /* Bad block options. */
694         if (cfg.flash_bbt)
695                 chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB |
696                                     NAND_BBT_CREATE;
697
698         /* Single buffer only, max 256 OOB minus ECC status */
699         if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
700                 dev_err(nfc->dev, "Unsupported flash page size\n");
701                 err = -ENXIO;
702                 goto error;
703         }
704
705         if (cfg.hardware_ecc) {
706                 if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
707                         dev_err(nfc->dev, "Unsupported flash with hwecc\n");
708                         err = -ENXIO;
709                         goto error;
710                 }
711
712                 if (chip->ecc.size != mtd->writesize) {
713                         dev_err(nfc->dev, "ecc size: %d\n", chip->ecc.size);
714                         dev_err(nfc->dev, "Step size needs to be page size\n");
715                         err = -ENXIO;
716                         goto error;
717                 }
718
719                 /* Current HW ECC layouts only use 64 bytes of OOB */
720                 if (mtd->oobsize > 64)
721                         mtd->oobsize = 64;
722
723                 /* propagate ecc.layout to mtd_info */
724                 mtd->ecclayout = chip->ecc.layout;
725                 chip->ecc.read_page = vf610_nfc_read_page;
726                 chip->ecc.write_page = vf610_nfc_write_page;
727                 chip->ecc.mode = NAND_ECC_HW;
728
729                 chip->ecc.size = PAGE_2K;
730                 chip->ecc.layout = &vf610_nfc_ecc;
731 #if defined(CONFIG_SYS_NAND_VF610_NFC_45_ECC_BYTES)
732                 chip->ecc.strength = 24;
733                 chip->ecc.bytes = 45;
734 #elif defined(CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES)
735                 chip->ecc.strength = 32;
736                 chip->ecc.bytes = 60;
737 #endif
738
739                 /* Set ECC_STATUS offset */
740                 vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
741                                     CONFIG_ECC_SRAM_ADDR_MASK,
742                                     CONFIG_ECC_SRAM_ADDR_SHIFT,
743                                     ECC_SRAM_ADDR >> 3);
744
745                 /* Enable ECC status in SRAM */
746                 vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
747         }
748
749         /* second phase scan */
750         err = nand_scan_tail(mtd);
751         if (err)
752                 return err;
753
754         err = nand_register(devnum, mtd);
755         if (err)
756                 return err;
757
758         return 0;
759
760 error:
761         return err;
762 }
763
764 void board_nand_init(void)
765 {
766         int err = vf610_nfc_nand_init(0, (void __iomem *)CONFIG_SYS_NAND_BASE);
767         if (err)
768                 printf("VF610 NAND init failed (err %d)\n", err);
769 }