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