blob: 43f5a3a4873f247d2e01e5c24dde49b3c607b3ed [file] [log] [blame]
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301/*
2 * Freescale Integrated Flash Controller NAND driver
3 *
4 * Copyright 2011-2012 Freescale Semiconductor, Inc
5 *
6 * Author: Dipen Dudhat <Dipen.Dudhat@freescale.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/module.h>
24#include <linux/types.h>
Prabhakar Kushwaha82771882012-03-15 11:04:23 +053025#include <linux/kernel.h>
Rob Herring5af50732013-09-17 14:28:33 -050026#include <linux/of_address.h>
Prabhakar Kushwaha82771882012-03-15 11:04:23 +053027#include <linux/slab.h>
28#include <linux/mtd/mtd.h>
29#include <linux/mtd/nand.h>
30#include <linux/mtd/partitions.h>
31#include <linux/mtd/nand_ecc.h>
Prabhakar Kushwahad2ae2e22014-01-17 11:15:16 +053032#include <linux/fsl_ifc.h>
Prabhakar Kushwaha82771882012-03-15 11:04:23 +053033
34#define ERR_BYTE 0xFF /* Value returned for read
35 bytes when read failed */
36#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait
37 for IFC NAND Machine */
38
39struct fsl_ifc_ctrl;
40
41/* mtd information per set */
42struct fsl_ifc_mtd {
Prabhakar Kushwaha82771882012-03-15 11:04:23 +053043 struct nand_chip chip;
44 struct fsl_ifc_ctrl *ctrl;
45
46 struct device *dev;
47 int bank; /* Chip select bank number */
48 unsigned int bufnum_mask; /* bufnum = page & bufnum_mask */
49 u8 __iomem *vbase; /* Chip select base virtual address */
50};
51
52/* overview of the fsl ifc controller */
53struct fsl_ifc_nand_ctrl {
54 struct nand_hw_control controller;
55 struct fsl_ifc_mtd *chips[FSL_IFC_BANK_COUNT];
56
Aaron Sierra44544062014-04-07 11:58:12 -050057 void __iomem *addr; /* Address of assigned IFC buffer */
Prabhakar Kushwaha82771882012-03-15 11:04:23 +053058 unsigned int page; /* Last page written to / read from */
59 unsigned int read_bytes;/* Number of bytes read during command */
60 unsigned int column; /* Saved column from SEQIN */
61 unsigned int index; /* Pointer to next byte to 'read' */
62 unsigned int oob; /* Non zero if operating on OOB data */
63 unsigned int eccread; /* Non zero for a full-page ECC read */
64 unsigned int counter; /* counter for the initializations */
Mike Dunn3f91e942012-04-25 12:06:09 -070065 unsigned int max_bitflips; /* Saved during READ0 cmd */
Prabhakar Kushwaha82771882012-03-15 11:04:23 +053066};
67
68static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl;
69
70/* 512-byte page with 4-bit ECC, 8-bit */
71static struct nand_ecclayout oob_512_8bit_ecc4 = {
72 .eccbytes = 8,
73 .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
74 .oobfree = { {0, 5}, {6, 2} },
75};
76
77/* 512-byte page with 4-bit ECC, 16-bit */
78static struct nand_ecclayout oob_512_16bit_ecc4 = {
79 .eccbytes = 8,
80 .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
81 .oobfree = { {2, 6}, },
82};
83
84/* 2048-byte page size with 4-bit ECC */
85static struct nand_ecclayout oob_2048_ecc4 = {
86 .eccbytes = 32,
87 .eccpos = {
88 8, 9, 10, 11, 12, 13, 14, 15,
89 16, 17, 18, 19, 20, 21, 22, 23,
90 24, 25, 26, 27, 28, 29, 30, 31,
91 32, 33, 34, 35, 36, 37, 38, 39,
92 },
93 .oobfree = { {2, 6}, {40, 24} },
94};
95
96/* 4096-byte page size with 4-bit ECC */
97static struct nand_ecclayout oob_4096_ecc4 = {
98 .eccbytes = 64,
99 .eccpos = {
100 8, 9, 10, 11, 12, 13, 14, 15,
101 16, 17, 18, 19, 20, 21, 22, 23,
102 24, 25, 26, 27, 28, 29, 30, 31,
103 32, 33, 34, 35, 36, 37, 38, 39,
104 40, 41, 42, 43, 44, 45, 46, 47,
105 48, 49, 50, 51, 52, 53, 54, 55,
106 56, 57, 58, 59, 60, 61, 62, 63,
107 64, 65, 66, 67, 68, 69, 70, 71,
108 },
109 .oobfree = { {2, 6}, {72, 56} },
110};
111
112/* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */
113static struct nand_ecclayout oob_4096_ecc8 = {
114 .eccbytes = 128,
115 .eccpos = {
116 8, 9, 10, 11, 12, 13, 14, 15,
117 16, 17, 18, 19, 20, 21, 22, 23,
118 24, 25, 26, 27, 28, 29, 30, 31,
119 32, 33, 34, 35, 36, 37, 38, 39,
120 40, 41, 42, 43, 44, 45, 46, 47,
121 48, 49, 50, 51, 52, 53, 54, 55,
122 56, 57, 58, 59, 60, 61, 62, 63,
123 64, 65, 66, 67, 68, 69, 70, 71,
124 72, 73, 74, 75, 76, 77, 78, 79,
125 80, 81, 82, 83, 84, 85, 86, 87,
126 88, 89, 90, 91, 92, 93, 94, 95,
127 96, 97, 98, 99, 100, 101, 102, 103,
128 104, 105, 106, 107, 108, 109, 110, 111,
129 112, 113, 114, 115, 116, 117, 118, 119,
130 120, 121, 122, 123, 124, 125, 126, 127,
131 128, 129, 130, 131, 132, 133, 134, 135,
132 },
133 .oobfree = { {2, 6}, {136, 82} },
134};
135
Prabhakar Kushwahaebff90b2013-09-24 16:41:23 +0530136/* 8192-byte page size with 4-bit ECC */
137static struct nand_ecclayout oob_8192_ecc4 = {
138 .eccbytes = 128,
139 .eccpos = {
140 8, 9, 10, 11, 12, 13, 14, 15,
141 16, 17, 18, 19, 20, 21, 22, 23,
142 24, 25, 26, 27, 28, 29, 30, 31,
143 32, 33, 34, 35, 36, 37, 38, 39,
144 40, 41, 42, 43, 44, 45, 46, 47,
145 48, 49, 50, 51, 52, 53, 54, 55,
146 56, 57, 58, 59, 60, 61, 62, 63,
147 64, 65, 66, 67, 68, 69, 70, 71,
148 72, 73, 74, 75, 76, 77, 78, 79,
149 80, 81, 82, 83, 84, 85, 86, 87,
150 88, 89, 90, 91, 92, 93, 94, 95,
151 96, 97, 98, 99, 100, 101, 102, 103,
152 104, 105, 106, 107, 108, 109, 110, 111,
153 112, 113, 114, 115, 116, 117, 118, 119,
154 120, 121, 122, 123, 124, 125, 126, 127,
155 128, 129, 130, 131, 132, 133, 134, 135,
156 },
157 .oobfree = { {2, 6}, {136, 208} },
158};
159
160/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
161static struct nand_ecclayout oob_8192_ecc8 = {
162 .eccbytes = 256,
163 .eccpos = {
164 8, 9, 10, 11, 12, 13, 14, 15,
165 16, 17, 18, 19, 20, 21, 22, 23,
166 24, 25, 26, 27, 28, 29, 30, 31,
167 32, 33, 34, 35, 36, 37, 38, 39,
168 40, 41, 42, 43, 44, 45, 46, 47,
169 48, 49, 50, 51, 52, 53, 54, 55,
170 56, 57, 58, 59, 60, 61, 62, 63,
171 64, 65, 66, 67, 68, 69, 70, 71,
172 72, 73, 74, 75, 76, 77, 78, 79,
173 80, 81, 82, 83, 84, 85, 86, 87,
174 88, 89, 90, 91, 92, 93, 94, 95,
175 96, 97, 98, 99, 100, 101, 102, 103,
176 104, 105, 106, 107, 108, 109, 110, 111,
177 112, 113, 114, 115, 116, 117, 118, 119,
178 120, 121, 122, 123, 124, 125, 126, 127,
179 128, 129, 130, 131, 132, 133, 134, 135,
180 136, 137, 138, 139, 140, 141, 142, 143,
181 144, 145, 146, 147, 148, 149, 150, 151,
182 152, 153, 154, 155, 156, 157, 158, 159,
183 160, 161, 162, 163, 164, 165, 166, 167,
184 168, 169, 170, 171, 172, 173, 174, 175,
185 176, 177, 178, 179, 180, 181, 182, 183,
186 184, 185, 186, 187, 188, 189, 190, 191,
187 192, 193, 194, 195, 196, 197, 198, 199,
188 200, 201, 202, 203, 204, 205, 206, 207,
189 208, 209, 210, 211, 212, 213, 214, 215,
190 216, 217, 218, 219, 220, 221, 222, 223,
191 224, 225, 226, 227, 228, 229, 230, 231,
192 232, 233, 234, 235, 236, 237, 238, 239,
193 240, 241, 242, 243, 244, 245, 246, 247,
194 248, 249, 250, 251, 252, 253, 254, 255,
195 256, 257, 258, 259, 260, 261, 262, 263,
196 },
197 .oobfree = { {2, 6}, {264, 80} },
198};
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530199
200/*
201 * Generic flash bbt descriptors
202 */
203static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
204static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
205
206static struct nand_bbt_descr bbt_main_descr = {
207 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
208 NAND_BBT_2BIT | NAND_BBT_VERSION,
209 .offs = 2, /* 0 on 8-bit small page */
210 .len = 4,
211 .veroffs = 6,
212 .maxblocks = 4,
213 .pattern = bbt_pattern,
214};
215
216static struct nand_bbt_descr bbt_mirror_descr = {
217 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
218 NAND_BBT_2BIT | NAND_BBT_VERSION,
219 .offs = 2, /* 0 on 8-bit small page */
220 .len = 4,
221 .veroffs = 6,
222 .maxblocks = 4,
223 .pattern = mirror_pattern,
224};
225
226/*
227 * Set up the IFC hardware block and page address fields, and the ifc nand
228 * structure addr field to point to the correct IFC buffer in memory
229 */
230static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
231{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100232 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100233 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530234 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
235 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
236 int buf_num;
237
238 ifc_nand_ctrl->page = page_addr;
239 /* Program ROW0/COL0 */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500240 ifc_out32(page_addr, &ifc->ifc_nand.row0);
241 ifc_out32((oob ? IFC_NAND_COL_MS : 0) | column, &ifc->ifc_nand.col0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530242
243 buf_num = page_addr & priv->bufnum_mask;
244
245 ifc_nand_ctrl->addr = priv->vbase + buf_num * (mtd->writesize * 2);
246 ifc_nand_ctrl->index = column;
247
248 /* for OOB data point to the second half of the buffer */
249 if (oob)
250 ifc_nand_ctrl->index += mtd->writesize;
251}
252
253static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
254{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100255 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100256 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530257 u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
Kim Phillips2caf87a2012-09-13 18:56:07 -0500258 u32 __iomem *mainarea = (u32 __iomem *)addr;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530259 u8 __iomem *oob = addr + mtd->writesize;
260 int i;
261
262 for (i = 0; i < mtd->writesize / 4; i++) {
263 if (__raw_readl(&mainarea[i]) != 0xffffffff)
264 return 0;
265 }
266
267 for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
268 int pos = chip->ecc.layout->eccpos[i];
269
270 if (__raw_readb(&oob[pos]) != 0xff)
271 return 0;
272 }
273
274 return 1;
275}
276
277/* returns nonzero if entire page is blank */
278static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
279 u32 *eccstat, unsigned int bufnum)
280{
281 u32 reg = eccstat[bufnum / 4];
282 int errors;
283
284 errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
285
286 return errors;
287}
288
289/*
290 * execute IFC NAND command and wait for it to complete
291 */
292static void fsl_ifc_run_command(struct mtd_info *mtd)
293{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100294 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100295 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530296 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
297 struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
298 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
299 u32 eccstat[4];
300 int i;
301
302 /* set the chip select for NAND Transaction */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500303 ifc_out32(priv->bank << IFC_NAND_CSEL_SHIFT,
304 &ifc->ifc_nand.nand_csel);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530305
306 dev_vdbg(priv->dev,
307 "%s: fir0=%08x fcr0=%08x\n",
308 __func__,
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500309 ifc_in32(&ifc->ifc_nand.nand_fir0),
310 ifc_in32(&ifc->ifc_nand.nand_fcr0));
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530311
312 ctrl->nand_stat = 0;
313
314 /* start read/write seq */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500315 ifc_out32(IFC_NAND_SEQ_STRT_FIR_STRT, &ifc->ifc_nand.nandseq_strt);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530316
317 /* wait for command complete flag or timeout */
318 wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat,
Nicholas Mc Guire95d70662015-03-13 07:23:47 -0400319 msecs_to_jiffies(IFC_TIMEOUT_MSECS));
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530320
321 /* ctrl->nand_stat will be updated from IRQ context */
322 if (!ctrl->nand_stat)
323 dev_err(priv->dev, "Controller is not responding\n");
324 if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_FTOER)
325 dev_err(priv->dev, "NAND Flash Timeout Error\n");
326 if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER)
327 dev_err(priv->dev, "NAND Flash Write Protect Error\n");
328
Mike Dunn3f91e942012-04-25 12:06:09 -0700329 nctrl->max_bitflips = 0;
330
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530331 if (nctrl->eccread) {
332 int errors;
333 int bufnum = nctrl->page & priv->bufnum_mask;
334 int sector = bufnum * chip->ecc.steps;
335 int sector_end = sector + chip->ecc.steps - 1;
336
337 for (i = sector / 4; i <= sector_end / 4; i++)
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500338 eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530339
340 for (i = sector; i <= sector_end; i++) {
341 errors = check_read_ecc(mtd, ctrl, eccstat, i);
342
343 if (errors == 15) {
344 /*
345 * Uncorrectable error.
346 * OK only if the whole page is blank.
347 *
348 * We disable ECCER reporting due to...
349 * erratum IFC-A002770 -- so report it now if we
350 * see an uncorrectable error in ECCSTAT.
351 */
352 if (!is_blank(mtd, bufnum))
353 ctrl->nand_stat |=
354 IFC_NAND_EVTER_STAT_ECCER;
355 break;
356 }
357
358 mtd->ecc_stats.corrected += errors;
Mike Dunn3f91e942012-04-25 12:06:09 -0700359 nctrl->max_bitflips = max_t(unsigned int,
360 nctrl->max_bitflips,
361 errors);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530362 }
363
364 nctrl->eccread = 0;
365 }
366}
367
368static void fsl_ifc_do_read(struct nand_chip *chip,
369 int oob,
370 struct mtd_info *mtd)
371{
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100372 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530373 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
374 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
375
376 /* Program FIR/IFC_NAND_FCR0 for Small/Large page */
377 if (mtd->writesize > 512) {
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500378 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
379 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
380 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
381 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) |
382 (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP4_SHIFT),
383 &ifc->ifc_nand.nand_fir0);
384 ifc_out32(0x0, &ifc->ifc_nand.nand_fir1);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530385
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500386 ifc_out32((NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) |
387 (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT),
388 &ifc->ifc_nand.nand_fcr0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530389 } else {
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500390 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
391 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
392 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
393 (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP3_SHIFT),
394 &ifc->ifc_nand.nand_fir0);
395 ifc_out32(0x0, &ifc->ifc_nand.nand_fir1);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530396
397 if (oob)
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500398 ifc_out32(NAND_CMD_READOOB <<
399 IFC_NAND_FCR0_CMD0_SHIFT,
400 &ifc->ifc_nand.nand_fcr0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530401 else
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500402 ifc_out32(NAND_CMD_READ0 <<
403 IFC_NAND_FCR0_CMD0_SHIFT,
404 &ifc->ifc_nand.nand_fcr0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530405 }
406}
407
408/* cmdfunc send commands to the IFC NAND Machine */
409static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
410 int column, int page_addr) {
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100411 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100412 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530413 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
414 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
415
416 /* clear the read buffer */
417 ifc_nand_ctrl->read_bytes = 0;
418 if (command != NAND_CMD_PAGEPROG)
419 ifc_nand_ctrl->index = 0;
420
421 switch (command) {
422 /* READ0 read the entire buffer to use hardware ECC. */
423 case NAND_CMD_READ0:
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500424 ifc_out32(0, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530425 set_addr(mtd, 0, page_addr, 0);
426
427 ifc_nand_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
428 ifc_nand_ctrl->index += column;
429
430 if (chip->ecc.mode == NAND_ECC_HW)
431 ifc_nand_ctrl->eccread = 1;
432
433 fsl_ifc_do_read(chip, 0, mtd);
434 fsl_ifc_run_command(mtd);
435 return;
436
437 /* READOOB reads only the OOB because no ECC is performed. */
438 case NAND_CMD_READOOB:
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500439 ifc_out32(mtd->oobsize - column, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530440 set_addr(mtd, column, page_addr, 1);
441
442 ifc_nand_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
443
444 fsl_ifc_do_read(chip, 1, mtd);
445 fsl_ifc_run_command(mtd);
446
447 return;
448
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530449 case NAND_CMD_READID:
Prabhakar Kushwaha59fdd5b2012-04-09 10:55:22 +0530450 case NAND_CMD_PARAM: {
451 int timing = IFC_FIR_OP_RB;
452 if (command == NAND_CMD_PARAM)
453 timing = IFC_FIR_OP_RBCD;
454
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500455 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
456 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
457 (timing << IFC_NAND_FIR0_OP2_SHIFT),
458 &ifc->ifc_nand.nand_fir0);
459 ifc_out32(command << IFC_NAND_FCR0_CMD0_SHIFT,
460 &ifc->ifc_nand.nand_fcr0);
461 ifc_out32(column, &ifc->ifc_nand.row3);
Prabhakar Kushwaha59fdd5b2012-04-09 10:55:22 +0530462
463 /*
464 * although currently it's 8 bytes for READID, we always read
465 * the maximum 256 bytes(for PARAM)
466 */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500467 ifc_out32(256, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha59fdd5b2012-04-09 10:55:22 +0530468 ifc_nand_ctrl->read_bytes = 256;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530469
470 set_addr(mtd, 0, 0, 0);
471 fsl_ifc_run_command(mtd);
472 return;
Prabhakar Kushwaha59fdd5b2012-04-09 10:55:22 +0530473 }
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530474
475 /* ERASE1 stores the block and page address */
476 case NAND_CMD_ERASE1:
477 set_addr(mtd, 0, page_addr, 0);
478 return;
479
480 /* ERASE2 uses the block and page address from ERASE1 */
481 case NAND_CMD_ERASE2:
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500482 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
483 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP1_SHIFT) |
484 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP2_SHIFT),
485 &ifc->ifc_nand.nand_fir0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530486
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500487 ifc_out32((NAND_CMD_ERASE1 << IFC_NAND_FCR0_CMD0_SHIFT) |
488 (NAND_CMD_ERASE2 << IFC_NAND_FCR0_CMD1_SHIFT),
489 &ifc->ifc_nand.nand_fcr0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530490
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500491 ifc_out32(0, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530492 ifc_nand_ctrl->read_bytes = 0;
493 fsl_ifc_run_command(mtd);
494 return;
495
496 /* SEQIN sets up the addr buffer and all registers except the length */
497 case NAND_CMD_SEQIN: {
498 u32 nand_fcr0;
499 ifc_nand_ctrl->column = column;
500 ifc_nand_ctrl->oob = 0;
501
502 if (mtd->writesize > 512) {
503 nand_fcr0 =
504 (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
Prabhakar Kushwaha4af98742013-10-03 11:36:41 +0530505 (NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
506 (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530507
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500508 ifc_out32(
509 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
510 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
511 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
512 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) |
513 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT),
514 &ifc->ifc_nand.nand_fir0);
515 ifc_out32(
516 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
517 (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR1_OP6_SHIFT) |
518 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT),
519 &ifc->ifc_nand.nand_fir1);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530520 } else {
521 nand_fcr0 = ((NAND_CMD_PAGEPROG <<
522 IFC_NAND_FCR0_CMD1_SHIFT) |
523 (NAND_CMD_SEQIN <<
Prabhakar Kushwaha4af98742013-10-03 11:36:41 +0530524 IFC_NAND_FCR0_CMD2_SHIFT) |
525 (NAND_CMD_STATUS <<
526 IFC_NAND_FCR0_CMD3_SHIFT));
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530527
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500528 ifc_out32(
Kim Phillips0c69fb02013-01-11 16:23:59 -0600529 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
530 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP1_SHIFT) |
531 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP2_SHIFT) |
532 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
533 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT),
534 &ifc->ifc_nand.nand_fir0);
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500535 ifc_out32(
536 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
537 (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
538 (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR1_OP7_SHIFT) |
539 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT),
540 &ifc->ifc_nand.nand_fir1);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530541
542 if (column >= mtd->writesize)
543 nand_fcr0 |=
544 NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
545 else
546 nand_fcr0 |=
547 NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
548 }
549
550 if (column >= mtd->writesize) {
551 /* OOB area --> READOOB */
552 column -= mtd->writesize;
553 ifc_nand_ctrl->oob = 1;
554 }
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500555 ifc_out32(nand_fcr0, &ifc->ifc_nand.nand_fcr0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530556 set_addr(mtd, column, page_addr, ifc_nand_ctrl->oob);
557 return;
558 }
559
560 /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
561 case NAND_CMD_PAGEPROG: {
562 if (ifc_nand_ctrl->oob) {
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500563 ifc_out32(ifc_nand_ctrl->index -
564 ifc_nand_ctrl->column,
565 &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530566 } else {
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500567 ifc_out32(0, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530568 }
569
570 fsl_ifc_run_command(mtd);
571 return;
572 }
573
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500574 case NAND_CMD_STATUS: {
575 void __iomem *addr;
576
577 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
578 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP1_SHIFT),
579 &ifc->ifc_nand.nand_fir0);
580 ifc_out32(NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT,
581 &ifc->ifc_nand.nand_fcr0);
582 ifc_out32(1, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530583 set_addr(mtd, 0, 0, 0);
584 ifc_nand_ctrl->read_bytes = 1;
585
586 fsl_ifc_run_command(mtd);
587
588 /*
589 * The chip always seems to report that it is
590 * write-protected, even when it is not.
591 */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500592 addr = ifc_nand_ctrl->addr;
Joe Schultz21704802014-04-07 11:58:18 -0500593 if (chip->options & NAND_BUSWIDTH_16)
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500594 ifc_out16(ifc_in16(addr) | (NAND_STATUS_WP), addr);
Joe Schultz21704802014-04-07 11:58:18 -0500595 else
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500596 ifc_out8(ifc_in8(addr) | (NAND_STATUS_WP), addr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530597 return;
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500598 }
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530599
600 case NAND_CMD_RESET:
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500601 ifc_out32(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT,
602 &ifc->ifc_nand.nand_fir0);
603 ifc_out32(NAND_CMD_RESET << IFC_NAND_FCR0_CMD0_SHIFT,
604 &ifc->ifc_nand.nand_fcr0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530605 fsl_ifc_run_command(mtd);
606 return;
607
608 default:
609 dev_err(priv->dev, "%s: error, unsupported command 0x%x.\n",
610 __func__, command);
611 }
612}
613
614static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
615{
616 /* The hardware does not seem to support multiple
617 * chips per bank.
618 */
619}
620
621/*
622 * Write buf to the IFC NAND Controller Data Buffer
623 */
624static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
625{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100626 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100627 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530628 unsigned int bufsize = mtd->writesize + mtd->oobsize;
629
630 if (len <= 0) {
631 dev_err(priv->dev, "%s: len %d bytes", __func__, len);
632 return;
633 }
634
635 if ((unsigned int)len > bufsize - ifc_nand_ctrl->index) {
636 dev_err(priv->dev,
637 "%s: beyond end of buffer (%d requested, %u available)\n",
638 __func__, len, bufsize - ifc_nand_ctrl->index);
639 len = bufsize - ifc_nand_ctrl->index;
640 }
641
Aaron Sierra44544062014-04-07 11:58:12 -0500642 memcpy_toio(ifc_nand_ctrl->addr + ifc_nand_ctrl->index, buf, len);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530643 ifc_nand_ctrl->index += len;
644}
645
646/*
647 * Read a byte from either the IFC hardware buffer
648 * read function for 8-bit buswidth
649 */
650static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd)
651{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100652 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100653 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Aaron Sierra44544062014-04-07 11:58:12 -0500654 unsigned int offset;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530655
656 /*
657 * If there are still bytes in the IFC buffer, then use the
658 * next byte.
659 */
Aaron Sierra44544062014-04-07 11:58:12 -0500660 if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) {
661 offset = ifc_nand_ctrl->index++;
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500662 return ifc_in8(ifc_nand_ctrl->addr + offset);
Aaron Sierra44544062014-04-07 11:58:12 -0500663 }
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530664
665 dev_err(priv->dev, "%s: beyond end of buffer\n", __func__);
666 return ERR_BYTE;
667}
668
669/*
670 * Read two bytes from the IFC hardware buffer
671 * read function for 16-bit buswith
672 */
673static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd)
674{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100675 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100676 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530677 uint16_t data;
678
679 /*
680 * If there are still bytes in the IFC buffer, then use the
681 * next byte.
682 */
683 if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) {
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500684 data = ifc_in16(ifc_nand_ctrl->addr + ifc_nand_ctrl->index);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530685 ifc_nand_ctrl->index += 2;
686 return (uint8_t) data;
687 }
688
689 dev_err(priv->dev, "%s: beyond end of buffer\n", __func__);
690 return ERR_BYTE;
691}
692
693/*
694 * Read from the IFC Controller Data Buffer
695 */
696static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
697{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100698 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100699 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530700 int avail;
701
702 if (len < 0) {
703 dev_err(priv->dev, "%s: len %d bytes", __func__, len);
704 return;
705 }
706
707 avail = min((unsigned int)len,
708 ifc_nand_ctrl->read_bytes - ifc_nand_ctrl->index);
Aaron Sierra44544062014-04-07 11:58:12 -0500709 memcpy_fromio(buf, ifc_nand_ctrl->addr + ifc_nand_ctrl->index, avail);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530710 ifc_nand_ctrl->index += avail;
711
712 if (len > avail)
713 dev_err(priv->dev,
714 "%s: beyond end of buffer (%d requested, %d available)\n",
715 __func__, len, avail);
716}
717
718/*
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530719 * This function is called after Program and Erase Operations to
720 * check for success or failure.
721 */
722static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
723{
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100724 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530725 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
726 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
727 u32 nand_fsr;
728
729 /* Use READ_STATUS command, but wait for the device to be ready */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500730 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
731 (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT),
732 &ifc->ifc_nand.nand_fir0);
733 ifc_out32(NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT,
734 &ifc->ifc_nand.nand_fcr0);
735 ifc_out32(1, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530736 set_addr(mtd, 0, 0, 0);
737 ifc_nand_ctrl->read_bytes = 1;
738
739 fsl_ifc_run_command(mtd);
740
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500741 nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530742
743 /*
744 * The chip always seems to report that it is
745 * write-protected, even when it is not.
746 */
747 return nand_fsr | NAND_STATUS_WP;
748}
749
Brian Norris1fbb9382012-05-02 10:14:55 -0700750static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
751 uint8_t *buf, int oob_required, int page)
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530752{
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100753 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530754 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
Mike Dunn3f91e942012-04-25 12:06:09 -0700755 struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530756
757 fsl_ifc_read_buf(mtd, buf, mtd->writesize);
Brian Norrisa6976cd2012-05-02 10:15:01 -0700758 if (oob_required)
759 fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530760
761 if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_ECCER)
762 dev_err(priv->dev, "NAND Flash ECC Uncorrectable Error\n");
763
764 if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
765 mtd->ecc_stats.failed++;
766
Mike Dunn3f91e942012-04-25 12:06:09 -0700767 return nctrl->max_bitflips;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530768}
769
770/* ECC will be calculated automatically, and errors will be detected in
771 * waitfunc.
772 */
Josh Wufdbad98d2012-06-25 18:07:45 +0800773static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
Boris BREZILLON45aaeff2015-10-13 11:22:18 +0200774 const uint8_t *buf, int oob_required, int page)
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530775{
776 fsl_ifc_write_buf(mtd, buf, mtd->writesize);
777 fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
Josh Wufdbad98d2012-06-25 18:07:45 +0800778
779 return 0;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530780}
781
782static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
783{
Boris BREZILLON4bd4ebc2015-12-01 12:03:04 +0100784 struct nand_chip *chip = mtd_to_nand(mtd);
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100785 struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530786
787 dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
788 chip->numchips);
789 dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
790 chip->chipsize);
791 dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
792 chip->pagemask);
793 dev_dbg(priv->dev, "%s: nand->chip_delay = %d\n", __func__,
794 chip->chip_delay);
795 dev_dbg(priv->dev, "%s: nand->badblockpos = %d\n", __func__,
796 chip->badblockpos);
797 dev_dbg(priv->dev, "%s: nand->chip_shift = %d\n", __func__,
798 chip->chip_shift);
799 dev_dbg(priv->dev, "%s: nand->page_shift = %d\n", __func__,
800 chip->page_shift);
801 dev_dbg(priv->dev, "%s: nand->phys_erase_shift = %d\n", __func__,
802 chip->phys_erase_shift);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530803 dev_dbg(priv->dev, "%s: nand->ecc.mode = %d\n", __func__,
804 chip->ecc.mode);
805 dev_dbg(priv->dev, "%s: nand->ecc.steps = %d\n", __func__,
806 chip->ecc.steps);
807 dev_dbg(priv->dev, "%s: nand->ecc.bytes = %d\n", __func__,
808 chip->ecc.bytes);
809 dev_dbg(priv->dev, "%s: nand->ecc.total = %d\n", __func__,
810 chip->ecc.total);
811 dev_dbg(priv->dev, "%s: nand->ecc.layout = %p\n", __func__,
812 chip->ecc.layout);
813 dev_dbg(priv->dev, "%s: mtd->flags = %08x\n", __func__, mtd->flags);
814 dev_dbg(priv->dev, "%s: mtd->size = %lld\n", __func__, mtd->size);
815 dev_dbg(priv->dev, "%s: mtd->erasesize = %d\n", __func__,
816 mtd->erasesize);
817 dev_dbg(priv->dev, "%s: mtd->writesize = %d\n", __func__,
818 mtd->writesize);
819 dev_dbg(priv->dev, "%s: mtd->oobsize = %d\n", __func__,
820 mtd->oobsize);
821
822 return 0;
823}
824
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530825static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
826{
827 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
828 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
829 uint32_t csor = 0, csor_8k = 0, csor_ext = 0;
830 uint32_t cs = priv->bank;
831
832 /* Save CSOR and CSOR_ext */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500833 csor = ifc_in32(&ifc->csor_cs[cs].csor);
834 csor_ext = ifc_in32(&ifc->csor_cs[cs].csor_ext);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530835
836 /* chage PageSize 8K and SpareSize 1K*/
837 csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500838 ifc_out32(csor_8k, &ifc->csor_cs[cs].csor);
839 ifc_out32(0x0000400, &ifc->csor_cs[cs].csor_ext);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530840
841 /* READID */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500842 ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
843 (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
844 (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT),
845 &ifc->ifc_nand.nand_fir0);
846 ifc_out32(NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT,
847 &ifc->ifc_nand.nand_fcr0);
848 ifc_out32(0x0, &ifc->ifc_nand.row3);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530849
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500850 ifc_out32(0x0, &ifc->ifc_nand.nand_fbcr);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530851
852 /* Program ROW0/COL0 */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500853 ifc_out32(0x0, &ifc->ifc_nand.row0);
854 ifc_out32(0x0, &ifc->ifc_nand.col0);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530855
856 /* set the chip select for NAND Transaction */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500857 ifc_out32(cs << IFC_NAND_CSEL_SHIFT, &ifc->ifc_nand.nand_csel);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530858
859 /* start read seq */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500860 ifc_out32(IFC_NAND_SEQ_STRT_FIR_STRT, &ifc->ifc_nand.nandseq_strt);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530861
862 /* wait for command complete flag or timeout */
863 wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat,
Nicholas Mc Guire95d70662015-03-13 07:23:47 -0400864 msecs_to_jiffies(IFC_TIMEOUT_MSECS));
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530865
866 if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
867 printk(KERN_ERR "fsl-ifc: Failed to Initialise SRAM\n");
868
869 /* Restore CSOR and CSOR_ext */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500870 ifc_out32(csor, &ifc->csor_cs[cs].csor);
871 ifc_out32(csor_ext, &ifc->csor_cs[cs].csor_ext);
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530872}
873
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530874static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
875{
876 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
877 struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
878 struct nand_chip *chip = &priv->chip;
Boris BREZILLON5e9fb932015-12-10 09:00:03 +0100879 struct mtd_info *mtd = nand_to_mtd(&priv->chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530880 struct nand_ecclayout *layout;
Aaron Sierra09691662014-08-26 18:18:33 -0500881 u32 csor;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530882
883 /* Fill in fsl_ifc_mtd structure */
Boris BREZILLON5e9fb932015-12-10 09:00:03 +0100884 mtd->dev.parent = priv->dev;
Brian Norrisa61ae812015-10-30 20:33:25 -0700885 nand_set_flash_node(chip, priv->dev->of_node);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530886
887 /* fill in nand_chip structure */
888 /* set up function call table */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500889 if ((ifc_in32(&ifc->cspr_cs[priv->bank].cspr)) & CSPR_PORT_SIZE_16)
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530890 chip->read_byte = fsl_ifc_read_byte16;
891 else
892 chip->read_byte = fsl_ifc_read_byte;
893
894 chip->write_buf = fsl_ifc_write_buf;
895 chip->read_buf = fsl_ifc_read_buf;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530896 chip->select_chip = fsl_ifc_select_chip;
897 chip->cmdfunc = fsl_ifc_cmdfunc;
898 chip->waitfunc = fsl_ifc_wait;
899
900 chip->bbt_td = &bbt_main_descr;
901 chip->bbt_md = &bbt_mirror_descr;
902
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500903 ifc_out32(0x0, &ifc->ifc_nand.ncfgr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530904
905 /* set up nand options */
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530906 chip->bbt_options = NAND_BBT_USE_FLASH;
Scott Wood20cd0002013-04-10 17:34:37 -0500907 chip->options = NAND_NO_SUBPAGE_WRITE;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530908
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500909 if (ifc_in32(&ifc->cspr_cs[priv->bank].cspr) & CSPR_PORT_SIZE_16) {
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530910 chip->read_byte = fsl_ifc_read_byte16;
911 chip->options |= NAND_BUSWIDTH_16;
912 } else {
913 chip->read_byte = fsl_ifc_read_byte;
914 }
915
916 chip->controller = &ifc_nand_ctrl->controller;
Boris BREZILLONd699ed22015-12-10 09:00:41 +0100917 nand_set_controller_data(chip, priv);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530918
919 chip->ecc.read_page = fsl_ifc_read_page;
920 chip->ecc.write_page = fsl_ifc_write_page;
921
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -0500922 csor = ifc_in32(&ifc->csor_cs[priv->bank].csor);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530923
924 /* Hardware generates ECC per 512 Bytes */
925 chip->ecc.size = 512;
926 chip->ecc.bytes = 8;
Mike Dunn44df4d12012-04-25 12:06:06 -0700927 chip->ecc.strength = 4;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530928
929 switch (csor & CSOR_NAND_PGS_MASK) {
930 case CSOR_NAND_PGS_512:
931 if (chip->options & NAND_BUSWIDTH_16) {
932 layout = &oob_512_16bit_ecc4;
933 } else {
934 layout = &oob_512_8bit_ecc4;
935
936 /* Avoid conflict with bad block marker */
937 bbt_main_descr.offs = 0;
938 bbt_mirror_descr.offs = 0;
939 }
940
941 priv->bufnum_mask = 15;
942 break;
943
944 case CSOR_NAND_PGS_2K:
945 layout = &oob_2048_ecc4;
946 priv->bufnum_mask = 3;
947 break;
948
949 case CSOR_NAND_PGS_4K:
950 if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
951 CSOR_NAND_ECC_MODE_4) {
952 layout = &oob_4096_ecc4;
953 } else {
954 layout = &oob_4096_ecc8;
955 chip->ecc.bytes = 16;
Prabhakar Kushwahaebff90b2013-09-24 16:41:23 +0530956 chip->ecc.strength = 8;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530957 }
958
959 priv->bufnum_mask = 1;
960 break;
961
Prabhakar Kushwahaebff90b2013-09-24 16:41:23 +0530962 case CSOR_NAND_PGS_8K:
963 if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
964 CSOR_NAND_ECC_MODE_4) {
965 layout = &oob_8192_ecc4;
966 } else {
967 layout = &oob_8192_ecc8;
968 chip->ecc.bytes = 16;
969 chip->ecc.strength = 8;
970 }
971
972 priv->bufnum_mask = 0;
973 break;
974
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530975 default:
976 dev_err(priv->dev, "bad csor %#x: bad page size\n", csor);
977 return -ENODEV;
978 }
979
980 /* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */
981 if (csor & CSOR_NAND_ECC_DEC_EN) {
982 chip->ecc.mode = NAND_ECC_HW;
983 chip->ecc.layout = layout;
984 } else {
985 chip->ecc.mode = NAND_ECC_SOFT;
986 }
987
Aaron Sierra09691662014-08-26 18:18:33 -0500988 if (ctrl->version == FSL_IFC_VERSION_1_1_0)
Prabhakar Kushwaha10bfa762012-09-13 14:24:49 +0530989 fsl_ifc_sram_init(priv);
990
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530991 return 0;
992}
993
994static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv)
995{
Boris BREZILLON5e9fb932015-12-10 09:00:03 +0100996 struct mtd_info *mtd = nand_to_mtd(&priv->chip);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +0530997
Boris BREZILLON5e9fb932015-12-10 09:00:03 +0100998 nand_release(mtd);
999
1000 kfree(mtd->name);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301001
1002 if (priv->vbase)
1003 iounmap(priv->vbase);
1004
1005 ifc_nand_ctrl->chips[priv->bank] = NULL;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301006
1007 return 0;
1008}
1009
1010static int match_bank(struct fsl_ifc_regs __iomem *ifc, int bank,
1011 phys_addr_t addr)
1012{
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -05001013 u32 cspr = ifc_in32(&ifc->cspr_cs[bank].cspr);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301014
1015 if (!(cspr & CSPR_V))
1016 return 0;
1017 if ((cspr & CSPR_MSEL) != CSPR_MSEL_NAND)
1018 return 0;
1019
1020 return (cspr & CSPR_BA) == convert_ifc_address(addr);
1021}
1022
1023static DEFINE_MUTEX(fsl_ifc_nand_mutex);
1024
Bill Pemberton06f25512012-11-19 13:23:07 -05001025static int fsl_ifc_nand_probe(struct platform_device *dev)
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301026{
1027 struct fsl_ifc_regs __iomem *ifc;
1028 struct fsl_ifc_mtd *priv;
1029 struct resource res;
1030 static const char *part_probe_types[]
1031 = { "cmdlinepart", "RedBoot", "ofpart", NULL };
1032 int ret;
1033 int bank;
1034 struct device_node *node = dev->dev.of_node;
Boris BREZILLON5e9fb932015-12-10 09:00:03 +01001035 struct mtd_info *mtd;
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301036
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301037 if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs)
1038 return -ENODEV;
1039 ifc = fsl_ifc_ctrl_dev->regs;
1040
1041 /* get, allocate and map the memory resource */
1042 ret = of_address_to_resource(node, 0, &res);
1043 if (ret) {
1044 dev_err(&dev->dev, "%s: failed to get resource\n", __func__);
1045 return ret;
1046 }
1047
1048 /* find which chip select it is connected to */
Aaron Sierra09691662014-08-26 18:18:33 -05001049 for (bank = 0; bank < fsl_ifc_ctrl_dev->banks; bank++) {
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301050 if (match_bank(ifc, bank, res.start))
1051 break;
1052 }
1053
Aaron Sierra09691662014-08-26 18:18:33 -05001054 if (bank >= fsl_ifc_ctrl_dev->banks) {
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301055 dev_err(&dev->dev, "%s: address did not match any chip selects\n",
1056 __func__);
1057 return -ENODEV;
1058 }
1059
1060 priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
1061 if (!priv)
1062 return -ENOMEM;
1063
1064 mutex_lock(&fsl_ifc_nand_mutex);
1065 if (!fsl_ifc_ctrl_dev->nand) {
1066 ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL);
1067 if (!ifc_nand_ctrl) {
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301068 mutex_unlock(&fsl_ifc_nand_mutex);
1069 return -ENOMEM;
1070 }
1071
1072 ifc_nand_ctrl->read_bytes = 0;
1073 ifc_nand_ctrl->index = 0;
1074 ifc_nand_ctrl->addr = NULL;
1075 fsl_ifc_ctrl_dev->nand = ifc_nand_ctrl;
1076
1077 spin_lock_init(&ifc_nand_ctrl->controller.lock);
1078 init_waitqueue_head(&ifc_nand_ctrl->controller.wq);
1079 } else {
1080 ifc_nand_ctrl = fsl_ifc_ctrl_dev->nand;
1081 }
1082 mutex_unlock(&fsl_ifc_nand_mutex);
1083
1084 ifc_nand_ctrl->chips[bank] = priv;
1085 priv->bank = bank;
1086 priv->ctrl = fsl_ifc_ctrl_dev;
1087 priv->dev = &dev->dev;
1088
1089 priv->vbase = ioremap(res.start, resource_size(&res));
1090 if (!priv->vbase) {
1091 dev_err(priv->dev, "%s: failed to map chip region\n", __func__);
1092 ret = -ENOMEM;
1093 goto err;
1094 }
1095
1096 dev_set_drvdata(priv->dev, priv);
1097
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -05001098 ifc_out32(IFC_NAND_EVTER_EN_OPC_EN |
1099 IFC_NAND_EVTER_EN_FTOER_EN |
1100 IFC_NAND_EVTER_EN_WPER_EN,
1101 &ifc->ifc_nand.nand_evter_en);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301102
1103 /* enable NAND Machine Interrupts */
Jaiprakash Singhcf184dc2015-05-20 21:17:11 -05001104 ifc_out32(IFC_NAND_EVTER_INTR_OPCIR_EN |
1105 IFC_NAND_EVTER_INTR_FTOERIR_EN |
1106 IFC_NAND_EVTER_INTR_WPERIR_EN,
1107 &ifc->ifc_nand.nand_evter_intr_en);
Boris BREZILLON5e9fb932015-12-10 09:00:03 +01001108
1109 mtd = nand_to_mtd(&priv->chip);
1110 mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start);
1111 if (!mtd->name) {
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301112 ret = -ENOMEM;
1113 goto err;
1114 }
1115
1116 ret = fsl_ifc_chip_init(priv);
1117 if (ret)
1118 goto err;
1119
Boris BREZILLON5e9fb932015-12-10 09:00:03 +01001120 ret = nand_scan_ident(mtd, 1, NULL);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301121 if (ret)
1122 goto err;
1123
Boris BREZILLON5e9fb932015-12-10 09:00:03 +01001124 ret = fsl_ifc_chip_init_tail(mtd);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301125 if (ret)
1126 goto err;
1127
Boris BREZILLON5e9fb932015-12-10 09:00:03 +01001128 ret = nand_scan_tail(mtd);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301129 if (ret)
1130 goto err;
1131
1132 /* First look for RedBoot table or partitions on the command
1133 * line, these take precedence over device tree information */
Boris BREZILLON5e9fb932015-12-10 09:00:03 +01001134 mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301135
1136 dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n",
1137 (unsigned long long)res.start, priv->bank);
1138 return 0;
1139
1140err:
1141 fsl_ifc_chip_remove(priv);
1142 return ret;
1143}
1144
1145static int fsl_ifc_nand_remove(struct platform_device *dev)
1146{
1147 struct fsl_ifc_mtd *priv = dev_get_drvdata(&dev->dev);
1148
1149 fsl_ifc_chip_remove(priv);
1150
1151 mutex_lock(&fsl_ifc_nand_mutex);
1152 ifc_nand_ctrl->counter--;
1153 if (!ifc_nand_ctrl->counter) {
1154 fsl_ifc_ctrl_dev->nand = NULL;
1155 kfree(ifc_nand_ctrl);
1156 }
1157 mutex_unlock(&fsl_ifc_nand_mutex);
1158
1159 return 0;
1160}
1161
1162static const struct of_device_id fsl_ifc_nand_match[] = {
1163 {
1164 .compatible = "fsl,ifc-nand",
1165 },
1166 {}
1167};
Luis de Bethencourt3f7f7a52015-09-18 00:12:30 +02001168MODULE_DEVICE_TABLE(of, fsl_ifc_nand_match);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301169
1170static struct platform_driver fsl_ifc_nand_driver = {
1171 .driver = {
1172 .name = "fsl,ifc-nand",
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301173 .of_match_table = fsl_ifc_nand_match,
1174 },
1175 .probe = fsl_ifc_nand_probe,
1176 .remove = fsl_ifc_nand_remove,
1177};
1178
Sachin Kamatc69ad0e2013-10-08 15:08:20 +05301179module_platform_driver(fsl_ifc_nand_driver);
Prabhakar Kushwaha82771882012-03-15 11:04:23 +05301180
1181MODULE_LICENSE("GPL");
1182MODULE_AUTHOR("Freescale");
1183MODULE_DESCRIPTION("Freescale Integrated Flash Controller MTD NAND driver");