blob: 49b63af85ddfecec30a9fd2a6958e7b761444bd3 [file] [log] [blame]
Dipen Dudhat52f90da2011-03-22 09:27:39 +05301/* Integrated Flash Controller NAND Machine Driver
2 *
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +05303 * Copyright (c) 2012 Freescale Semiconductor, Inc
Dipen Dudhat52f90da2011-03-22 09:27:39 +05304 *
5 * Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com>
6 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Dipen Dudhat52f90da2011-03-22 09:27:39 +05308 */
9
10#include <common.h>
11#include <malloc.h>
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +000012#include <nand.h>
Dipen Dudhat52f90da2011-03-22 09:27:39 +053013
14#include <linux/mtd/mtd.h>
15#include <linux/mtd/nand.h>
16#include <linux/mtd/nand_ecc.h>
17
18#include <asm/io.h>
19#include <asm/errno.h>
20#include <asm/fsl_ifc.h>
21
Prabhakar Kushwaha79da5e32012-09-12 22:26:05 +000022#define FSL_IFC_V1_1_0 0x01010000
Dipen Dudhat52f90da2011-03-22 09:27:39 +053023#define MAX_BANKS 4
24#define ERR_BYTE 0xFF /* Value returned for read bytes
25 when read failed */
26#define IFC_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for IFC
27 NAND Machine */
28
29struct fsl_ifc_ctrl;
30
31/* mtd information per set */
32struct fsl_ifc_mtd {
Dipen Dudhat52f90da2011-03-22 09:27:39 +053033 struct nand_chip chip;
34 struct fsl_ifc_ctrl *ctrl;
35
36 struct device *dev;
37 int bank; /* Chip select bank number */
38 unsigned int bufnum_mask; /* bufnum = page & bufnum_mask */
39 u8 __iomem *vbase; /* Chip select base virtual address */
40};
41
42/* overview of the fsl ifc controller */
43struct fsl_ifc_ctrl {
44 struct nand_hw_control controller;
45 struct fsl_ifc_mtd *chips[MAX_BANKS];
46
47 /* device info */
48 struct fsl_ifc *regs;
49 uint8_t __iomem *addr; /* Address of assigned IFC buffer */
50 unsigned int cs_nand; /* On which chipsel NAND is connected */
51 unsigned int page; /* Last page written to / read from */
52 unsigned int read_bytes; /* Number of bytes read during command */
53 unsigned int column; /* Saved column from SEQIN */
54 unsigned int index; /* Pointer to next byte to 'read' */
55 unsigned int status; /* status read from NEESR after last op */
56 unsigned int oob; /* Non zero if operating on OOB data */
57 unsigned int eccread; /* Non zero for a full-page ECC read */
58};
59
60static struct fsl_ifc_ctrl *ifc_ctrl;
61
62/* 512-byte page with 4-bit ECC, 8-bit */
63static struct nand_ecclayout oob_512_8bit_ecc4 = {
64 .eccbytes = 8,
65 .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
66 .oobfree = { {0, 5}, {6, 2} },
67};
68
69/* 512-byte page with 4-bit ECC, 16-bit */
70static struct nand_ecclayout oob_512_16bit_ecc4 = {
71 .eccbytes = 8,
72 .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
73 .oobfree = { {2, 6}, },
74};
75
76/* 2048-byte page size with 4-bit ECC */
77static struct nand_ecclayout oob_2048_ecc4 = {
78 .eccbytes = 32,
79 .eccpos = {
80 8, 9, 10, 11, 12, 13, 14, 15,
81 16, 17, 18, 19, 20, 21, 22, 23,
82 24, 25, 26, 27, 28, 29, 30, 31,
83 32, 33, 34, 35, 36, 37, 38, 39,
84 },
85 .oobfree = { {2, 6}, {40, 24} },
86};
87
88/* 4096-byte page size with 4-bit ECC */
89static struct nand_ecclayout oob_4096_ecc4 = {
90 .eccbytes = 64,
91 .eccpos = {
92 8, 9, 10, 11, 12, 13, 14, 15,
93 16, 17, 18, 19, 20, 21, 22, 23,
94 24, 25, 26, 27, 28, 29, 30, 31,
95 32, 33, 34, 35, 36, 37, 38, 39,
96 40, 41, 42, 43, 44, 45, 46, 47,
97 48, 49, 50, 51, 52, 53, 54, 55,
98 56, 57, 58, 59, 60, 61, 62, 63,
99 64, 65, 66, 67, 68, 69, 70, 71,
100 },
101 .oobfree = { {2, 6}, {72, 56} },
102};
103
104/* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */
105static struct nand_ecclayout oob_4096_ecc8 = {
106 .eccbytes = 128,
107 .eccpos = {
108 8, 9, 10, 11, 12, 13, 14, 15,
109 16, 17, 18, 19, 20, 21, 22, 23,
110 24, 25, 26, 27, 28, 29, 30, 31,
111 32, 33, 34, 35, 36, 37, 38, 39,
112 40, 41, 42, 43, 44, 45, 46, 47,
113 48, 49, 50, 51, 52, 53, 54, 55,
114 56, 57, 58, 59, 60, 61, 62, 63,
115 64, 65, 66, 67, 68, 69, 70, 71,
116 72, 73, 74, 75, 76, 77, 78, 79,
117 80, 81, 82, 83, 84, 85, 86, 87,
118 88, 89, 90, 91, 92, 93, 94, 95,
119 96, 97, 98, 99, 100, 101, 102, 103,
120 104, 105, 106, 107, 108, 109, 110, 111,
121 112, 113, 114, 115, 116, 117, 118, 119,
122 120, 121, 122, 123, 124, 125, 126, 127,
123 128, 129, 130, 131, 132, 133, 134, 135,
124 },
125 .oobfree = { {2, 6}, {136, 82} },
126};
127
Prabhakar Kushwaha71220f82013-10-04 10:05:36 +0530128/* 8192-byte page size with 4-bit ECC */
129static struct nand_ecclayout oob_8192_ecc4 = {
130 .eccbytes = 128,
131 .eccpos = {
132 8, 9, 10, 11, 12, 13, 14, 15,
133 16, 17, 18, 19, 20, 21, 22, 23,
134 24, 25, 26, 27, 28, 29, 30, 31,
135 32, 33, 34, 35, 36, 37, 38, 39,
136 40, 41, 42, 43, 44, 45, 46, 47,
137 48, 49, 50, 51, 52, 53, 54, 55,
138 56, 57, 58, 59, 60, 61, 62, 63,
139 64, 65, 66, 67, 68, 69, 70, 71,
140 72, 73, 74, 75, 76, 77, 78, 79,
141 80, 81, 82, 83, 84, 85, 86, 87,
142 88, 89, 90, 91, 92, 93, 94, 95,
143 96, 97, 98, 99, 100, 101, 102, 103,
144 104, 105, 106, 107, 108, 109, 110, 111,
145 112, 113, 114, 115, 116, 117, 118, 119,
146 120, 121, 122, 123, 124, 125, 126, 127,
147 128, 129, 130, 131, 132, 133, 134, 135,
148 },
149 .oobfree = { {2, 6}, {136, 208} },
150};
151
152/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
153static struct nand_ecclayout oob_8192_ecc8 = {
154 .eccbytes = 256,
155 .eccpos = {
156 8, 9, 10, 11, 12, 13, 14, 15,
157 16, 17, 18, 19, 20, 21, 22, 23,
158 24, 25, 26, 27, 28, 29, 30, 31,
159 32, 33, 34, 35, 36, 37, 38, 39,
160 40, 41, 42, 43, 44, 45, 46, 47,
161 48, 49, 50, 51, 52, 53, 54, 55,
162 56, 57, 58, 59, 60, 61, 62, 63,
163 64, 65, 66, 67, 68, 69, 70, 71,
164 72, 73, 74, 75, 76, 77, 78, 79,
165 80, 81, 82, 83, 84, 85, 86, 87,
166 88, 89, 90, 91, 92, 93, 94, 95,
167 96, 97, 98, 99, 100, 101, 102, 103,
168 104, 105, 106, 107, 108, 109, 110, 111,
169 112, 113, 114, 115, 116, 117, 118, 119,
170 120, 121, 122, 123, 124, 125, 126, 127,
171 128, 129, 130, 131, 132, 133, 134, 135,
172 136, 137, 138, 139, 140, 141, 142, 143,
173 144, 145, 146, 147, 148, 149, 150, 151,
174 152, 153, 154, 155, 156, 157, 158, 159,
175 160, 161, 162, 163, 164, 165, 166, 167,
176 168, 169, 170, 171, 172, 173, 174, 175,
177 176, 177, 178, 179, 180, 181, 182, 183,
178 184, 185, 186, 187, 188, 189, 190, 191,
179 192, 193, 194, 195, 196, 197, 198, 199,
180 200, 201, 202, 203, 204, 205, 206, 207,
181 208, 209, 210, 211, 212, 213, 214, 215,
182 216, 217, 218, 219, 220, 221, 222, 223,
183 224, 225, 226, 227, 228, 229, 230, 231,
184 232, 233, 234, 235, 236, 237, 238, 239,
185 240, 241, 242, 243, 244, 245, 246, 247,
186 248, 249, 250, 251, 252, 253, 254, 255,
187 256, 257, 258, 259, 260, 261, 262, 263,
188 },
189 .oobfree = { {2, 6}, {264, 80} },
190};
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530191
192/*
193 * Generic flash bbt descriptors
194 */
195static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
196static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
197
198static struct nand_bbt_descr bbt_main_descr = {
199 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
200 NAND_BBT_2BIT | NAND_BBT_VERSION,
201 .offs = 2, /* 0 on 8-bit small page */
202 .len = 4,
203 .veroffs = 6,
204 .maxblocks = 4,
205 .pattern = bbt_pattern,
206};
207
208static struct nand_bbt_descr bbt_mirror_descr = {
209 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
210 NAND_BBT_2BIT | NAND_BBT_VERSION,
211 .offs = 2, /* 0 on 8-bit small page */
212 .len = 4,
213 .veroffs = 6,
214 .maxblocks = 4,
215 .pattern = mirror_pattern,
216};
217
218/*
219 * Set up the IFC hardware block and page address fields, and the ifc nand
220 * structure addr field to point to the correct IFC buffer in memory
221 */
222static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
223{
224 struct nand_chip *chip = mtd->priv;
225 struct fsl_ifc_mtd *priv = chip->priv;
226 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
227 struct fsl_ifc *ifc = ctrl->regs;
228 int buf_num;
229
230 ctrl->page = page_addr;
231
232 /* Program ROW0/COL0 */
233 out_be32(&ifc->ifc_nand.row0, page_addr);
234 out_be32(&ifc->ifc_nand.col0, (oob ? IFC_NAND_COL_MS : 0) | column);
235
236 buf_num = page_addr & priv->bufnum_mask;
237
238 ctrl->addr = priv->vbase + buf_num * (mtd->writesize * 2);
239 ctrl->index = column;
240
241 /* for OOB data point to the second half of the buffer */
242 if (oob)
243 ctrl->index += mtd->writesize;
244}
245
246static int is_blank(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
247 unsigned int bufnum)
248{
249 struct nand_chip *chip = mtd->priv;
250 struct fsl_ifc_mtd *priv = chip->priv;
251 u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
252 u32 __iomem *main = (u32 *)addr;
253 u8 __iomem *oob = addr + mtd->writesize;
254 int i;
255
256 for (i = 0; i < mtd->writesize / 4; i++) {
257 if (__raw_readl(&main[i]) != 0xffffffff)
258 return 0;
259 }
260
261 for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
262 int pos = chip->ecc.layout->eccpos[i];
263
264 if (__raw_readb(&oob[pos]) != 0xff)
265 return 0;
266 }
267
268 return 1;
269}
270
271/* returns nonzero if entire page is blank */
272static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
273 u32 *eccstat, unsigned int bufnum)
274{
275 u32 reg = eccstat[bufnum / 4];
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530276 int errors;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530277
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530278 errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530279
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530280 return errors;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530281}
282
283/*
284 * execute IFC NAND command and wait for it to complete
285 */
286static int fsl_ifc_run_command(struct mtd_info *mtd)
287{
288 struct nand_chip *chip = mtd->priv;
289 struct fsl_ifc_mtd *priv = chip->priv;
290 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
291 struct fsl_ifc *ifc = ctrl->regs;
292 long long end_tick;
293 u32 eccstat[4];
294 int i;
295
296 /* set the chip select for NAND Transaction */
297 out_be32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
298
299 /* start read/write seq */
300 out_be32(&ifc->ifc_nand.nandseq_strt,
301 IFC_NAND_SEQ_STRT_FIR_STRT);
302
303 /* wait for NAND Machine complete flag or timeout */
304 end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
305
306 while (end_tick > get_ticks()) {
307 ctrl->status = in_be32(&ifc->ifc_nand.nand_evter_stat);
308
309 if (ctrl->status & IFC_NAND_EVTER_STAT_OPC)
310 break;
311 }
312
313 out_be32(&ifc->ifc_nand.nand_evter_stat, ctrl->status);
314
315 if (ctrl->status & IFC_NAND_EVTER_STAT_FTOER)
316 printf("%s: Flash Time Out Error\n", __func__);
317 if (ctrl->status & IFC_NAND_EVTER_STAT_WPER)
318 printf("%s: Write Protect Error\n", __func__);
319
320 if (ctrl->eccread) {
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530321 int errors;
322 int bufnum = ctrl->page & priv->bufnum_mask;
323 int sector = bufnum * chip->ecc.steps;
324 int sector_end = sector + chip->ecc.steps - 1;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530325
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530326 for (i = sector / 4; i <= sector_end / 4; i++)
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530327 eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]);
328
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530329 for (i = sector; i <= sector_end; i++) {
330 errors = check_read_ecc(mtd, ctrl, eccstat, i);
331
332 if (errors == 15) {
333 /*
334 * Uncorrectable error.
335 * OK only if the whole page is blank.
336 *
337 * We disable ECCER reporting due to erratum
338 * IFC-A002770 -- so report it now if we
339 * see an uncorrectable error in ECCSTAT.
340 */
341 if (!is_blank(mtd, ctrl, bufnum))
342 ctrl->status |=
343 IFC_NAND_EVTER_STAT_ECCER;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530344 break;
Prabhakar Kushwaha5f720b82012-01-20 18:38:14 +0530345 }
346
347 mtd->ecc_stats.corrected += errors;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530348 }
349
350 ctrl->eccread = 0;
351 }
352
353 /* returns 0 on success otherwise non-zero) */
354 return ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO;
355}
356
357static void fsl_ifc_do_read(struct nand_chip *chip,
358 int oob,
359 struct mtd_info *mtd)
360{
361 struct fsl_ifc_mtd *priv = chip->priv;
362 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
363 struct fsl_ifc *ifc = ctrl->regs;
364
365 /* Program FIR/IFC_NAND_FCR0 for Small/Large page */
366 if (mtd->writesize > 512) {
367 out_be32(&ifc->ifc_nand.nand_fir0,
368 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
369 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
370 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
371 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) |
372 (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP4_SHIFT));
373 out_be32(&ifc->ifc_nand.nand_fir1, 0x0);
374
375 out_be32(&ifc->ifc_nand.nand_fcr0,
376 (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) |
377 (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT));
378 } else {
379 out_be32(&ifc->ifc_nand.nand_fir0,
380 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
381 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
382 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
383 (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP3_SHIFT));
384
385 if (oob)
386 out_be32(&ifc->ifc_nand.nand_fcr0,
387 NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT);
388 else
389 out_be32(&ifc->ifc_nand.nand_fcr0,
390 NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT);
391 }
392}
393
394/* cmdfunc send commands to the IFC NAND Machine */
395static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
396 int column, int page_addr)
397{
398 struct nand_chip *chip = mtd->priv;
399 struct fsl_ifc_mtd *priv = chip->priv;
400 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
401 struct fsl_ifc *ifc = ctrl->regs;
402
403 /* clear the read buffer */
404 ctrl->read_bytes = 0;
405 if (command != NAND_CMD_PAGEPROG)
406 ctrl->index = 0;
407
408 switch (command) {
409 /* READ0 read the entire buffer to use hardware ECC. */
410 case NAND_CMD_READ0: {
411 out_be32(&ifc->ifc_nand.nand_fbcr, 0);
412 set_addr(mtd, 0, page_addr, 0);
413
414 ctrl->read_bytes = mtd->writesize + mtd->oobsize;
415 ctrl->index += column;
416
417 if (chip->ecc.mode == NAND_ECC_HW)
418 ctrl->eccread = 1;
419
420 fsl_ifc_do_read(chip, 0, mtd);
421 fsl_ifc_run_command(mtd);
422 return;
423 }
424
425 /* READOOB reads only the OOB because no ECC is performed. */
426 case NAND_CMD_READOOB:
427 out_be32(&ifc->ifc_nand.nand_fbcr, mtd->oobsize - column);
428 set_addr(mtd, column, page_addr, 1);
429
430 ctrl->read_bytes = mtd->writesize + mtd->oobsize;
431
432 fsl_ifc_do_read(chip, 1, mtd);
433 fsl_ifc_run_command(mtd);
434
435 return;
436
437 /* READID must read all possible bytes while CEB is active */
438 case NAND_CMD_READID:
Prabhakar Kushwaha807fc702012-04-08 18:57:18 +0000439 case NAND_CMD_PARAM: {
440 int timing = IFC_FIR_OP_RB;
441 if (command == NAND_CMD_PARAM)
442 timing = IFC_FIR_OP_RBCD;
443
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530444 out_be32(&ifc->ifc_nand.nand_fir0,
Prabhakar Kushwahaba427672012-11-07 21:52:27 +0000445 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530446 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
Prabhakar Kushwaha807fc702012-04-08 18:57:18 +0000447 (timing << IFC_NAND_FIR0_OP2_SHIFT));
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530448 out_be32(&ifc->ifc_nand.nand_fcr0,
Prabhakar Kushwaha807fc702012-04-08 18:57:18 +0000449 command << IFC_NAND_FCR0_CMD0_SHIFT);
450 out_be32(&ifc->ifc_nand.row3, column);
451
452 /*
453 * although currently it's 8 bytes for READID, we always read
454 * the maximum 256 bytes(for PARAM)
455 */
456 out_be32(&ifc->ifc_nand.nand_fbcr, 256);
457 ctrl->read_bytes = 256;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530458
459 set_addr(mtd, 0, 0, 0);
460 fsl_ifc_run_command(mtd);
461 return;
Prabhakar Kushwaha807fc702012-04-08 18:57:18 +0000462 }
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530463
464 /* ERASE1 stores the block and page address */
465 case NAND_CMD_ERASE1:
466 set_addr(mtd, 0, page_addr, 0);
467 return;
468
469 /* ERASE2 uses the block and page address from ERASE1 */
470 case NAND_CMD_ERASE2:
471 out_be32(&ifc->ifc_nand.nand_fir0,
472 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
473 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP1_SHIFT) |
474 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP2_SHIFT));
475
476 out_be32(&ifc->ifc_nand.nand_fcr0,
477 (NAND_CMD_ERASE1 << IFC_NAND_FCR0_CMD0_SHIFT) |
478 (NAND_CMD_ERASE2 << IFC_NAND_FCR0_CMD1_SHIFT));
479
480 out_be32(&ifc->ifc_nand.nand_fbcr, 0);
481 ctrl->read_bytes = 0;
482 fsl_ifc_run_command(mtd);
483 return;
484
485 /* SEQIN sets up the addr buffer and all registers except the length */
486 case NAND_CMD_SEQIN: {
487 u32 nand_fcr0;
488 ctrl->column = column;
489 ctrl->oob = 0;
490
491 if (mtd->writesize > 512) {
492 nand_fcr0 =
493 (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
Prabhakar Kushwahaed5ac342013-10-03 11:35:35 +0530494 (NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
495 (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530496
497 out_be32(&ifc->ifc_nand.nand_fir0,
498 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
499 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
500 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
501 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) |
Prabhakar Kushwahaed5ac342013-10-03 11:35:35 +0530502 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT));
503 out_be32(&ifc->ifc_nand.nand_fir1,
504 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
505 (IFC_FIR_OP_RDSTAT <<
506 IFC_NAND_FIR1_OP6_SHIFT) |
507 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT));
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530508 } else {
509 nand_fcr0 = ((NAND_CMD_PAGEPROG <<
510 IFC_NAND_FCR0_CMD1_SHIFT) |
511 (NAND_CMD_SEQIN <<
Prabhakar Kushwahaed5ac342013-10-03 11:35:35 +0530512 IFC_NAND_FCR0_CMD2_SHIFT) |
513 (NAND_CMD_STATUS <<
514 IFC_NAND_FCR0_CMD3_SHIFT));
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530515
516 out_be32(&ifc->ifc_nand.nand_fir0,
517 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
518 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP1_SHIFT) |
519 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP2_SHIFT) |
520 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
521 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT));
522 out_be32(&ifc->ifc_nand.nand_fir1,
Prabhakar Kushwahaed5ac342013-10-03 11:35:35 +0530523 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
524 (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
525 (IFC_FIR_OP_RDSTAT <<
526 IFC_NAND_FIR1_OP7_SHIFT) |
527 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT));
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530528
Prabhakar Kushwahad9036122012-01-20 18:39:05 +0530529 if (column >= mtd->writesize)
530 nand_fcr0 |=
531 NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
532 else
533 nand_fcr0 |=
534 NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530535 }
536
Prabhakar Kushwahad9036122012-01-20 18:39:05 +0530537 if (column >= mtd->writesize) {
538 /* OOB area --> READOOB */
539 column -= mtd->writesize;
540 ctrl->oob = 1;
541 }
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530542 out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0);
543 set_addr(mtd, column, page_addr, ctrl->oob);
544 return;
545 }
546
547 /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
548 case NAND_CMD_PAGEPROG:
549 if (ctrl->oob)
Prabhakar Kushwahad9036122012-01-20 18:39:05 +0530550 out_be32(&ifc->ifc_nand.nand_fbcr,
551 ctrl->index - ctrl->column);
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530552 else
553 out_be32(&ifc->ifc_nand.nand_fbcr, 0);
554
555 fsl_ifc_run_command(mtd);
556 return;
557
558 case NAND_CMD_STATUS:
559 out_be32(&ifc->ifc_nand.nand_fir0,
560 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
561 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP1_SHIFT));
562 out_be32(&ifc->ifc_nand.nand_fcr0,
563 NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT);
564 out_be32(&ifc->ifc_nand.nand_fbcr, 1);
565 set_addr(mtd, 0, 0, 0);
566 ctrl->read_bytes = 1;
567
568 fsl_ifc_run_command(mtd);
569
570 /* Chip sometimes reporting write protect even when it's not */
571 out_8(ctrl->addr, in_8(ctrl->addr) | NAND_STATUS_WP);
572 return;
573
574 case NAND_CMD_RESET:
575 out_be32(&ifc->ifc_nand.nand_fir0,
576 IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT);
577 out_be32(&ifc->ifc_nand.nand_fcr0,
578 NAND_CMD_RESET << IFC_NAND_FCR0_CMD0_SHIFT);
579 fsl_ifc_run_command(mtd);
580 return;
581
582 default:
583 printf("%s: error, unsupported command 0x%x.\n",
584 __func__, command);
585 }
586}
587
588/*
589 * Write buf to the IFC NAND Controller Data Buffer
590 */
591static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
592{
593 struct nand_chip *chip = mtd->priv;
594 struct fsl_ifc_mtd *priv = chip->priv;
595 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
596 unsigned int bufsize = mtd->writesize + mtd->oobsize;
597
598 if (len <= 0) {
599 printf("%s of %d bytes", __func__, len);
600 ctrl->status = 0;
601 return;
602 }
603
604 if ((unsigned int)len > bufsize - ctrl->index) {
605 printf("%s beyond end of buffer "
606 "(%d requested, %u available)\n",
607 __func__, len, bufsize - ctrl->index);
608 len = bufsize - ctrl->index;
609 }
610
611 memcpy_toio(&ctrl->addr[ctrl->index], buf, len);
612 ctrl->index += len;
613}
614
615/*
616 * read a byte from either the IFC hardware buffer if it has any data left
617 * otherwise issue a command to read a single byte.
618 */
619static u8 fsl_ifc_read_byte(struct mtd_info *mtd)
620{
621 struct nand_chip *chip = mtd->priv;
622 struct fsl_ifc_mtd *priv = chip->priv;
623 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
624
625 /* If there are still bytes in the IFC buffer, then use the
626 * next byte. */
627 if (ctrl->index < ctrl->read_bytes)
628 return in_8(&ctrl->addr[ctrl->index++]);
629
630 printf("%s beyond end of buffer\n", __func__);
631 return ERR_BYTE;
632}
633
634/*
635 * Read two bytes from the IFC hardware buffer
636 * read function for 16-bit buswith
637 */
638static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd)
639{
640 struct nand_chip *chip = mtd->priv;
641 struct fsl_ifc_mtd *priv = chip->priv;
642 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
643 uint16_t data;
644
645 /*
646 * If there are still bytes in the IFC buffer, then use the
647 * next byte.
648 */
649 if (ctrl->index < ctrl->read_bytes) {
650 data = in_be16((uint16_t *)&ctrl->
651 addr[ctrl->index]);
652 ctrl->index += 2;
653 return (uint8_t)data;
654 }
655
656 printf("%s beyond end of buffer\n", __func__);
657 return ERR_BYTE;
658}
659
660/*
661 * Read from the IFC Controller Data Buffer
662 */
663static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
664{
665 struct nand_chip *chip = mtd->priv;
666 struct fsl_ifc_mtd *priv = chip->priv;
667 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
668 int avail;
669
670 if (len < 0)
671 return;
672
673 avail = min((unsigned int)len, ctrl->read_bytes - ctrl->index);
674 memcpy_fromio(buf, &ctrl->addr[ctrl->index], avail);
675 ctrl->index += avail;
676
677 if (len > avail)
678 printf("%s beyond end of buffer "
679 "(%d requested, %d available)\n",
680 __func__, len, avail);
681}
682
683/*
684 * Verify buffer against the IFC Controller Data Buffer
685 */
686static int fsl_ifc_verify_buf(struct mtd_info *mtd,
687 const u_char *buf, int len)
688{
689 struct nand_chip *chip = mtd->priv;
690 struct fsl_ifc_mtd *priv = chip->priv;
691 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
692 int i;
693
694 if (len < 0) {
695 printf("%s of %d bytes", __func__, len);
696 return -EINVAL;
697 }
698
699 if ((unsigned int)len > ctrl->read_bytes - ctrl->index) {
700 printf("%s beyond end of buffer "
701 "(%d requested, %u available)\n",
702 __func__, len, ctrl->read_bytes - ctrl->index);
703
704 ctrl->index = ctrl->read_bytes;
705 return -EINVAL;
706 }
707
708 for (i = 0; i < len; i++)
709 if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i])
710 break;
711
712 ctrl->index += len;
713 return i == len && ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO;
714}
715
716/* This function is called after Program and Erase Operations to
717 * check for success or failure.
718 */
719static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
720{
721 struct fsl_ifc_mtd *priv = chip->priv;
722 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
723 struct fsl_ifc *ifc = ctrl->regs;
724 u32 nand_fsr;
725
726 if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
727 return NAND_STATUS_FAIL;
728
729 /* Use READ_STATUS command, but wait for the device to be ready */
730 out_be32(&ifc->ifc_nand.nand_fir0,
731 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
732 (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT));
733 out_be32(&ifc->ifc_nand.nand_fcr0, NAND_CMD_STATUS <<
734 IFC_NAND_FCR0_CMD0_SHIFT);
735 out_be32(&ifc->ifc_nand.nand_fbcr, 1);
736 set_addr(mtd, 0, 0, 0);
737 ctrl->read_bytes = 1;
738
739 fsl_ifc_run_command(mtd);
740
741 if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
742 return NAND_STATUS_FAIL;
743
744 nand_fsr = in_be32(&ifc->ifc_nand.nand_fsr);
745
746 /* Chip sometimes reporting write protect even when it's not */
747 nand_fsr = nand_fsr | NAND_STATUS_WP;
748 return nand_fsr;
749}
750
Sergey Lapindfe64e22013-01-14 03:46:50 +0000751static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
752 uint8_t *buf, int oob_required, int page)
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530753{
754 struct fsl_ifc_mtd *priv = chip->priv;
755 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
756
757 fsl_ifc_read_buf(mtd, buf, mtd->writesize);
758 fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
759
760 if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
761 mtd->ecc_stats.failed++;
762
763 return 0;
764}
765
766/* ECC will be calculated automatically, and errors will be detected in
767 * waitfunc.
768 */
Sergey Lapindfe64e22013-01-14 03:46:50 +0000769static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
770 const uint8_t *buf, int oob_required)
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530771{
772 fsl_ifc_write_buf(mtd, buf, mtd->writesize);
773 fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000774
775 return 0;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530776}
777
778static void fsl_ifc_ctrl_init(void)
779{
780 ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL);
781 if (!ifc_ctrl)
782 return;
783
784 ifc_ctrl->regs = IFC_BASE_ADDR;
785
786 /* clear event registers */
787 out_be32(&ifc_ctrl->regs->ifc_nand.nand_evter_stat, ~0U);
788 out_be32(&ifc_ctrl->regs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
789
790 /* Enable error and event for any detected errors */
791 out_be32(&ifc_ctrl->regs->ifc_nand.nand_evter_en,
792 IFC_NAND_EVTER_EN_OPC_EN |
793 IFC_NAND_EVTER_EN_PGRDCMPL_EN |
794 IFC_NAND_EVTER_EN_FTOER_EN |
795 IFC_NAND_EVTER_EN_WPER_EN);
796
797 out_be32(&ifc_ctrl->regs->ifc_nand.ncfgr, 0x0);
798}
799
800static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
801{
802}
803
Prabhakar Kushwaha79da5e32012-09-12 22:26:05 +0000804static void fsl_ifc_sram_init(void)
805{
806 struct fsl_ifc *ifc = ifc_ctrl->regs;
807 uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
808 long long end_tick;
809
810 cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
811
812 /* Save CSOR and CSOR_ext */
813 csor = in_be32(&ifc_ctrl->regs->csor_cs[cs].csor);
814 csor_ext = in_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext);
815
816 /* chage PageSize 8K and SpareSize 1K*/
817 csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
818 out_be32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k);
819 out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400);
820
821 /* READID */
822 out_be32(&ifc->ifc_nand.nand_fir0,
Prabhakar Kushwahaba427672012-11-07 21:52:27 +0000823 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
Prabhakar Kushwaha79da5e32012-09-12 22:26:05 +0000824 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
825 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
826 out_be32(&ifc->ifc_nand.nand_fcr0,
827 NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
828 out_be32(&ifc->ifc_nand.row3, 0x0);
829
830 out_be32(&ifc->ifc_nand.nand_fbcr, 0x0);
831
832 /* Program ROW0/COL0 */
833 out_be32(&ifc->ifc_nand.row0, 0x0);
834 out_be32(&ifc->ifc_nand.col0, 0x0);
835
836 /* set the chip select for NAND Transaction */
837 out_be32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
838
839 /* start read seq */
840 out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
841
842 /* wait for NAND Machine complete flag or timeout */
843 end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
844
845 while (end_tick > get_ticks()) {
846 ifc_ctrl->status = in_be32(&ifc->ifc_nand.nand_evter_stat);
847
848 if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
849 break;
850 }
851
852 out_be32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
853
854 /* Restore CSOR and CSOR_ext */
855 out_be32(&ifc_ctrl->regs->csor_cs[cs].csor, csor);
856 out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
857}
858
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000859static int fsl_ifc_chip_init(int devnum, u8 *addr)
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530860{
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000861 struct mtd_info *mtd = &nand_info[devnum];
862 struct nand_chip *nand;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530863 struct fsl_ifc_mtd *priv;
864 struct nand_ecclayout *layout;
Prabhakar Kushwaha79da5e32012-09-12 22:26:05 +0000865 uint32_t cspr = 0, csor = 0, ver = 0;
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000866 int ret;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530867
868 if (!ifc_ctrl) {
869 fsl_ifc_ctrl_init();
870 if (!ifc_ctrl)
871 return -1;
872 }
873
874 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
875 if (!priv)
876 return -ENOMEM;
877
878 priv->ctrl = ifc_ctrl;
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000879 priv->vbase = addr;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530880
881 /* Find which chip select it is connected to.
882 */
883 for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) {
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000884 phys_addr_t phys_addr = virt_to_phys(addr);
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530885
886 cspr = in_be32(&ifc_ctrl->regs->cspr_cs[priv->bank].cspr);
887 csor = in_be32(&ifc_ctrl->regs->csor_cs[priv->bank].csor);
888
889 if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND &&
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000890 (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) {
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530891 ifc_ctrl->cs_nand = priv->bank << IFC_NAND_CSEL_SHIFT;
892 break;
893 }
894 }
895
896 if (priv->bank >= MAX_BANKS) {
897 printf("%s: address did not match any "
898 "chip selects\n", __func__);
Prabhakar Kushwaha76d067a2012-04-10 22:48:27 +0000899 kfree(priv);
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530900 return -ENODEV;
901 }
902
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +0000903 nand = &priv->chip;
904 mtd->priv = nand;
905
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530906 ifc_ctrl->chips[priv->bank] = priv;
907
908 /* fill in nand_chip structure */
909 /* set up function call table */
910
911 nand->write_buf = fsl_ifc_write_buf;
912 nand->read_buf = fsl_ifc_read_buf;
913 nand->verify_buf = fsl_ifc_verify_buf;
914 nand->select_chip = fsl_ifc_select_chip;
915 nand->cmdfunc = fsl_ifc_cmdfunc;
916 nand->waitfunc = fsl_ifc_wait;
917
918 /* set up nand options */
919 nand->bbt_td = &bbt_main_descr;
920 nand->bbt_md = &bbt_mirror_descr;
921
922 /* set up nand options */
Sergey Lapindfe64e22013-01-14 03:46:50 +0000923 nand->options = NAND_NO_SUBPAGE_WRITE;
924 nand->bbt_options = NAND_BBT_USE_FLASH;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530925
926 if (cspr & CSPR_PORT_SIZE_16) {
927 nand->read_byte = fsl_ifc_read_byte16;
928 nand->options |= NAND_BUSWIDTH_16;
929 } else {
930 nand->read_byte = fsl_ifc_read_byte;
931 }
932
933 nand->controller = &ifc_ctrl->controller;
934 nand->priv = priv;
935
936 nand->ecc.read_page = fsl_ifc_read_page;
937 nand->ecc.write_page = fsl_ifc_write_page;
938
939 /* Hardware generates ECC per 512 Bytes */
940 nand->ecc.size = 512;
941 nand->ecc.bytes = 8;
942
943 switch (csor & CSOR_NAND_PGS_MASK) {
944 case CSOR_NAND_PGS_512:
945 if (nand->options & NAND_BUSWIDTH_16) {
946 layout = &oob_512_16bit_ecc4;
947 } else {
948 layout = &oob_512_8bit_ecc4;
949
950 /* Avoid conflict with bad block marker */
951 bbt_main_descr.offs = 0;
952 bbt_mirror_descr.offs = 0;
953 }
954
Sergey Lapindfe64e22013-01-14 03:46:50 +0000955 nand->ecc.strength = 4;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530956 priv->bufnum_mask = 15;
957 break;
958
959 case CSOR_NAND_PGS_2K:
960 layout = &oob_2048_ecc4;
Sergey Lapindfe64e22013-01-14 03:46:50 +0000961 nand->ecc.strength = 4;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530962 priv->bufnum_mask = 3;
963 break;
964
965 case CSOR_NAND_PGS_4K:
966 if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
967 CSOR_NAND_ECC_MODE_4) {
968 layout = &oob_4096_ecc4;
Sergey Lapindfe64e22013-01-14 03:46:50 +0000969 nand->ecc.strength = 4;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530970 } else {
971 layout = &oob_4096_ecc8;
Sergey Lapindfe64e22013-01-14 03:46:50 +0000972 nand->ecc.strength = 8;
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530973 nand->ecc.bytes = 16;
974 }
975
976 priv->bufnum_mask = 1;
977 break;
978
Prabhakar Kushwaha71220f82013-10-04 10:05:36 +0530979 case CSOR_NAND_PGS_8K:
980 if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
981 CSOR_NAND_ECC_MODE_4) {
982 layout = &oob_8192_ecc4;
983 nand->ecc.strength = 4;
984 } else {
985 layout = &oob_8192_ecc8;
986 nand->ecc.strength = 8;
987 nand->ecc.bytes = 16;
988 }
989
990 priv->bufnum_mask = 0;
991 break;
992
993
Dipen Dudhat52f90da2011-03-22 09:27:39 +0530994 default:
995 printf("ifc nand: bad csor %#x: bad page size\n", csor);
996 return -ENODEV;
997 }
998
999 /* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */
1000 if (csor & CSOR_NAND_ECC_DEC_EN) {
1001 nand->ecc.mode = NAND_ECC_HW;
1002 nand->ecc.layout = layout;
1003 } else {
1004 nand->ecc.mode = NAND_ECC_SOFT;
1005 }
1006
Prabhakar Kushwaha79da5e32012-09-12 22:26:05 +00001007 ver = in_be32(&ifc_ctrl->regs->ifc_rev);
1008 if (ver == FSL_IFC_V1_1_0)
1009 fsl_ifc_sram_init();
1010
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +00001011 ret = nand_scan_ident(mtd, 1, NULL);
1012 if (ret)
1013 return ret;
1014
1015 ret = nand_scan_tail(mtd);
1016 if (ret)
1017 return ret;
1018
1019 ret = nand_register(devnum);
1020 if (ret)
1021 return ret;
Dipen Dudhat52f90da2011-03-22 09:27:39 +05301022 return 0;
1023}
Prabhakar Kushwahaa1b81ab2013-04-04 18:44:06 +00001024
1025#ifndef CONFIG_SYS_NAND_BASE_LIST
1026#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
1027#endif
1028
1029static unsigned long base_address[CONFIG_SYS_MAX_NAND_DEVICE] =
1030 CONFIG_SYS_NAND_BASE_LIST;
1031
1032void board_nand_init(void)
1033{
1034 int i;
1035
1036 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
1037 fsl_ifc_chip_init(i, (u8 *)base_address[i]);
1038}