blob: 8b453cb383c206f2e9acc4d29c425343a3703052 [file] [log] [blame]
Dipen Dudhat9eae0832011-03-22 09:27:39 +05301/* Integrated Flash Controller NAND Machine Driver
2 *
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +05303 * Copyright (c) 2012 Freescale Semiconductor, Inc
Dipen Dudhat9eae0832011-03-22 09:27:39 +05304 *
5 * Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com>
6 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Dipen Dudhat9eae0832011-03-22 09:27:39 +05308 */
9
10#include <common.h>
11#include <malloc.h>
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +000012#include <nand.h>
Dipen Dudhat9eae0832011-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>
York Sun37562f62013-10-22 12:39:02 -070020#include <fsl_ifc.h>
Dipen Dudhat9eae0832011-03-22 09:27:39 +053021
Prabhakar Kushwahaa8759642014-06-12 09:13:08 +053022#ifndef CONFIG_SYS_FSL_IFC_BANK_COUNT
23#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
24#endif
25
Prabhakar Kushwahaa8759642014-06-12 09:13:08 +053026#define MAX_BANKS CONFIG_SYS_FSL_IFC_BANK_COUNT
Dipen Dudhat9eae0832011-03-22 09:27:39 +053027#define ERR_BYTE 0xFF /* Value returned for read bytes
28 when read failed */
29#define IFC_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for IFC
30 NAND Machine */
31
32struct fsl_ifc_ctrl;
33
34/* mtd information per set */
35struct fsl_ifc_mtd {
Dipen Dudhat9eae0832011-03-22 09:27:39 +053036 struct nand_chip chip;
37 struct fsl_ifc_ctrl *ctrl;
38
39 struct device *dev;
40 int bank; /* Chip select bank number */
41 unsigned int bufnum_mask; /* bufnum = page & bufnum_mask */
42 u8 __iomem *vbase; /* Chip select base virtual address */
43};
44
45/* overview of the fsl ifc controller */
46struct fsl_ifc_ctrl {
47 struct nand_hw_control controller;
48 struct fsl_ifc_mtd *chips[MAX_BANKS];
49
50 /* device info */
51 struct fsl_ifc *regs;
52 uint8_t __iomem *addr; /* Address of assigned IFC buffer */
53 unsigned int cs_nand; /* On which chipsel NAND is connected */
54 unsigned int page; /* Last page written to / read from */
55 unsigned int read_bytes; /* Number of bytes read during command */
56 unsigned int column; /* Saved column from SEQIN */
57 unsigned int index; /* Pointer to next byte to 'read' */
58 unsigned int status; /* status read from NEESR after last op */
59 unsigned int oob; /* Non zero if operating on OOB data */
60 unsigned int eccread; /* Non zero for a full-page ECC read */
61};
62
63static struct fsl_ifc_ctrl *ifc_ctrl;
64
65/* 512-byte page with 4-bit ECC, 8-bit */
66static struct nand_ecclayout oob_512_8bit_ecc4 = {
67 .eccbytes = 8,
68 .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
69 .oobfree = { {0, 5}, {6, 2} },
70};
71
72/* 512-byte page with 4-bit ECC, 16-bit */
73static struct nand_ecclayout oob_512_16bit_ecc4 = {
74 .eccbytes = 8,
75 .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
76 .oobfree = { {2, 6}, },
77};
78
79/* 2048-byte page size with 4-bit ECC */
80static struct nand_ecclayout oob_2048_ecc4 = {
81 .eccbytes = 32,
82 .eccpos = {
83 8, 9, 10, 11, 12, 13, 14, 15,
84 16, 17, 18, 19, 20, 21, 22, 23,
85 24, 25, 26, 27, 28, 29, 30, 31,
86 32, 33, 34, 35, 36, 37, 38, 39,
87 },
88 .oobfree = { {2, 6}, {40, 24} },
89};
90
91/* 4096-byte page size with 4-bit ECC */
92static struct nand_ecclayout oob_4096_ecc4 = {
93 .eccbytes = 64,
94 .eccpos = {
95 8, 9, 10, 11, 12, 13, 14, 15,
96 16, 17, 18, 19, 20, 21, 22, 23,
97 24, 25, 26, 27, 28, 29, 30, 31,
98 32, 33, 34, 35, 36, 37, 38, 39,
99 40, 41, 42, 43, 44, 45, 46, 47,
100 48, 49, 50, 51, 52, 53, 54, 55,
101 56, 57, 58, 59, 60, 61, 62, 63,
102 64, 65, 66, 67, 68, 69, 70, 71,
103 },
104 .oobfree = { {2, 6}, {72, 56} },
105};
106
107/* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */
108static struct nand_ecclayout oob_4096_ecc8 = {
109 .eccbytes = 128,
110 .eccpos = {
111 8, 9, 10, 11, 12, 13, 14, 15,
112 16, 17, 18, 19, 20, 21, 22, 23,
113 24, 25, 26, 27, 28, 29, 30, 31,
114 32, 33, 34, 35, 36, 37, 38, 39,
115 40, 41, 42, 43, 44, 45, 46, 47,
116 48, 49, 50, 51, 52, 53, 54, 55,
117 56, 57, 58, 59, 60, 61, 62, 63,
118 64, 65, 66, 67, 68, 69, 70, 71,
119 72, 73, 74, 75, 76, 77, 78, 79,
120 80, 81, 82, 83, 84, 85, 86, 87,
121 88, 89, 90, 91, 92, 93, 94, 95,
122 96, 97, 98, 99, 100, 101, 102, 103,
123 104, 105, 106, 107, 108, 109, 110, 111,
124 112, 113, 114, 115, 116, 117, 118, 119,
125 120, 121, 122, 123, 124, 125, 126, 127,
126 128, 129, 130, 131, 132, 133, 134, 135,
127 },
128 .oobfree = { {2, 6}, {136, 82} },
129};
130
Prabhakar Kushwahaa3aaf1d2013-10-04 10:05:36 +0530131/* 8192-byte page size with 4-bit ECC */
132static struct nand_ecclayout oob_8192_ecc4 = {
133 .eccbytes = 128,
134 .eccpos = {
135 8, 9, 10, 11, 12, 13, 14, 15,
136 16, 17, 18, 19, 20, 21, 22, 23,
137 24, 25, 26, 27, 28, 29, 30, 31,
138 32, 33, 34, 35, 36, 37, 38, 39,
139 40, 41, 42, 43, 44, 45, 46, 47,
140 48, 49, 50, 51, 52, 53, 54, 55,
141 56, 57, 58, 59, 60, 61, 62, 63,
142 64, 65, 66, 67, 68, 69, 70, 71,
143 72, 73, 74, 75, 76, 77, 78, 79,
144 80, 81, 82, 83, 84, 85, 86, 87,
145 88, 89, 90, 91, 92, 93, 94, 95,
146 96, 97, 98, 99, 100, 101, 102, 103,
147 104, 105, 106, 107, 108, 109, 110, 111,
148 112, 113, 114, 115, 116, 117, 118, 119,
149 120, 121, 122, 123, 124, 125, 126, 127,
150 128, 129, 130, 131, 132, 133, 134, 135,
151 },
152 .oobfree = { {2, 6}, {136, 208} },
153};
154
155/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
156static struct nand_ecclayout oob_8192_ecc8 = {
157 .eccbytes = 256,
158 .eccpos = {
159 8, 9, 10, 11, 12, 13, 14, 15,
160 16, 17, 18, 19, 20, 21, 22, 23,
161 24, 25, 26, 27, 28, 29, 30, 31,
162 32, 33, 34, 35, 36, 37, 38, 39,
163 40, 41, 42, 43, 44, 45, 46, 47,
164 48, 49, 50, 51, 52, 53, 54, 55,
165 56, 57, 58, 59, 60, 61, 62, 63,
166 64, 65, 66, 67, 68, 69, 70, 71,
167 72, 73, 74, 75, 76, 77, 78, 79,
168 80, 81, 82, 83, 84, 85, 86, 87,
169 88, 89, 90, 91, 92, 93, 94, 95,
170 96, 97, 98, 99, 100, 101, 102, 103,
171 104, 105, 106, 107, 108, 109, 110, 111,
172 112, 113, 114, 115, 116, 117, 118, 119,
173 120, 121, 122, 123, 124, 125, 126, 127,
174 128, 129, 130, 131, 132, 133, 134, 135,
175 136, 137, 138, 139, 140, 141, 142, 143,
176 144, 145, 146, 147, 148, 149, 150, 151,
177 152, 153, 154, 155, 156, 157, 158, 159,
178 160, 161, 162, 163, 164, 165, 166, 167,
179 168, 169, 170, 171, 172, 173, 174, 175,
180 176, 177, 178, 179, 180, 181, 182, 183,
181 184, 185, 186, 187, 188, 189, 190, 191,
182 192, 193, 194, 195, 196, 197, 198, 199,
183 200, 201, 202, 203, 204, 205, 206, 207,
184 208, 209, 210, 211, 212, 213, 214, 215,
185 216, 217, 218, 219, 220, 221, 222, 223,
186 224, 225, 226, 227, 228, 229, 230, 231,
187 232, 233, 234, 235, 236, 237, 238, 239,
188 240, 241, 242, 243, 244, 245, 246, 247,
189 248, 249, 250, 251, 252, 253, 254, 255,
190 256, 257, 258, 259, 260, 261, 262, 263,
191 },
192 .oobfree = { {2, 6}, {264, 80} },
193};
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530194
195/*
196 * Generic flash bbt descriptors
197 */
198static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
199static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
200
201static struct nand_bbt_descr bbt_main_descr = {
202 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
203 NAND_BBT_2BIT | NAND_BBT_VERSION,
204 .offs = 2, /* 0 on 8-bit small page */
205 .len = 4,
206 .veroffs = 6,
207 .maxblocks = 4,
208 .pattern = bbt_pattern,
209};
210
211static struct nand_bbt_descr bbt_mirror_descr = {
212 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
213 NAND_BBT_2BIT | NAND_BBT_VERSION,
214 .offs = 2, /* 0 on 8-bit small page */
215 .len = 4,
216 .veroffs = 6,
217 .maxblocks = 4,
218 .pattern = mirror_pattern,
219};
220
221/*
222 * Set up the IFC hardware block and page address fields, and the ifc nand
223 * structure addr field to point to the correct IFC buffer in memory
224 */
225static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
226{
227 struct nand_chip *chip = mtd->priv;
228 struct fsl_ifc_mtd *priv = chip->priv;
229 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
230 struct fsl_ifc *ifc = ctrl->regs;
231 int buf_num;
232
233 ctrl->page = page_addr;
234
235 /* Program ROW0/COL0 */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530236 ifc_out32(&ifc->ifc_nand.row0, page_addr);
237 ifc_out32(&ifc->ifc_nand.col0, (oob ? IFC_NAND_COL_MS : 0) | column);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530238
239 buf_num = page_addr & priv->bufnum_mask;
240
241 ctrl->addr = priv->vbase + buf_num * (mtd->writesize * 2);
242 ctrl->index = column;
243
244 /* for OOB data point to the second half of the buffer */
245 if (oob)
246 ctrl->index += mtd->writesize;
247}
248
249static int is_blank(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
250 unsigned int bufnum)
251{
252 struct nand_chip *chip = mtd->priv;
253 struct fsl_ifc_mtd *priv = chip->priv;
254 u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
255 u32 __iomem *main = (u32 *)addr;
256 u8 __iomem *oob = addr + mtd->writesize;
257 int i;
258
259 for (i = 0; i < mtd->writesize / 4; i++) {
260 if (__raw_readl(&main[i]) != 0xffffffff)
261 return 0;
262 }
263
264 for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
265 int pos = chip->ecc.layout->eccpos[i];
266
267 if (__raw_readb(&oob[pos]) != 0xff)
268 return 0;
269 }
270
271 return 1;
272}
273
274/* returns nonzero if entire page is blank */
275static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
276 u32 *eccstat, unsigned int bufnum)
277{
278 u32 reg = eccstat[bufnum / 4];
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530279 int errors;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530280
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530281 errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530282
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530283 return errors;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530284}
285
286/*
287 * execute IFC NAND command and wait for it to complete
288 */
289static int fsl_ifc_run_command(struct mtd_info *mtd)
290{
291 struct nand_chip *chip = mtd->priv;
292 struct fsl_ifc_mtd *priv = chip->priv;
293 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
294 struct fsl_ifc *ifc = ctrl->regs;
295 long long end_tick;
296 u32 eccstat[4];
297 int i;
298
299 /* set the chip select for NAND Transaction */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530300 ifc_out32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530301
302 /* start read/write seq */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530303 ifc_out32(&ifc->ifc_nand.nandseq_strt,
304 IFC_NAND_SEQ_STRT_FIR_STRT);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530305
306 /* wait for NAND Machine complete flag or timeout */
307 end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
308
309 while (end_tick > get_ticks()) {
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530310 ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530311
312 if (ctrl->status & IFC_NAND_EVTER_STAT_OPC)
313 break;
314 }
315
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530316 ifc_out32(&ifc->ifc_nand.nand_evter_stat, ctrl->status);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530317
318 if (ctrl->status & IFC_NAND_EVTER_STAT_FTOER)
319 printf("%s: Flash Time Out Error\n", __func__);
320 if (ctrl->status & IFC_NAND_EVTER_STAT_WPER)
321 printf("%s: Write Protect Error\n", __func__);
322
323 if (ctrl->eccread) {
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530324 int errors;
325 int bufnum = ctrl->page & priv->bufnum_mask;
326 int sector = bufnum * chip->ecc.steps;
327 int sector_end = sector + chip->ecc.steps - 1;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530328
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530329 for (i = sector / 4; i <= sector_end / 4; i++)
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530330 eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530331
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530332 for (i = sector; i <= sector_end; i++) {
333 errors = check_read_ecc(mtd, ctrl, eccstat, i);
334
335 if (errors == 15) {
336 /*
337 * Uncorrectable error.
338 * OK only if the whole page is blank.
339 *
340 * We disable ECCER reporting due to erratum
341 * IFC-A002770 -- so report it now if we
342 * see an uncorrectable error in ECCSTAT.
343 */
344 if (!is_blank(mtd, ctrl, bufnum))
345 ctrl->status |=
346 IFC_NAND_EVTER_STAT_ECCER;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530347 break;
Prabhakar Kushwahacdd045d2012-01-20 18:38:14 +0530348 }
349
350 mtd->ecc_stats.corrected += errors;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530351 }
352
353 ctrl->eccread = 0;
354 }
355
356 /* returns 0 on success otherwise non-zero) */
357 return ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO;
358}
359
360static void fsl_ifc_do_read(struct nand_chip *chip,
361 int oob,
362 struct mtd_info *mtd)
363{
364 struct fsl_ifc_mtd *priv = chip->priv;
365 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
366 struct fsl_ifc *ifc = ctrl->regs;
367
368 /* Program FIR/IFC_NAND_FCR0 for Small/Large page */
369 if (mtd->writesize > 512) {
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530370 ifc_out32(&ifc->ifc_nand.nand_fir0,
371 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
372 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
373 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
374 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) |
375 (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP4_SHIFT));
376 ifc_out32(&ifc->ifc_nand.nand_fir1, 0x0);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530377
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530378 ifc_out32(&ifc->ifc_nand.nand_fcr0,
379 (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) |
380 (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530381 } else {
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530382 ifc_out32(&ifc->ifc_nand.nand_fir0,
383 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
384 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
385 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
386 (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP3_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530387
388 if (oob)
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530389 ifc_out32(&ifc->ifc_nand.nand_fcr0,
390 NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530391 else
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530392 ifc_out32(&ifc->ifc_nand.nand_fcr0,
393 NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530394 }
395}
396
397/* cmdfunc send commands to the IFC NAND Machine */
398static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
399 int column, int page_addr)
400{
401 struct nand_chip *chip = mtd->priv;
402 struct fsl_ifc_mtd *priv = chip->priv;
403 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
404 struct fsl_ifc *ifc = ctrl->regs;
405
406 /* clear the read buffer */
407 ctrl->read_bytes = 0;
408 if (command != NAND_CMD_PAGEPROG)
409 ctrl->index = 0;
410
411 switch (command) {
412 /* READ0 read the entire buffer to use hardware ECC. */
413 case NAND_CMD_READ0: {
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530414 ifc_out32(&ifc->ifc_nand.nand_fbcr, 0);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530415 set_addr(mtd, 0, page_addr, 0);
416
417 ctrl->read_bytes = mtd->writesize + mtd->oobsize;
418 ctrl->index += column;
419
420 if (chip->ecc.mode == NAND_ECC_HW)
421 ctrl->eccread = 1;
422
423 fsl_ifc_do_read(chip, 0, mtd);
424 fsl_ifc_run_command(mtd);
425 return;
426 }
427
428 /* READOOB reads only the OOB because no ECC is performed. */
429 case NAND_CMD_READOOB:
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530430 ifc_out32(&ifc->ifc_nand.nand_fbcr, mtd->oobsize - column);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530431 set_addr(mtd, column, page_addr, 1);
432
433 ctrl->read_bytes = mtd->writesize + mtd->oobsize;
434
435 fsl_ifc_do_read(chip, 1, mtd);
436 fsl_ifc_run_command(mtd);
437
438 return;
439
440 /* READID must read all possible bytes while CEB is active */
441 case NAND_CMD_READID:
Prabhakar Kushwahaf31cf532012-04-08 18:57:18 +0000442 case NAND_CMD_PARAM: {
443 int timing = IFC_FIR_OP_RB;
444 if (command == NAND_CMD_PARAM)
445 timing = IFC_FIR_OP_RBCD;
446
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530447 ifc_out32(&ifc->ifc_nand.nand_fir0,
448 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
449 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
450 (timing << IFC_NAND_FIR0_OP2_SHIFT));
451 ifc_out32(&ifc->ifc_nand.nand_fcr0,
452 command << IFC_NAND_FCR0_CMD0_SHIFT);
453 ifc_out32(&ifc->ifc_nand.row3, column);
Prabhakar Kushwahaf31cf532012-04-08 18:57:18 +0000454
455 /*
456 * although currently it's 8 bytes for READID, we always read
457 * the maximum 256 bytes(for PARAM)
458 */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530459 ifc_out32(&ifc->ifc_nand.nand_fbcr, 256);
Prabhakar Kushwahaf31cf532012-04-08 18:57:18 +0000460 ctrl->read_bytes = 256;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530461
462 set_addr(mtd, 0, 0, 0);
463 fsl_ifc_run_command(mtd);
464 return;
Prabhakar Kushwahaf31cf532012-04-08 18:57:18 +0000465 }
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530466
467 /* ERASE1 stores the block and page address */
468 case NAND_CMD_ERASE1:
469 set_addr(mtd, 0, page_addr, 0);
470 return;
471
472 /* ERASE2 uses the block and page address from ERASE1 */
473 case NAND_CMD_ERASE2:
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530474 ifc_out32(&ifc->ifc_nand.nand_fir0,
475 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
476 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP1_SHIFT) |
477 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP2_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530478
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530479 ifc_out32(&ifc->ifc_nand.nand_fcr0,
480 (NAND_CMD_ERASE1 << IFC_NAND_FCR0_CMD0_SHIFT) |
481 (NAND_CMD_ERASE2 << IFC_NAND_FCR0_CMD1_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530482
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530483 ifc_out32(&ifc->ifc_nand.nand_fbcr, 0);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530484 ctrl->read_bytes = 0;
485 fsl_ifc_run_command(mtd);
486 return;
487
488 /* SEQIN sets up the addr buffer and all registers except the length */
489 case NAND_CMD_SEQIN: {
490 u32 nand_fcr0;
491 ctrl->column = column;
492 ctrl->oob = 0;
493
494 if (mtd->writesize > 512) {
495 nand_fcr0 =
496 (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
Prabhakar Kushwaha18e6bde2013-10-03 11:35:35 +0530497 (NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
498 (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530499
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530500 ifc_out32(&ifc->ifc_nand.nand_fir0,
501 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
502 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
503 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
504 (IFC_FIR_OP_WBCD <<
505 IFC_NAND_FIR0_OP3_SHIFT) |
506 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT));
507 ifc_out32(&ifc->ifc_nand.nand_fir1,
508 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
509 (IFC_FIR_OP_RDSTAT <<
Prabhakar Kushwaha18e6bde2013-10-03 11:35:35 +0530510 IFC_NAND_FIR1_OP6_SHIFT) |
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530511 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530512 } else {
513 nand_fcr0 = ((NAND_CMD_PAGEPROG <<
514 IFC_NAND_FCR0_CMD1_SHIFT) |
515 (NAND_CMD_SEQIN <<
Prabhakar Kushwaha18e6bde2013-10-03 11:35:35 +0530516 IFC_NAND_FCR0_CMD2_SHIFT) |
517 (NAND_CMD_STATUS <<
518 IFC_NAND_FCR0_CMD3_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530519
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530520 ifc_out32(&ifc->ifc_nand.nand_fir0,
521 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
522 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP1_SHIFT) |
523 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP2_SHIFT) |
524 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
525 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT));
526 ifc_out32(&ifc->ifc_nand.nand_fir1,
527 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
528 (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
529 (IFC_FIR_OP_RDSTAT <<
Prabhakar Kushwaha18e6bde2013-10-03 11:35:35 +0530530 IFC_NAND_FIR1_OP7_SHIFT) |
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530531 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT));
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530532
Prabhakar Kushwaha0ed5e772012-01-20 18:39:05 +0530533 if (column >= mtd->writesize)
534 nand_fcr0 |=
535 NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
536 else
537 nand_fcr0 |=
538 NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530539 }
540
Prabhakar Kushwaha0ed5e772012-01-20 18:39:05 +0530541 if (column >= mtd->writesize) {
542 /* OOB area --> READOOB */
543 column -= mtd->writesize;
544 ctrl->oob = 1;
545 }
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530546 ifc_out32(&ifc->ifc_nand.nand_fcr0, nand_fcr0);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530547 set_addr(mtd, column, page_addr, ctrl->oob);
548 return;
549 }
550
551 /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
552 case NAND_CMD_PAGEPROG:
553 if (ctrl->oob)
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530554 ifc_out32(&ifc->ifc_nand.nand_fbcr,
555 ctrl->index - ctrl->column);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530556 else
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530557 ifc_out32(&ifc->ifc_nand.nand_fbcr, 0);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530558
559 fsl_ifc_run_command(mtd);
560 return;
561
562 case NAND_CMD_STATUS:
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530563 ifc_out32(&ifc->ifc_nand.nand_fir0,
564 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
565 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP1_SHIFT));
566 ifc_out32(&ifc->ifc_nand.nand_fcr0,
567 NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT);
568 ifc_out32(&ifc->ifc_nand.nand_fbcr, 1);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530569 set_addr(mtd, 0, 0, 0);
570 ctrl->read_bytes = 1;
571
572 fsl_ifc_run_command(mtd);
573
574 /* Chip sometimes reporting write protect even when it's not */
575 out_8(ctrl->addr, in_8(ctrl->addr) | NAND_STATUS_WP);
576 return;
577
578 case NAND_CMD_RESET:
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530579 ifc_out32(&ifc->ifc_nand.nand_fir0,
580 IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT);
581 ifc_out32(&ifc->ifc_nand.nand_fcr0,
582 NAND_CMD_RESET << IFC_NAND_FCR0_CMD0_SHIFT);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530583 fsl_ifc_run_command(mtd);
584 return;
585
586 default:
587 printf("%s: error, unsupported command 0x%x.\n",
588 __func__, command);
589 }
590}
591
592/*
593 * Write buf to the IFC NAND Controller Data Buffer
594 */
595static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
596{
597 struct nand_chip *chip = mtd->priv;
598 struct fsl_ifc_mtd *priv = chip->priv;
599 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
600 unsigned int bufsize = mtd->writesize + mtd->oobsize;
601
602 if (len <= 0) {
603 printf("%s of %d bytes", __func__, len);
604 ctrl->status = 0;
605 return;
606 }
607
608 if ((unsigned int)len > bufsize - ctrl->index) {
609 printf("%s beyond end of buffer "
610 "(%d requested, %u available)\n",
611 __func__, len, bufsize - ctrl->index);
612 len = bufsize - ctrl->index;
613 }
614
615 memcpy_toio(&ctrl->addr[ctrl->index], buf, len);
616 ctrl->index += len;
617}
618
619/*
620 * read a byte from either the IFC hardware buffer if it has any data left
621 * otherwise issue a command to read a single byte.
622 */
623static u8 fsl_ifc_read_byte(struct mtd_info *mtd)
624{
625 struct nand_chip *chip = mtd->priv;
626 struct fsl_ifc_mtd *priv = chip->priv;
627 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
628
629 /* If there are still bytes in the IFC buffer, then use the
630 * next byte. */
631 if (ctrl->index < ctrl->read_bytes)
632 return in_8(&ctrl->addr[ctrl->index++]);
633
634 printf("%s beyond end of buffer\n", __func__);
635 return ERR_BYTE;
636}
637
638/*
639 * Read two bytes from the IFC hardware buffer
640 * read function for 16-bit buswith
641 */
642static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd)
643{
644 struct nand_chip *chip = mtd->priv;
645 struct fsl_ifc_mtd *priv = chip->priv;
646 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
647 uint16_t data;
648
649 /*
650 * If there are still bytes in the IFC buffer, then use the
651 * next byte.
652 */
653 if (ctrl->index < ctrl->read_bytes) {
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530654 data = ifc_in16((uint16_t *)&ctrl->
655 addr[ctrl->index]);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530656 ctrl->index += 2;
657 return (uint8_t)data;
658 }
659
660 printf("%s beyond end of buffer\n", __func__);
661 return ERR_BYTE;
662}
663
664/*
665 * Read from the IFC Controller Data Buffer
666 */
667static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
668{
669 struct nand_chip *chip = mtd->priv;
670 struct fsl_ifc_mtd *priv = chip->priv;
671 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
672 int avail;
673
674 if (len < 0)
675 return;
676
677 avail = min((unsigned int)len, ctrl->read_bytes - ctrl->index);
678 memcpy_fromio(buf, &ctrl->addr[ctrl->index], avail);
679 ctrl->index += avail;
680
681 if (len > avail)
682 printf("%s beyond end of buffer "
683 "(%d requested, %d available)\n",
684 __func__, len, avail);
685}
686
687/*
688 * Verify buffer against the IFC Controller Data Buffer
689 */
690static int fsl_ifc_verify_buf(struct mtd_info *mtd,
691 const u_char *buf, int len)
692{
693 struct nand_chip *chip = mtd->priv;
694 struct fsl_ifc_mtd *priv = chip->priv;
695 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
696 int i;
697
698 if (len < 0) {
699 printf("%s of %d bytes", __func__, len);
700 return -EINVAL;
701 }
702
703 if ((unsigned int)len > ctrl->read_bytes - ctrl->index) {
704 printf("%s beyond end of buffer "
705 "(%d requested, %u available)\n",
706 __func__, len, ctrl->read_bytes - ctrl->index);
707
708 ctrl->index = ctrl->read_bytes;
709 return -EINVAL;
710 }
711
712 for (i = 0; i < len; i++)
713 if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i])
714 break;
715
716 ctrl->index += len;
717 return i == len && ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO;
718}
719
720/* This function is called after Program and Erase Operations to
721 * check for success or failure.
722 */
723static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
724{
725 struct fsl_ifc_mtd *priv = chip->priv;
726 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
727 struct fsl_ifc *ifc = ctrl->regs;
728 u32 nand_fsr;
729
730 if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
731 return NAND_STATUS_FAIL;
732
733 /* Use READ_STATUS command, but wait for the device to be ready */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530734 ifc_out32(&ifc->ifc_nand.nand_fir0,
735 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
736 (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT));
737 ifc_out32(&ifc->ifc_nand.nand_fcr0, NAND_CMD_STATUS <<
738 IFC_NAND_FCR0_CMD0_SHIFT);
739 ifc_out32(&ifc->ifc_nand.nand_fbcr, 1);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530740 set_addr(mtd, 0, 0, 0);
741 ctrl->read_bytes = 1;
742
743 fsl_ifc_run_command(mtd);
744
745 if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
746 return NAND_STATUS_FAIL;
747
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530748 nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530749
750 /* Chip sometimes reporting write protect even when it's not */
751 nand_fsr = nand_fsr | NAND_STATUS_WP;
752 return nand_fsr;
753}
754
Sergey Lapin3a38a552013-01-14 03:46:50 +0000755static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
756 uint8_t *buf, int oob_required, int page)
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530757{
758 struct fsl_ifc_mtd *priv = chip->priv;
759 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
760
761 fsl_ifc_read_buf(mtd, buf, mtd->writesize);
762 fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
763
764 if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
765 mtd->ecc_stats.failed++;
766
767 return 0;
768}
769
770/* ECC will be calculated automatically, and errors will be detected in
771 * waitfunc.
772 */
Sergey Lapin3a38a552013-01-14 03:46:50 +0000773static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
774 const uint8_t *buf, int oob_required)
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530775{
776 fsl_ifc_write_buf(mtd, buf, mtd->writesize);
777 fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
Sergey Lapin3a38a552013-01-14 03:46:50 +0000778
779 return 0;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530780}
781
782static void fsl_ifc_ctrl_init(void)
783{
784 ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL);
785 if (!ifc_ctrl)
786 return;
787
788 ifc_ctrl->regs = IFC_BASE_ADDR;
789
790 /* clear event registers */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530791 ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_stat, ~0U);
792 ifc_out32(&ifc_ctrl->regs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530793
794 /* Enable error and event for any detected errors */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530795 ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_en,
796 IFC_NAND_EVTER_EN_OPC_EN |
797 IFC_NAND_EVTER_EN_PGRDCMPL_EN |
798 IFC_NAND_EVTER_EN_FTOER_EN |
799 IFC_NAND_EVTER_EN_WPER_EN);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530800
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530801 ifc_out32(&ifc_ctrl->regs->ifc_nand.ncfgr, 0x0);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530802}
803
804static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
805{
806}
807
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +0530808static int fsl_ifc_sram_init(uint32_t ver)
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000809{
810 struct fsl_ifc *ifc = ifc_ctrl->regs;
811 uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +0530812 uint32_t ncfgr = 0;
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000813 long long end_tick;
814
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +0530815 if (ver > FSL_IFC_V1_1_0) {
816 ncfgr = ifc_in32(&ifc->ifc_nand.ncfgr);
817 ifc_out32(&ifc->ifc_nand.ncfgr, ncfgr | IFC_NAND_SRAM_INIT_EN);
818
819 /* wait for SRAM_INIT bit to be clear or timeout */
820 end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
821 while (end_tick > get_ticks()) {
822 ifc_ctrl->status =
823 ifc_in32(&ifc->ifc_nand.nand_evter_stat);
824
825 if (!(ifc_ctrl->status & IFC_NAND_SRAM_INIT_EN))
826 return 0;
827 }
828 printf("fsl-ifc: Failed to Initialise SRAM\n");
829 return 1;
830 }
831
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000832 cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
833
834 /* Save CSOR and CSOR_ext */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530835 csor = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor);
836 csor_ext = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor_ext);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000837
838 /* chage PageSize 8K and SpareSize 1K*/
839 csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530840 ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k);
841 ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000842
843 /* READID */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530844 ifc_out32(&ifc->ifc_nand.nand_fir0,
845 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
846 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
847 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
848 ifc_out32(&ifc->ifc_nand.nand_fcr0,
849 NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
850 ifc_out32(&ifc->ifc_nand.row3, 0x0);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000851
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530852 ifc_out32(&ifc->ifc_nand.nand_fbcr, 0x0);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000853
854 /* Program ROW0/COL0 */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530855 ifc_out32(&ifc->ifc_nand.row0, 0x0);
856 ifc_out32(&ifc->ifc_nand.col0, 0x0);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000857
858 /* set the chip select for NAND Transaction */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530859 ifc_out32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000860
861 /* start read seq */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530862 ifc_out32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000863
864 /* wait for NAND Machine complete flag or timeout */
865 end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
866
867 while (end_tick > get_ticks()) {
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530868 ifc_ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000869
870 if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
871 break;
872 }
873
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +0530874 if (ifc_ctrl->status != IFC_NAND_EVTER_STAT_OPC) {
875 printf("fsl-ifc: Failed to Initialise SRAM\n");
876 return 1;
877 }
878
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530879 ifc_out32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000880
881 /* Restore CSOR and CSOR_ext */
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530882 ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor);
883 ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +0530884
885 return 0;
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000886}
887
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +0000888static int fsl_ifc_chip_init(int devnum, u8 *addr)
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530889{
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +0000890 struct mtd_info *mtd = &nand_info[devnum];
891 struct nand_chip *nand;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530892 struct fsl_ifc_mtd *priv;
893 struct nand_ecclayout *layout;
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +0000894 uint32_t cspr = 0, csor = 0, ver = 0;
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +0530895 int ret = 0;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530896
897 if (!ifc_ctrl) {
898 fsl_ifc_ctrl_init();
899 if (!ifc_ctrl)
900 return -1;
901 }
902
903 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
904 if (!priv)
905 return -ENOMEM;
906
907 priv->ctrl = ifc_ctrl;
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +0000908 priv->vbase = addr;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530909
910 /* Find which chip select it is connected to.
911 */
912 for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) {
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +0000913 phys_addr_t phys_addr = virt_to_phys(addr);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530914
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +0530915 cspr = ifc_in32(&ifc_ctrl->regs->cspr_cs[priv->bank].cspr);
916 csor = ifc_in32(&ifc_ctrl->regs->csor_cs[priv->bank].csor);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530917
918 if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND &&
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +0000919 (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) {
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530920 ifc_ctrl->cs_nand = priv->bank << IFC_NAND_CSEL_SHIFT;
921 break;
922 }
923 }
924
925 if (priv->bank >= MAX_BANKS) {
926 printf("%s: address did not match any "
927 "chip selects\n", __func__);
Prabhakar Kushwahaae25e882012-04-10 22:48:27 +0000928 kfree(priv);
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530929 return -ENODEV;
930 }
931
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +0000932 nand = &priv->chip;
933 mtd->priv = nand;
934
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530935 ifc_ctrl->chips[priv->bank] = priv;
936
937 /* fill in nand_chip structure */
938 /* set up function call table */
939
940 nand->write_buf = fsl_ifc_write_buf;
941 nand->read_buf = fsl_ifc_read_buf;
942 nand->verify_buf = fsl_ifc_verify_buf;
943 nand->select_chip = fsl_ifc_select_chip;
944 nand->cmdfunc = fsl_ifc_cmdfunc;
945 nand->waitfunc = fsl_ifc_wait;
946
947 /* set up nand options */
948 nand->bbt_td = &bbt_main_descr;
949 nand->bbt_md = &bbt_mirror_descr;
950
951 /* set up nand options */
Sergey Lapin3a38a552013-01-14 03:46:50 +0000952 nand->options = NAND_NO_SUBPAGE_WRITE;
953 nand->bbt_options = NAND_BBT_USE_FLASH;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530954
955 if (cspr & CSPR_PORT_SIZE_16) {
956 nand->read_byte = fsl_ifc_read_byte16;
957 nand->options |= NAND_BUSWIDTH_16;
958 } else {
959 nand->read_byte = fsl_ifc_read_byte;
960 }
961
962 nand->controller = &ifc_ctrl->controller;
963 nand->priv = priv;
964
965 nand->ecc.read_page = fsl_ifc_read_page;
966 nand->ecc.write_page = fsl_ifc_write_page;
967
968 /* Hardware generates ECC per 512 Bytes */
969 nand->ecc.size = 512;
970 nand->ecc.bytes = 8;
971
972 switch (csor & CSOR_NAND_PGS_MASK) {
973 case CSOR_NAND_PGS_512:
974 if (nand->options & NAND_BUSWIDTH_16) {
975 layout = &oob_512_16bit_ecc4;
976 } else {
977 layout = &oob_512_8bit_ecc4;
978
979 /* Avoid conflict with bad block marker */
980 bbt_main_descr.offs = 0;
981 bbt_mirror_descr.offs = 0;
982 }
983
Sergey Lapin3a38a552013-01-14 03:46:50 +0000984 nand->ecc.strength = 4;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530985 priv->bufnum_mask = 15;
986 break;
987
988 case CSOR_NAND_PGS_2K:
989 layout = &oob_2048_ecc4;
Sergey Lapin3a38a552013-01-14 03:46:50 +0000990 nand->ecc.strength = 4;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530991 priv->bufnum_mask = 3;
992 break;
993
994 case CSOR_NAND_PGS_4K:
995 if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
996 CSOR_NAND_ECC_MODE_4) {
997 layout = &oob_4096_ecc4;
Sergey Lapin3a38a552013-01-14 03:46:50 +0000998 nand->ecc.strength = 4;
Dipen Dudhat9eae0832011-03-22 09:27:39 +0530999 } else {
1000 layout = &oob_4096_ecc8;
Sergey Lapin3a38a552013-01-14 03:46:50 +00001001 nand->ecc.strength = 8;
Dipen Dudhat9eae0832011-03-22 09:27:39 +05301002 nand->ecc.bytes = 16;
1003 }
1004
1005 priv->bufnum_mask = 1;
1006 break;
1007
Prabhakar Kushwahaa3aaf1d2013-10-04 10:05:36 +05301008 case CSOR_NAND_PGS_8K:
1009 if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
1010 CSOR_NAND_ECC_MODE_4) {
1011 layout = &oob_8192_ecc4;
1012 nand->ecc.strength = 4;
1013 } else {
1014 layout = &oob_8192_ecc8;
1015 nand->ecc.strength = 8;
1016 nand->ecc.bytes = 16;
1017 }
1018
1019 priv->bufnum_mask = 0;
1020 break;
1021
1022
Dipen Dudhat9eae0832011-03-22 09:27:39 +05301023 default:
1024 printf("ifc nand: bad csor %#x: bad page size\n", csor);
1025 return -ENODEV;
1026 }
1027
1028 /* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */
1029 if (csor & CSOR_NAND_ECC_DEC_EN) {
1030 nand->ecc.mode = NAND_ECC_HW;
1031 nand->ecc.layout = layout;
1032 } else {
1033 nand->ecc.mode = NAND_ECC_SOFT;
1034 }
1035
Prabhakar Kushwaha62908c22014-01-18 12:28:30 +05301036 ver = ifc_in32(&ifc_ctrl->regs->ifc_rev);
Prabhakar Kushwaha82efc812014-06-12 12:14:00 +05301037 if (ver >= FSL_IFC_V1_1_0)
1038 ret = fsl_ifc_sram_init(ver);
1039 if (ret)
1040 return ret;
Prabhakar Kushwahadccbf352012-09-12 22:26:05 +00001041
Prabhakar Kushwaha5c23a822014-06-14 08:48:19 +05301042 if (ver >= FSL_IFC_V2_0_0)
1043 priv->bufnum_mask = (priv->bufnum_mask * 2) + 1;
1044
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +00001045 ret = nand_scan_ident(mtd, 1, NULL);
1046 if (ret)
1047 return ret;
1048
1049 ret = nand_scan_tail(mtd);
1050 if (ret)
1051 return ret;
1052
1053 ret = nand_register(devnum);
1054 if (ret)
1055 return ret;
Dipen Dudhat9eae0832011-03-22 09:27:39 +05301056 return 0;
1057}
Prabhakar Kushwaha895d0392013-04-04 18:44:06 +00001058
1059#ifndef CONFIG_SYS_NAND_BASE_LIST
1060#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
1061#endif
1062
1063static unsigned long base_address[CONFIG_SYS_MAX_NAND_DEVICE] =
1064 CONFIG_SYS_NAND_BASE_LIST;
1065
1066void board_nand_init(void)
1067{
1068 int i;
1069
1070 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
1071 fsl_ifc_chip_init(i, (u8 *)base_address[i]);
1072}