blob: 9a9260caf4794dda9dd737224414bf80813549c7 [file] [log] [blame]
Ilya Yanok36fab992009-08-11 02:32:54 +04001/*
Scott Woodcfcbf8c2009-09-02 16:45:31 -05002 * Copyright 2004-2007 Freescale Semiconductor, Inc.
Ilya Yanok36fab992009-08-11 02:32:54 +04003 * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
4 * Copyright 2009 Ilya Yanok, <yanok@emcraft.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <common.h>
22#include <nand.h>
23#include <linux/err.h>
24#include <asm/io.h>
Stefano Babic58c758f2011-01-14 03:35:21 +000025#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35)
Ilya Yanok36fab992009-08-11 02:32:54 +040026#include <asm/arch/imx-regs.h>
27#endif
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +020028#include <fsl_nfc.h>
Ilya Yanok36fab992009-08-11 02:32:54 +040029
30#define DRIVER_NAME "mxc_nand"
31
Ilya Yanok36fab992009-08-11 02:32:54 +040032typedef enum {false, true} bool;
33
34struct mxc_nand_host {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +020035 struct mtd_info mtd;
36 struct nand_chip *nand;
Ilya Yanok36fab992009-08-11 02:32:54 +040037
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +020038 struct fsl_nfc_regs __iomem *regs;
39 int spare_only;
40 int status_request;
41 int pagesize_2k;
42 int clk_act;
43 uint16_t col_addr;
44 unsigned int page_addr;
Ilya Yanok36fab992009-08-11 02:32:54 +040045};
46
47static struct mxc_nand_host mxc_host;
48static struct mxc_nand_host *host = &mxc_host;
49
50/* Define delays in microsec for NAND device operations */
51#define TROP_US_DELAY 2000
52/* Macros to get byte and bit positions of ECC */
53#define COLPOS(x) ((x) >> 3)
54#define BITPOS(x) ((x) & 0xf)
55
56/* Define single bit Error positions in Main & Spare area */
57#define MAIN_SINGLEBIT_ERROR 0x4
58#define SPARE_SINGLEBIT_ERROR 0x1
59
60/* OOB placement block for use with hardware ecc generation */
John Rigbyb081c2e2010-01-26 19:24:18 -070061#if defined(MXC_NFC_V1)
62#ifndef CONFIG_SYS_NAND_LARGEPAGE
Ilya Yanok36fab992009-08-11 02:32:54 +040063static struct nand_ecclayout nand_hw_eccoob = {
64 .eccbytes = 5,
65 .eccpos = {6, 7, 8, 9, 10},
John Rigbyb081c2e2010-01-26 19:24:18 -070066 .oobfree = { {0, 5}, {11, 5}, }
Ilya Yanok36fab992009-08-11 02:32:54 +040067};
68#else
John Rigbyb081c2e2010-01-26 19:24:18 -070069static struct nand_ecclayout nand_hw_eccoob2k = {
70 .eccbytes = 20,
71 .eccpos = {
72 6, 7, 8, 9, 10,
73 22, 23, 24, 25, 26,
74 38, 39, 40, 41, 42,
75 54, 55, 56, 57, 58,
76 },
77 .oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} },
Ilya Yanok36fab992009-08-11 02:32:54 +040078};
79#endif
John Rigbyb081c2e2010-01-26 19:24:18 -070080#elif defined(MXC_NFC_V1_1)
81#ifndef CONFIG_SYS_NAND_LARGEPAGE
82static struct nand_ecclayout nand_hw_eccoob = {
83 .eccbytes = 9,
84 .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
85 .oobfree = { {2, 5} }
Magnus Liljac4832df2010-01-17 17:46:10 +010086};
John Rigbyb081c2e2010-01-26 19:24:18 -070087#else
88static struct nand_ecclayout nand_hw_eccoob2k = {
89 .eccbytes = 36,
90 .eccpos = {
91 7, 8, 9, 10, 11, 12, 13, 14, 15,
92 23, 24, 25, 26, 27, 28, 29, 30, 31,
93 39, 40, 41, 42, 43, 44, 45, 46, 47,
94 55, 56, 57, 58, 59, 60, 61, 62, 63,
95 },
96 .oobfree = { {2, 5}, {16, 7}, {32, 7}, {48, 7} },
97};
98#endif
99#endif
Magnus Liljac4832df2010-01-17 17:46:10 +0100100
Magnus Liljaf6a97482009-11-11 20:18:43 +0100101#ifdef CONFIG_MX27
102static int is_16bit_nand(void)
103{
104 struct system_control_regs *sc_regs =
105 (struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
106
107 if (readl(&sc_regs->fmcr) & NF_16BIT_SEL)
108 return 1;
109 else
110 return 0;
111}
112#elif defined(CONFIG_MX31)
113static int is_16bit_nand(void)
114{
115 struct clock_control_regs *sc_regs =
116 (struct clock_control_regs *)CCM_BASE;
117
118 if (readl(&sc_regs->rcsr) & CCM_RCSR_NF16B)
119 return 1;
120 else
121 return 0;
122}
Stefano Babic58c758f2011-01-14 03:35:21 +0000123#elif defined(CONFIG_MX25) || defined(CONFIG_MX35)
John Rigbyb081c2e2010-01-26 19:24:18 -0700124static int is_16bit_nand(void)
125{
126 struct ccm_regs *ccm =
127 (struct ccm_regs *)IMX_CCM_BASE;
128
129 if (readl(&ccm->rcsr) & CCM_RCSR_NF_16BIT_SEL)
130 return 1;
131 else
132 return 0;
133}
Magnus Liljaf6a97482009-11-11 20:18:43 +0100134#else
135#warning "8/16 bit NAND autodetection not supported"
136static int is_16bit_nand(void)
137{
138 return 0;
139}
140#endif
141
Ilya Yanok36fab992009-08-11 02:32:54 +0400142static uint32_t *mxc_nand_memcpy32(uint32_t *dest, uint32_t *source, size_t size)
143{
144 uint32_t *d = dest;
145
146 size >>= 2;
147 while (size--)
148 __raw_writel(__raw_readl(source++), d++);
149 return dest;
150}
151
152/*
153 * This function polls the NANDFC to wait for the basic operation to
154 * complete by checking the INT bit of config2 register.
155 */
156static void wait_op_done(struct mxc_nand_host *host, int max_retries,
157 uint16_t param)
158{
159 uint32_t tmp;
160
161 while (max_retries-- > 0) {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200162 if (readw(&host->regs->config2) & NFC_INT) {
163 tmp = readw(&host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400164 tmp &= ~NFC_INT;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200165 writew(tmp, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400166 break;
167 }
168 udelay(1);
169 }
170 if (max_retries < 0) {
171 MTDDEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
172 __func__, param);
173 }
174}
175
176/*
177 * This function issues the specified command to the NAND device and
178 * waits for completion.
179 */
180static void send_cmd(struct mxc_nand_host *host, uint16_t cmd)
181{
182 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd);
183
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200184 writew(cmd, &host->regs->flash_cmd);
185 writew(NFC_CMD, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400186
187 /* Wait for operation to complete */
188 wait_op_done(host, TROP_US_DELAY, cmd);
189}
190
191/*
192 * This function sends an address (or partial address) to the
193 * NAND device. The address is used to select the source/destination for
194 * a NAND command.
195 */
196static void send_addr(struct mxc_nand_host *host, uint16_t addr)
197{
198 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr);
199
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200200 writew(addr, &host->regs->flash_addr);
201 writew(NFC_ADDR, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400202
203 /* Wait for operation to complete */
204 wait_op_done(host, TROP_US_DELAY, addr);
205}
206
207/*
Helmut Raiger780f30b2011-07-06 09:40:28 +0200208 * This function requests the NANDFC to initiate the transfer
Ilya Yanok36fab992009-08-11 02:32:54 +0400209 * of data currently in the NANDFC RAM buffer to the NAND device.
210 */
211static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
212 int spare_only)
213{
John Rigbyb081c2e2010-01-26 19:24:18 -0700214 if (spare_only)
215 MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only);
216
217 if (is_mxc_nfc_11()) {
218 int i;
219 /*
220 * The controller copies the 64 bytes of spare data from
221 * the first 16 bytes of each of the 4 64 byte spare buffers.
222 * Copy the contiguous data starting in spare_area[0] to
223 * the four spare area buffers.
224 */
225 for (i = 1; i < 4; i++) {
226 void __iomem *src = &host->regs->spare_area[0][i * 16];
227 void __iomem *dst = &host->regs->spare_area[i][0];
228
229 mxc_nand_memcpy32(dst, src, 16);
230 }
231 }
Ilya Yanok36fab992009-08-11 02:32:54 +0400232
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200233 writew(buf_id, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400234
235 /* Configure spare or page+spare access */
236 if (!host->pagesize_2k) {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200237 uint16_t config1 = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400238 if (spare_only)
239 config1 |= NFC_SP_EN;
240 else
241 config1 &= ~(NFC_SP_EN);
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200242 writew(config1, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400243 }
244
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200245 writew(NFC_INPUT, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400246
247 /* Wait for operation to complete */
248 wait_op_done(host, TROP_US_DELAY, spare_only);
249}
250
251/*
Helmut Raiger780f30b2011-07-06 09:40:28 +0200252 * Requests NANDFC to initiate the transfer of data from the
Ilya Yanok36fab992009-08-11 02:32:54 +0400253 * NAND device into in the NANDFC ram buffer.
254 */
255static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
256 int spare_only)
257{
258 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
259
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200260 writew(buf_id, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400261
262 /* Configure spare or page+spare access */
263 if (!host->pagesize_2k) {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200264 uint32_t config1 = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400265 if (spare_only)
266 config1 |= NFC_SP_EN;
267 else
268 config1 &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200269 writew(config1, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400270 }
271
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200272 writew(NFC_OUTPUT, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400273
274 /* Wait for operation to complete */
275 wait_op_done(host, TROP_US_DELAY, spare_only);
John Rigbyb081c2e2010-01-26 19:24:18 -0700276
277 if (is_mxc_nfc_11()) {
278 int i;
279
280 /*
281 * The controller copies the 64 bytes of spare data to
282 * the first 16 bytes of each of the 4 spare buffers.
283 * Make the data contiguous starting in spare_area[0].
284 */
285 for (i = 1; i < 4; i++) {
286 void __iomem *src = &host->regs->spare_area[i][0];
287 void __iomem *dst = &host->regs->spare_area[0][i * 16];
288
289 mxc_nand_memcpy32(dst, src, 16);
290 }
291 }
Ilya Yanok36fab992009-08-11 02:32:54 +0400292}
293
294/* Request the NANDFC to perform a read of the NAND device ID. */
295static void send_read_id(struct mxc_nand_host *host)
296{
297 uint16_t tmp;
298
299 /* NANDFC buffer 0 is used for device ID output */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200300 writew(0x0, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400301
302 /* Read ID into main buffer */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200303 tmp = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400304 tmp &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200305 writew(tmp, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400306
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200307 writew(NFC_ID, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400308
309 /* Wait for operation to complete */
310 wait_op_done(host, TROP_US_DELAY, 0);
311}
312
313/*
314 * This function requests the NANDFC to perform a read of the
315 * NAND device status and returns the current status.
316 */
317static uint16_t get_dev_status(struct mxc_nand_host *host)
318{
John Rigbyb081c2e2010-01-26 19:24:18 -0700319 void __iomem *main_buf = host->regs->main_area[1];
Ilya Yanok36fab992009-08-11 02:32:54 +0400320 uint32_t store;
321 uint16_t ret, tmp;
322 /* Issue status request to NAND device */
323
324 /* store the main area1 first word, later do recovery */
325 store = readl(main_buf);
326 /* NANDFC buffer 1 is used for device status */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200327 writew(1, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400328
329 /* Read status into main buffer */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200330 tmp = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400331 tmp &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200332 writew(tmp, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400333
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200334 writew(NFC_STATUS, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400335
336 /* Wait for operation to complete */
337 wait_op_done(host, TROP_US_DELAY, 0);
338
339 /*
340 * Status is placed in first word of main buffer
341 * get status, then recovery area 1 data
342 */
343 ret = readw(main_buf);
344 writel(store, main_buf);
345
346 return ret;
347}
348
349/* This function is used by upper layer to checks if device is ready */
350static int mxc_nand_dev_ready(struct mtd_info *mtd)
351{
352 /*
353 * NFC handles R/B internally. Therefore, this function
354 * always returns status as ready.
355 */
356 return 1;
357}
358
359#ifdef CONFIG_MXC_NAND_HWECC
360static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
361{
362 /*
363 * If HW ECC is enabled, we turn it on during init. There is
364 * no need to enable again here.
365 */
366}
367
John Rigbyb081c2e2010-01-26 19:24:18 -0700368#ifdef MXC_NFC_V1_1
369static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on)
370{
371 struct nand_chip *nand_chip = mtd->priv;
372 struct mxc_nand_host *host = nand_chip->priv;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200373 uint16_t tmp = readw(&host->regs->config1);
John Rigbyb081c2e2010-01-26 19:24:18 -0700374
375 if (on)
376 tmp |= NFC_ECC_EN;
377 else
378 tmp &= ~NFC_ECC_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200379 writew(tmp, &host->regs->config1);
John Rigbyb081c2e2010-01-26 19:24:18 -0700380}
381
382static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
383 struct nand_chip *chip,
384 int page, int sndcmd)
385{
386 struct mxc_nand_host *host = chip->priv;
387 uint8_t *buf = chip->oob_poi;
388 int length = mtd->oobsize;
389 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
390 uint8_t *bufpoi = buf;
391 int i, toread;
392
393 MTDDEBUG(MTD_DEBUG_LEVEL0,
394 "%s: Reading OOB area of page %u to oob %p\n",
395 __FUNCTION__, host->page_addr, buf);
396
397 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, page);
398 for (i = 0; i < chip->ecc.steps; i++) {
399 toread = min_t(int, length, chip->ecc.prepad);
400 if (toread) {
401 chip->read_buf(mtd, bufpoi, toread);
402 bufpoi += toread;
403 length -= toread;
404 }
405 bufpoi += chip->ecc.bytes;
406 host->col_addr += chip->ecc.bytes;
407 length -= chip->ecc.bytes;
408
409 toread = min_t(int, length, chip->ecc.postpad);
410 if (toread) {
411 chip->read_buf(mtd, bufpoi, toread);
412 bufpoi += toread;
413 length -= toread;
414 }
415 }
416 if (length > 0)
417 chip->read_buf(mtd, bufpoi, length);
418
419 _mxc_nand_enable_hwecc(mtd, 0);
420 chip->cmdfunc(mtd, NAND_CMD_READOOB,
421 mtd->writesize + chip->ecc.prepad, page);
422 bufpoi = buf + chip->ecc.prepad;
423 length = mtd->oobsize - chip->ecc.prepad;
424 for (i = 0; i < chip->ecc.steps; i++) {
425 toread = min_t(int, length, chip->ecc.bytes);
426 chip->read_buf(mtd, bufpoi, toread);
427 bufpoi += eccpitch;
428 length -= eccpitch;
429 host->col_addr += chip->ecc.postpad + chip->ecc.prepad;
430 }
431 _mxc_nand_enable_hwecc(mtd, 1);
432 return 1;
433}
434
435static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd,
436 struct nand_chip *chip,
437 uint8_t *buf,
438 int page)
439{
440 struct mxc_nand_host *host = chip->priv;
441 int eccsize = chip->ecc.size;
442 int eccbytes = chip->ecc.bytes;
443 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
444 uint8_t *oob = chip->oob_poi;
445 int steps, size;
446 int n;
447
448 _mxc_nand_enable_hwecc(mtd, 0);
449 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, host->page_addr);
450
451 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
452 host->col_addr = n * eccsize;
453 chip->read_buf(mtd, buf, eccsize);
454 buf += eccsize;
455
456 host->col_addr = mtd->writesize + n * eccpitch;
457 if (chip->ecc.prepad) {
458 chip->read_buf(mtd, oob, chip->ecc.prepad);
459 oob += chip->ecc.prepad;
460 }
461
462 chip->read_buf(mtd, oob, eccbytes);
463 oob += eccbytes;
464
465 if (chip->ecc.postpad) {
466 chip->read_buf(mtd, oob, chip->ecc.postpad);
467 oob += chip->ecc.postpad;
468 }
469 }
470
471 size = mtd->oobsize - (oob - chip->oob_poi);
472 if (size)
473 chip->read_buf(mtd, oob, size);
474 _mxc_nand_enable_hwecc(mtd, 0);
475
476 return 0;
477}
478
479static int mxc_nand_read_page_syndrome(struct mtd_info *mtd,
480 struct nand_chip *chip,
481 uint8_t *buf,
482 int page)
483{
484 struct mxc_nand_host *host = chip->priv;
485 int n, eccsize = chip->ecc.size;
486 int eccbytes = chip->ecc.bytes;
487 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
488 int eccsteps = chip->ecc.steps;
489 uint8_t *p = buf;
490 uint8_t *oob = chip->oob_poi;
491
492 MTDDEBUG(MTD_DEBUG_LEVEL1, "Reading page %u to buf %p oob %p\n",
493 host->page_addr, buf, oob);
494
Helmut Raiger780f30b2011-07-06 09:40:28 +0200495 /* first read the data area and the available portion of OOB */
John Rigbyb081c2e2010-01-26 19:24:18 -0700496 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
497 int stat;
498
499 host->col_addr = n * eccsize;
500
501 chip->read_buf(mtd, p, eccsize);
502
503 host->col_addr = mtd->writesize + n * eccpitch;
504
505 if (chip->ecc.prepad) {
506 chip->read_buf(mtd, oob, chip->ecc.prepad);
507 oob += chip->ecc.prepad;
508 }
509
510 stat = chip->ecc.correct(mtd, p, oob, NULL);
511
512 if (stat < 0)
513 mtd->ecc_stats.failed++;
514 else
515 mtd->ecc_stats.corrected += stat;
516 oob += eccbytes;
517
518 if (chip->ecc.postpad) {
519 chip->read_buf(mtd, oob, chip->ecc.postpad);
520 oob += chip->ecc.postpad;
521 }
522 }
523
524 /* Calculate remaining oob bytes */
525 n = mtd->oobsize - (oob - chip->oob_poi);
526 if (n)
527 chip->read_buf(mtd, oob, n);
528
529 /* Then switch ECC off and read the OOB area to get the ECC code */
530 _mxc_nand_enable_hwecc(mtd, 0);
531 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, host->page_addr);
532 eccsteps = chip->ecc.steps;
533 oob = chip->oob_poi + chip->ecc.prepad;
534 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
535 host->col_addr = mtd->writesize +
536 n * eccpitch +
537 chip->ecc.prepad;
538 chip->read_buf(mtd, oob, eccbytes);
539 oob += eccbytes + chip->ecc.postpad;
540 }
541 _mxc_nand_enable_hwecc(mtd, 1);
542 return 0;
543}
544
545static int mxc_nand_write_oob_syndrome(struct mtd_info *mtd,
546 struct nand_chip *chip, int page)
547{
548 struct mxc_nand_host *host = chip->priv;
549 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
550 int length = mtd->oobsize;
551 int i, len, status, steps = chip->ecc.steps;
552 const uint8_t *bufpoi = chip->oob_poi;
553
554 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
555 for (i = 0; i < steps; i++) {
556 len = min_t(int, length, eccpitch);
557
558 chip->write_buf(mtd, bufpoi, len);
559 bufpoi += len;
560 length -= len;
561 host->col_addr += chip->ecc.prepad + chip->ecc.postpad;
562 }
563 if (length > 0)
564 chip->write_buf(mtd, bufpoi, length);
565
566 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
567 status = chip->waitfunc(mtd, chip);
568 return status & NAND_STATUS_FAIL ? -EIO : 0;
569}
570
571static void mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
572 struct nand_chip *chip,
573 const uint8_t *buf)
574{
575 struct mxc_nand_host *host = chip->priv;
576 int eccsize = chip->ecc.size;
577 int eccbytes = chip->ecc.bytes;
578 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
579 uint8_t *oob = chip->oob_poi;
580 int steps, size;
581 int n;
582
583 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
584 host->col_addr = n * eccsize;
585 chip->write_buf(mtd, buf, eccsize);
586 buf += eccsize;
587
588 host->col_addr = mtd->writesize + n * eccpitch;
589
590 if (chip->ecc.prepad) {
591 chip->write_buf(mtd, oob, chip->ecc.prepad);
592 oob += chip->ecc.prepad;
593 }
594
595 host->col_addr += eccbytes;
596 oob += eccbytes;
597
598 if (chip->ecc.postpad) {
599 chip->write_buf(mtd, oob, chip->ecc.postpad);
600 oob += chip->ecc.postpad;
601 }
602 }
603
604 size = mtd->oobsize - (oob - chip->oob_poi);
605 if (size)
606 chip->write_buf(mtd, oob, size);
607}
608
609static void mxc_nand_write_page_syndrome(struct mtd_info *mtd,
610 struct nand_chip *chip,
611 const uint8_t *buf)
612{
613 struct mxc_nand_host *host = chip->priv;
614 int i, n, eccsize = chip->ecc.size;
615 int eccbytes = chip->ecc.bytes;
616 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
617 int eccsteps = chip->ecc.steps;
618 const uint8_t *p = buf;
619 uint8_t *oob = chip->oob_poi;
620
621 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
622
623 for (i = n = 0;
624 eccsteps;
625 n++, eccsteps--, i += eccbytes, p += eccsize) {
626 host->col_addr = n * eccsize;
627
628 chip->write_buf(mtd, p, eccsize);
629
630 host->col_addr = mtd->writesize + n * eccpitch;
631
632 if (chip->ecc.prepad) {
633 chip->write_buf(mtd, oob, chip->ecc.prepad);
634 oob += chip->ecc.prepad;
635 }
636
637 chip->write_buf(mtd, oob, eccbytes);
638 oob += eccbytes;
639
640 if (chip->ecc.postpad) {
641 chip->write_buf(mtd, oob, chip->ecc.postpad);
642 oob += chip->ecc.postpad;
643 }
644 }
645
646 /* Calculate remaining oob bytes */
647 i = mtd->oobsize - (oob - chip->oob_poi);
648 if (i)
649 chip->write_buf(mtd, oob, i);
650}
651
652static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
653 u_char *read_ecc, u_char *calc_ecc)
654{
655 struct nand_chip *nand_chip = mtd->priv;
656 struct mxc_nand_host *host = nand_chip->priv;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200657 uint16_t ecc_status = readw(&host->regs->ecc_status_result);
John Rigbyb081c2e2010-01-26 19:24:18 -0700658 int subpages = mtd->writesize / nand_chip->subpagesize;
659 int pg2blk_shift = nand_chip->phys_erase_shift -
660 nand_chip->page_shift;
661
662 do {
663 if ((ecc_status & 0xf) > 4) {
664 static int last_bad = -1;
665
666 if (last_bad != host->page_addr >> pg2blk_shift) {
667 last_bad = host->page_addr >> pg2blk_shift;
668 printk(KERN_DEBUG
669 "MXC_NAND: HWECC uncorrectable ECC error"
670 " in block %u page %u subpage %d\n",
671 last_bad, host->page_addr,
672 mtd->writesize / nand_chip->subpagesize
673 - subpages);
674 }
675 return -1;
676 }
677 ecc_status >>= 4;
678 subpages--;
679 } while (subpages > 0);
680
681 return 0;
682}
683#else
684#define mxc_nand_read_page_syndrome NULL
685#define mxc_nand_read_page_raw_syndrome NULL
686#define mxc_nand_read_oob_syndrome NULL
687#define mxc_nand_write_page_syndrome NULL
688#define mxc_nand_write_page_raw_syndrome NULL
689#define mxc_nand_write_oob_syndrome NULL
690#define mxc_nfc_11_nand_correct_data NULL
691
Ilya Yanok36fab992009-08-11 02:32:54 +0400692static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
693 u_char *read_ecc, u_char *calc_ecc)
694{
695 struct nand_chip *nand_chip = mtd->priv;
696 struct mxc_nand_host *host = nand_chip->priv;
697
698 /*
699 * 1-Bit errors are automatically corrected in HW. No need for
700 * additional correction. 2-Bit errors cannot be corrected by
701 * HW ECC, so we need to return failure
702 */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200703 uint16_t ecc_status = readw(&host->regs->ecc_status_result);
Ilya Yanok36fab992009-08-11 02:32:54 +0400704
705 if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
706 MTDDEBUG(MTD_DEBUG_LEVEL0,
707 "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
708 return -1;
709 }
710
711 return 0;
712}
John Rigbyb081c2e2010-01-26 19:24:18 -0700713#endif
714
Ilya Yanok36fab992009-08-11 02:32:54 +0400715static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
716 u_char *ecc_code)
717{
718 return 0;
719}
720#endif
721
722static u_char mxc_nand_read_byte(struct mtd_info *mtd)
723{
724 struct nand_chip *nand_chip = mtd->priv;
725 struct mxc_nand_host *host = nand_chip->priv;
726 uint8_t ret = 0;
727 uint16_t col;
728 uint16_t __iomem *main_buf =
John Rigbyb081c2e2010-01-26 19:24:18 -0700729 (uint16_t __iomem *)host->regs->main_area[0];
Ilya Yanok36fab992009-08-11 02:32:54 +0400730 uint16_t __iomem *spare_buf =
John Rigbyb081c2e2010-01-26 19:24:18 -0700731 (uint16_t __iomem *)host->regs->spare_area[0];
Ilya Yanok36fab992009-08-11 02:32:54 +0400732 union {
733 uint16_t word;
734 uint8_t bytes[2];
735 } nfc_word;
736
737 /* Check for status request */
738 if (host->status_request)
739 return get_dev_status(host) & 0xFF;
740
741 /* Get column for 16-bit access */
742 col = host->col_addr >> 1;
743
744 /* If we are accessing the spare region */
745 if (host->spare_only)
746 nfc_word.word = readw(&spare_buf[col]);
747 else
748 nfc_word.word = readw(&main_buf[col]);
749
750 /* Pick upper/lower byte of word from RAM buffer */
751 ret = nfc_word.bytes[host->col_addr & 0x1];
752
753 /* Update saved column address */
754 if (nand_chip->options & NAND_BUSWIDTH_16)
755 host->col_addr += 2;
756 else
757 host->col_addr++;
758
759 return ret;
760}
761
762static uint16_t mxc_nand_read_word(struct mtd_info *mtd)
763{
764 struct nand_chip *nand_chip = mtd->priv;
765 struct mxc_nand_host *host = nand_chip->priv;
766 uint16_t col, ret;
767 uint16_t __iomem *p;
768
769 MTDDEBUG(MTD_DEBUG_LEVEL3,
770 "mxc_nand_read_word(col = %d)\n", host->col_addr);
771
772 col = host->col_addr;
773 /* Adjust saved column address */
774 if (col < mtd->writesize && host->spare_only)
775 col += mtd->writesize;
776
777 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700778 p = (uint16_t __iomem *)(host->regs->main_area[0] +
779 (col >> 1));
Ilya Yanok36fab992009-08-11 02:32:54 +0400780 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700781 p = (uint16_t __iomem *)(host->regs->spare_area[0] +
Ilya Yanok36fab992009-08-11 02:32:54 +0400782 ((col - mtd->writesize) >> 1));
783 }
784
785 if (col & 1) {
786 union {
787 uint16_t word;
788 uint8_t bytes[2];
789 } nfc_word[3];
790
791 nfc_word[0].word = readw(p);
792 nfc_word[1].word = readw(p + 1);
793
794 nfc_word[2].bytes[0] = nfc_word[0].bytes[1];
795 nfc_word[2].bytes[1] = nfc_word[1].bytes[0];
796
797 ret = nfc_word[2].word;
798 } else {
799 ret = readw(p);
800 }
801
802 /* Update saved column address */
803 host->col_addr = col + 2;
804
805 return ret;
806}
807
808/*
809 * Write data of length len to buffer buf. The data to be
810 * written on NAND Flash is first copied to RAMbuffer. After the Data Input
811 * Operation by the NFC, the data is written to NAND Flash
812 */
813static void mxc_nand_write_buf(struct mtd_info *mtd,
814 const u_char *buf, int len)
815{
816 struct nand_chip *nand_chip = mtd->priv;
817 struct mxc_nand_host *host = nand_chip->priv;
818 int n, col, i = 0;
819
820 MTDDEBUG(MTD_DEBUG_LEVEL3,
821 "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr,
822 len);
823
824 col = host->col_addr;
825
826 /* Adjust saved column address */
827 if (col < mtd->writesize && host->spare_only)
828 col += mtd->writesize;
829
830 n = mtd->writesize + mtd->oobsize - col;
831 n = min(len, n);
832
833 MTDDEBUG(MTD_DEBUG_LEVEL3,
834 "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n);
835
836 while (n > 0) {
837 void __iomem *p;
838
839 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700840 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanok36fab992009-08-11 02:32:54 +0400841 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700842 p = host->regs->spare_area[0] -
Ilya Yanok36fab992009-08-11 02:32:54 +0400843 mtd->writesize + (col & ~3);
844 }
845
846 MTDDEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__,
847 __LINE__, p);
848
849 if (((col | (unsigned long)&buf[i]) & 3) || n < 4) {
850 union {
851 uint32_t word;
852 uint8_t bytes[4];
853 } nfc_word;
854
855 nfc_word.word = readl(p);
856 nfc_word.bytes[col & 3] = buf[i++];
857 n--;
858 col++;
859
860 writel(nfc_word.word, p);
861 } else {
862 int m = mtd->writesize - col;
863
864 if (col >= mtd->writesize)
865 m += mtd->oobsize;
866
867 m = min(n, m) & ~3;
868
869 MTDDEBUG(MTD_DEBUG_LEVEL3,
870 "%s:%d: n = %d, m = %d, i = %d, col = %d\n",
871 __func__, __LINE__, n, m, i, col);
872
873 mxc_nand_memcpy32(p, (uint32_t *)&buf[i], m);
874 col += m;
875 i += m;
876 n -= m;
877 }
878 }
879 /* Update saved column address */
880 host->col_addr = col;
881}
882
883/*
884 * Read the data buffer from the NAND Flash. To read the data from NAND
885 * Flash first the data output cycle is initiated by the NFC, which copies
886 * the data to RAMbuffer. This data of length len is then copied to buffer buf.
887 */
888static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
889{
890 struct nand_chip *nand_chip = mtd->priv;
891 struct mxc_nand_host *host = nand_chip->priv;
892 int n, col, i = 0;
893
894 MTDDEBUG(MTD_DEBUG_LEVEL3,
895 "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len);
896
897 col = host->col_addr;
898
899 /* Adjust saved column address */
900 if (col < mtd->writesize && host->spare_only)
901 col += mtd->writesize;
902
903 n = mtd->writesize + mtd->oobsize - col;
904 n = min(len, n);
905
906 while (n > 0) {
907 void __iomem *p;
908
909 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700910 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanok36fab992009-08-11 02:32:54 +0400911 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700912 p = host->regs->spare_area[0] -
Ilya Yanok36fab992009-08-11 02:32:54 +0400913 mtd->writesize + (col & ~3);
914 }
915
916 if (((col | (int)&buf[i]) & 3) || n < 4) {
917 union {
918 uint32_t word;
919 uint8_t bytes[4];
920 } nfc_word;
921
922 nfc_word.word = readl(p);
923 buf[i++] = nfc_word.bytes[col & 3];
924 n--;
925 col++;
926 } else {
927 int m = mtd->writesize - col;
928
929 if (col >= mtd->writesize)
930 m += mtd->oobsize;
931
932 m = min(n, m) & ~3;
933 mxc_nand_memcpy32((uint32_t *)&buf[i], p, m);
934
935 col += m;
936 i += m;
937 n -= m;
938 }
939 }
940 /* Update saved column address */
941 host->col_addr = col;
942}
943
944/*
945 * Used by the upper layer to verify the data in NAND Flash
946 * with the data in the buf.
947 */
948static int mxc_nand_verify_buf(struct mtd_info *mtd,
949 const u_char *buf, int len)
950{
951 u_char tmp[256];
952 uint bsize;
953
954 while (len) {
955 bsize = min(len, 256);
956 mxc_nand_read_buf(mtd, tmp, bsize);
957
958 if (memcmp(buf, tmp, bsize))
959 return 1;
960
961 buf += bsize;
962 len -= bsize;
963 }
964
965 return 0;
966}
967
968/*
969 * This function is used by upper layer for select and
970 * deselect of the NAND chip
971 */
972static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
973{
974 struct nand_chip *nand_chip = mtd->priv;
975 struct mxc_nand_host *host = nand_chip->priv;
976
977 switch (chip) {
978 case -1:
979 /* TODO: Disable the NFC clock */
980 if (host->clk_act)
981 host->clk_act = 0;
982 break;
983 case 0:
984 /* TODO: Enable the NFC clock */
985 if (!host->clk_act)
986 host->clk_act = 1;
987 break;
988
989 default:
990 break;
991 }
992}
993
994/*
995 * Used by the upper layer to write command to NAND Flash for
996 * different operations to be carried out on NAND Flash
997 */
John Rigbyb081c2e2010-01-26 19:24:18 -0700998void mxc_nand_command(struct mtd_info *mtd, unsigned command,
Ilya Yanok36fab992009-08-11 02:32:54 +0400999 int column, int page_addr)
1000{
1001 struct nand_chip *nand_chip = mtd->priv;
1002 struct mxc_nand_host *host = nand_chip->priv;
1003
1004 MTDDEBUG(MTD_DEBUG_LEVEL3,
1005 "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
1006 command, column, page_addr);
1007
1008 /* Reset command state information */
1009 host->status_request = false;
1010
1011 /* Command pre-processing step */
1012 switch (command) {
1013
1014 case NAND_CMD_STATUS:
1015 host->col_addr = 0;
1016 host->status_request = true;
1017 break;
1018
1019 case NAND_CMD_READ0:
John Rigbyb081c2e2010-01-26 19:24:18 -07001020 host->page_addr = page_addr;
Ilya Yanok36fab992009-08-11 02:32:54 +04001021 host->col_addr = column;
1022 host->spare_only = false;
1023 break;
1024
1025 case NAND_CMD_READOOB:
1026 host->col_addr = column;
1027 host->spare_only = true;
1028 if (host->pagesize_2k)
1029 command = NAND_CMD_READ0; /* only READ0 is valid */
1030 break;
1031
1032 case NAND_CMD_SEQIN:
1033 if (column >= mtd->writesize) {
1034 /*
1035 * before sending SEQIN command for partial write,
1036 * we need read one page out. FSL NFC does not support
Helmut Raiger780f30b2011-07-06 09:40:28 +02001037 * partial write. It always sends out 512+ecc+512+ecc
Ilya Yanok36fab992009-08-11 02:32:54 +04001038 * for large page nand flash. But for small page nand
1039 * flash, it does support SPARE ONLY operation.
1040 */
1041 if (host->pagesize_2k) {
1042 /* call ourself to read a page */
1043 mxc_nand_command(mtd, NAND_CMD_READ0, 0,
1044 page_addr);
1045 }
1046
1047 host->col_addr = column - mtd->writesize;
1048 host->spare_only = true;
1049
1050 /* Set program pointer to spare region */
1051 if (!host->pagesize_2k)
1052 send_cmd(host, NAND_CMD_READOOB);
1053 } else {
1054 host->spare_only = false;
1055 host->col_addr = column;
1056
1057 /* Set program pointer to page start */
1058 if (!host->pagesize_2k)
1059 send_cmd(host, NAND_CMD_READ0);
1060 }
1061 break;
1062
1063 case NAND_CMD_PAGEPROG:
1064 send_prog_page(host, 0, host->spare_only);
1065
John Rigbyb081c2e2010-01-26 19:24:18 -07001066 if (host->pagesize_2k && !is_mxc_nfc_11()) {
Helmut Raiger780f30b2011-07-06 09:40:28 +02001067 /* data in 4 areas */
Ilya Yanok36fab992009-08-11 02:32:54 +04001068 send_prog_page(host, 1, host->spare_only);
1069 send_prog_page(host, 2, host->spare_only);
1070 send_prog_page(host, 3, host->spare_only);
1071 }
1072
1073 break;
1074 }
1075
1076 /* Write out the command to the device. */
1077 send_cmd(host, command);
1078
1079 /* Write out column address, if necessary */
1080 if (column != -1) {
1081 /*
1082 * MXC NANDFC can only perform full page+spare or
Helmut Raiger780f30b2011-07-06 09:40:28 +02001083 * spare-only read/write. When the upper layers perform
1084 * a read/write buffer operation, we will use the saved
1085 * column address to index into the full page.
Ilya Yanok36fab992009-08-11 02:32:54 +04001086 */
1087 send_addr(host, 0);
1088 if (host->pagesize_2k)
1089 /* another col addr cycle for 2k page */
1090 send_addr(host, 0);
1091 }
1092
1093 /* Write out page address, if necessary */
1094 if (page_addr != -1) {
John Rigbyb081c2e2010-01-26 19:24:18 -07001095 u32 page_mask = nand_chip->pagemask;
1096 do {
1097 send_addr(host, page_addr & 0xFF);
1098 page_addr >>= 8;
1099 page_mask >>= 8;
1100 } while (page_mask);
Ilya Yanok36fab992009-08-11 02:32:54 +04001101 }
1102
1103 /* Command post-processing step */
1104 switch (command) {
1105
1106 case NAND_CMD_RESET:
1107 break;
1108
1109 case NAND_CMD_READOOB:
1110 case NAND_CMD_READ0:
1111 if (host->pagesize_2k) {
1112 /* send read confirm command */
1113 send_cmd(host, NAND_CMD_READSTART);
1114 /* read for each AREA */
1115 send_read_page(host, 0, host->spare_only);
John Rigbyb081c2e2010-01-26 19:24:18 -07001116 if (!is_mxc_nfc_11()) {
1117 send_read_page(host, 1, host->spare_only);
1118 send_read_page(host, 2, host->spare_only);
1119 send_read_page(host, 3, host->spare_only);
1120 }
Ilya Yanok36fab992009-08-11 02:32:54 +04001121 } else {
1122 send_read_page(host, 0, host->spare_only);
1123 }
1124 break;
1125
1126 case NAND_CMD_READID:
1127 host->col_addr = 0;
1128 send_read_id(host);
1129 break;
1130
1131 case NAND_CMD_PAGEPROG:
1132 break;
1133
1134 case NAND_CMD_STATUS:
1135 break;
1136
1137 case NAND_CMD_ERASE2:
1138 break;
1139 }
1140}
1141
John Rigbyb081c2e2010-01-26 19:24:18 -07001142#ifdef MXC_NFC_V1_1
1143static void mxc_setup_config1(void)
1144{
1145 uint16_t tmp;
1146
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001147 tmp = readw(&host->regs->config1);
John Rigbyb081c2e2010-01-26 19:24:18 -07001148 tmp |= NFC_ONE_CYCLE;
1149 tmp |= NFC_4_8N_ECC;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001150 writew(tmp, &host->regs->config1);
John Rigbyb081c2e2010-01-26 19:24:18 -07001151 if (host->pagesize_2k)
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001152 writew(64/2, &host->regs->spare_area_size);
John Rigbyb081c2e2010-01-26 19:24:18 -07001153 else
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001154 writew(16/2, &host->regs->spare_area_size);
John Rigbyb081c2e2010-01-26 19:24:18 -07001155}
1156#else
1157#define mxc_setup_config1()
1158#endif
1159
Timo Ketolaa1028732012-04-18 22:55:31 +00001160#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
1161
1162static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
1163static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
1164
1165static struct nand_bbt_descr bbt_main_descr = {
1166 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1167 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1168 .offs = 0,
1169 .len = 4,
1170 .veroffs = 4,
1171 .maxblocks = 4,
1172 .pattern = bbt_pattern,
1173};
1174
1175static struct nand_bbt_descr bbt_mirror_descr = {
1176 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1177 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1178 .offs = 0,
1179 .len = 4,
1180 .veroffs = 4,
1181 .maxblocks = 4,
1182 .pattern = mirror_pattern,
1183};
1184
1185#endif
1186
Ilya Yanok36fab992009-08-11 02:32:54 +04001187int board_nand_init(struct nand_chip *this)
1188{
Ilya Yanok36fab992009-08-11 02:32:54 +04001189 struct mtd_info *mtd;
1190 uint16_t tmp;
1191 int err = 0;
1192
Timo Ketolaa1028732012-04-18 22:55:31 +00001193#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
1194 this->options |= NAND_USE_FLASH_BBT;
1195 this->bbt_td = &bbt_main_descr;
1196 this->bbt_md = &bbt_mirror_descr;
1197#endif
1198
Ilya Yanok36fab992009-08-11 02:32:54 +04001199 /* structures must be linked */
1200 mtd = &host->mtd;
1201 mtd->priv = this;
1202 host->nand = this;
1203
1204 /* 5 us command delay time */
1205 this->chip_delay = 5;
1206
1207 this->priv = host;
1208 this->dev_ready = mxc_nand_dev_ready;
1209 this->cmdfunc = mxc_nand_command;
1210 this->select_chip = mxc_nand_select_chip;
1211 this->read_byte = mxc_nand_read_byte;
1212 this->read_word = mxc_nand_read_word;
1213 this->write_buf = mxc_nand_write_buf;
1214 this->read_buf = mxc_nand_read_buf;
1215 this->verify_buf = mxc_nand_verify_buf;
1216
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001217 host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
Ilya Yanok36fab992009-08-11 02:32:54 +04001218 host->clk_act = 1;
1219
1220#ifdef CONFIG_MXC_NAND_HWECC
1221 this->ecc.calculate = mxc_nand_calculate_ecc;
1222 this->ecc.hwctl = mxc_nand_enable_hwecc;
1223 this->ecc.correct = mxc_nand_correct_data;
John Rigbyb081c2e2010-01-26 19:24:18 -07001224 if (is_mxc_nfc_11()) {
1225 this->ecc.mode = NAND_ECC_HW_SYNDROME;
1226 this->ecc.read_page = mxc_nand_read_page_syndrome;
1227 this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome;
1228 this->ecc.read_oob = mxc_nand_read_oob_syndrome;
1229 this->ecc.write_page = mxc_nand_write_page_syndrome;
1230 this->ecc.write_page_raw = mxc_nand_write_page_raw_syndrome;
1231 this->ecc.write_oob = mxc_nand_write_oob_syndrome;
1232 this->ecc.bytes = 9;
1233 this->ecc.prepad = 7;
1234 } else {
1235 this->ecc.mode = NAND_ECC_HW;
1236 }
1237
1238 host->pagesize_2k = 0;
1239
Ilya Yanok36fab992009-08-11 02:32:54 +04001240 this->ecc.size = 512;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001241 tmp = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +04001242 tmp |= NFC_ECC_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001243 writew(tmp, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +04001244#else
1245 this->ecc.layout = &nand_soft_eccoob;
1246 this->ecc.mode = NAND_ECC_SOFT;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001247 tmp = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +04001248 tmp &= ~NFC_ECC_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001249 writew(tmp, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +04001250#endif
Ilya Yanok36fab992009-08-11 02:32:54 +04001251 /* Reset NAND */
1252 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1253
1254 /*
1255 * preset operation
1256 * Unlock the internal RAM Buffer
1257 */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001258 writew(0x2, &host->regs->config);
Ilya Yanok36fab992009-08-11 02:32:54 +04001259
1260 /* Blocks to be unlocked */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001261 writew(0x0, &host->regs->unlockstart_blkaddr);
Helmut Raigerb4b1e762011-07-06 19:04:41 +02001262 /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the
1263 * unlockend_blkaddr, but the magic 0x4000 does not always work
1264 * when writing more than some 32 megabytes (on 2k page nands)
1265 * However 0xFFFF doesn't seem to have this kind
1266 * of limitation (tried it back and forth several times).
1267 * The linux kernel driver sets this to 0xFFFF for the v2 controller
1268 * only, but probably this was not tested there for v1.
1269 * The very same limitation seems to apply to this kernel driver.
1270 * This might be NAND chip specific and the i.MX31 datasheet is
1271 * extremely vague about the semantics of this register.
1272 */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001273 writew(0xFFFF, &host->regs->unlockend_blkaddr);
Ilya Yanok36fab992009-08-11 02:32:54 +04001274
1275 /* Unlock Block Command for given address range */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001276 writew(0x4, &host->regs->wrprot);
Ilya Yanok36fab992009-08-11 02:32:54 +04001277
Helmut Raiger780f30b2011-07-06 09:40:28 +02001278 /* NAND bus width determines access functions used by upper layer */
Magnus Liljaf6a97482009-11-11 20:18:43 +01001279 if (is_16bit_nand())
Ilya Yanok36fab992009-08-11 02:32:54 +04001280 this->options |= NAND_BUSWIDTH_16;
1281
Magnus Liljac4832df2010-01-17 17:46:10 +01001282#ifdef CONFIG_SYS_NAND_LARGEPAGE
1283 host->pagesize_2k = 1;
John Rigbyb081c2e2010-01-26 19:24:18 -07001284 this->ecc.layout = &nand_hw_eccoob2k;
Magnus Liljac4832df2010-01-17 17:46:10 +01001285#else
Ilya Yanok36fab992009-08-11 02:32:54 +04001286 host->pagesize_2k = 0;
John Rigbyb081c2e2010-01-26 19:24:18 -07001287 this->ecc.layout = &nand_hw_eccoob;
Magnus Liljac4832df2010-01-17 17:46:10 +01001288#endif
John Rigbyb081c2e2010-01-26 19:24:18 -07001289 mxc_setup_config1();
Ilya Yanok36fab992009-08-11 02:32:54 +04001290 return err;
1291}