blob: 9633858a7d518bbb86e9c2507c50ee1bd2b78f30 [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>
John Rigbyb081c2e2010-01-26 19:24:18 -070025#if defined(CONFIG_MX27) || defined(CONFIG_MX25)
Ilya Yanok36fab992009-08-11 02:32:54 +040026#include <asm/arch/imx-regs.h>
27#endif
28
29#define DRIVER_NAME "mxc_nand"
30
John Rigbyb081c2e2010-01-26 19:24:18 -070031/*
32 * TODO: Use same register defs here as nand_spl mxc nand driver.
33 */
34/*
35 * Register map and bit definitions for the Freescale NAND Flash Controller
36 * present in various i.MX devices.
37 *
38 * MX31 and MX27 have version 1 which has
39 * 4 512 byte main buffers and
40 * 4 16 byte spare buffers
41 * to support up to 2K byte pagesize nand.
42 * Reading or writing a 2K page requires 4 FDI/FDO cycles.
43 *
44 * MX25 has version 1.1 which has
45 * 8 512 byte main buffers and
46 * 8 64 byte spare buffers
47 * to support up to 4K byte pagesize nand.
48 * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle.
49 * Also some of registers are moved and/or changed meaning as seen below.
50 */
51#if defined(CONFIG_MX31) || defined(CONFIG_MX27)
52#define MXC_NFC_V1
53#elif defined(CONFIG_MX25)
54#define MXC_NFC_V1_1
55#else
56#warning "MXC NFC version not defined"
57#endif
58
59#if defined(MXC_NFC_V1)
60#define NAND_MXC_NR_BUFS 4
61#define NAND_MXC_SPARE_BUF_SIZE 16
62#define NAND_MXC_REG_OFFSET 0xe00
63#define is_mxc_nfc_11() 0
64#elif defined(MXC_NFC_V1_1)
65#define NAND_MXC_NR_BUFS 8
66#define NAND_MXC_SPARE_BUF_SIZE 64
67#define NAND_MXC_REG_OFFSET 0x1e00
68#define is_mxc_nfc_11() 1
69#else
70#error "define CONFIG_NAND_MXC_VXXX to use mtd mxc nand driver"
71#endif
Ilya Yanok36fab992009-08-11 02:32:54 +040072struct nfc_regs {
John Rigbyb081c2e2010-01-26 19:24:18 -070073 uint8_t main_area[NAND_MXC_NR_BUFS][0x200];
74 uint8_t spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE];
75 /*
76 * reserved size is offset of nfc registers
77 * minus total main and spare sizes
78 */
79 uint8_t reserved1[NAND_MXC_REG_OFFSET
80 - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)];
81#if defined(MXC_NFC_V1)
Ilya Yanok36fab992009-08-11 02:32:54 +040082 uint16_t nfc_buf_size;
John Rigbyb081c2e2010-01-26 19:24:18 -070083 uint16_t reserved2;
Ilya Yanok36fab992009-08-11 02:32:54 +040084 uint16_t nfc_buf_addr;
85 uint16_t nfc_flash_addr;
86 uint16_t nfc_flash_cmd;
87 uint16_t nfc_config;
88 uint16_t nfc_ecc_status_result;
89 uint16_t nfc_rsltmain_area;
90 uint16_t nfc_rsltspare_area;
91 uint16_t nfc_wrprot;
92 uint16_t nfc_unlockstart_blkaddr;
93 uint16_t nfc_unlockend_blkaddr;
94 uint16_t nfc_nf_wrprst;
95 uint16_t nfc_config1;
96 uint16_t nfc_config2;
John Rigbyb081c2e2010-01-26 19:24:18 -070097#elif defined(MXC_NFC_V1_1)
98 uint16_t reserved2[2];
99 uint16_t nfc_buf_addr;
100 uint16_t nfc_flash_addr;
101 uint16_t nfc_flash_cmd;
102 uint16_t nfc_config;
103 uint16_t nfc_ecc_status_result;
104 uint16_t nfc_ecc_status_result2;
105 uint16_t nfc_spare_area_size;
106 uint16_t nfc_wrprot;
107 uint16_t reserved3[2];
108 uint16_t nfc_nf_wrprst;
109 uint16_t nfc_config1;
110 uint16_t nfc_config2;
111 uint16_t reserved4;
112 uint16_t nfc_unlockstart_blkaddr;
113 uint16_t nfc_unlockend_blkaddr;
114 uint16_t nfc_unlockstart_blkaddr1;
115 uint16_t nfc_unlockend_blkaddr1;
116 uint16_t nfc_unlockstart_blkaddr2;
117 uint16_t nfc_unlockend_blkaddr2;
118 uint16_t nfc_unlockstart_blkaddr3;
119 uint16_t nfc_unlockend_blkaddr3;
120#endif
Ilya Yanok36fab992009-08-11 02:32:54 +0400121};
122
123/*
124 * Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
125 * for Command operation
126 */
127#define NFC_CMD 0x1
128
129/*
130 * Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register
131 * for Address operation
132 */
133#define NFC_ADDR 0x2
134
135/*
136 * Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register
137 * for Input operation
138 */
139#define NFC_INPUT 0x4
140
141/*
142 * Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register
143 * for Data Output operation
144 */
145#define NFC_OUTPUT 0x8
146
147/*
148 * Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register
149 * for Read ID operation
150 */
151#define NFC_ID 0x10
152
153/*
154 * Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register
155 * for Read Status operation
156 */
157#define NFC_STATUS 0x20
158
159/*
160 * Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read
161 * Status operation
162 */
163#define NFC_INT 0x8000
164
John Rigbyb081c2e2010-01-26 19:24:18 -0700165#ifdef MXC_NFC_V1_1
166#define NFC_4_8N_ECC (1 << 0)
167#else
168#define NFC_4_8N_ECC 0
169#endif
Ilya Yanok36fab992009-08-11 02:32:54 +0400170#define NFC_SP_EN (1 << 2)
171#define NFC_ECC_EN (1 << 3)
172#define NFC_BIG (1 << 5)
173#define NFC_RST (1 << 6)
174#define NFC_CE (1 << 7)
175#define NFC_ONE_CYCLE (1 << 8)
176
177typedef enum {false, true} bool;
178
179struct mxc_nand_host {
180 struct mtd_info mtd;
181 struct nand_chip *nand;
182
183 struct nfc_regs __iomem *regs;
184 int spare_only;
185 int status_request;
186 int pagesize_2k;
187 int clk_act;
188 uint16_t col_addr;
John Rigbyb081c2e2010-01-26 19:24:18 -0700189 unsigned int page_addr;
Ilya Yanok36fab992009-08-11 02:32:54 +0400190};
191
192static struct mxc_nand_host mxc_host;
193static struct mxc_nand_host *host = &mxc_host;
194
195/* Define delays in microsec for NAND device operations */
196#define TROP_US_DELAY 2000
197/* Macros to get byte and bit positions of ECC */
198#define COLPOS(x) ((x) >> 3)
199#define BITPOS(x) ((x) & 0xf)
200
201/* Define single bit Error positions in Main & Spare area */
202#define MAIN_SINGLEBIT_ERROR 0x4
203#define SPARE_SINGLEBIT_ERROR 0x1
204
205/* OOB placement block for use with hardware ecc generation */
John Rigbyb081c2e2010-01-26 19:24:18 -0700206#if defined(MXC_NFC_V1)
207#ifndef CONFIG_SYS_NAND_LARGEPAGE
Ilya Yanok36fab992009-08-11 02:32:54 +0400208static struct nand_ecclayout nand_hw_eccoob = {
209 .eccbytes = 5,
210 .eccpos = {6, 7, 8, 9, 10},
John Rigbyb081c2e2010-01-26 19:24:18 -0700211 .oobfree = { {0, 5}, {11, 5}, }
Ilya Yanok36fab992009-08-11 02:32:54 +0400212};
213#else
John Rigbyb081c2e2010-01-26 19:24:18 -0700214static struct nand_ecclayout nand_hw_eccoob2k = {
215 .eccbytes = 20,
216 .eccpos = {
217 6, 7, 8, 9, 10,
218 22, 23, 24, 25, 26,
219 38, 39, 40, 41, 42,
220 54, 55, 56, 57, 58,
221 },
222 .oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} },
Ilya Yanok36fab992009-08-11 02:32:54 +0400223};
224#endif
John Rigbyb081c2e2010-01-26 19:24:18 -0700225#elif defined(MXC_NFC_V1_1)
226#ifndef CONFIG_SYS_NAND_LARGEPAGE
227static struct nand_ecclayout nand_hw_eccoob = {
228 .eccbytes = 9,
229 .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
230 .oobfree = { {2, 5} }
Magnus Liljac4832df2010-01-17 17:46:10 +0100231};
John Rigbyb081c2e2010-01-26 19:24:18 -0700232#else
233static struct nand_ecclayout nand_hw_eccoob2k = {
234 .eccbytes = 36,
235 .eccpos = {
236 7, 8, 9, 10, 11, 12, 13, 14, 15,
237 23, 24, 25, 26, 27, 28, 29, 30, 31,
238 39, 40, 41, 42, 43, 44, 45, 46, 47,
239 55, 56, 57, 58, 59, 60, 61, 62, 63,
240 },
241 .oobfree = { {2, 5}, {16, 7}, {32, 7}, {48, 7} },
242};
243#endif
244#endif
Magnus Liljac4832df2010-01-17 17:46:10 +0100245
Magnus Liljaf6a97482009-11-11 20:18:43 +0100246#ifdef CONFIG_MX27
247static int is_16bit_nand(void)
248{
249 struct system_control_regs *sc_regs =
250 (struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
251
252 if (readl(&sc_regs->fmcr) & NF_16BIT_SEL)
253 return 1;
254 else
255 return 0;
256}
257#elif defined(CONFIG_MX31)
258static int is_16bit_nand(void)
259{
260 struct clock_control_regs *sc_regs =
261 (struct clock_control_regs *)CCM_BASE;
262
263 if (readl(&sc_regs->rcsr) & CCM_RCSR_NF16B)
264 return 1;
265 else
266 return 0;
267}
John Rigbyb081c2e2010-01-26 19:24:18 -0700268#elif defined(CONFIG_MX25)
269static int is_16bit_nand(void)
270{
271 struct ccm_regs *ccm =
272 (struct ccm_regs *)IMX_CCM_BASE;
273
274 if (readl(&ccm->rcsr) & CCM_RCSR_NF_16BIT_SEL)
275 return 1;
276 else
277 return 0;
278}
Magnus Liljaf6a97482009-11-11 20:18:43 +0100279#else
280#warning "8/16 bit NAND autodetection not supported"
281static int is_16bit_nand(void)
282{
283 return 0;
284}
285#endif
286
Ilya Yanok36fab992009-08-11 02:32:54 +0400287static uint32_t *mxc_nand_memcpy32(uint32_t *dest, uint32_t *source, size_t size)
288{
289 uint32_t *d = dest;
290
291 size >>= 2;
292 while (size--)
293 __raw_writel(__raw_readl(source++), d++);
294 return dest;
295}
296
297/*
298 * This function polls the NANDFC to wait for the basic operation to
299 * complete by checking the INT bit of config2 register.
300 */
301static void wait_op_done(struct mxc_nand_host *host, int max_retries,
302 uint16_t param)
303{
304 uint32_t tmp;
305
306 while (max_retries-- > 0) {
307 if (readw(&host->regs->nfc_config2) & NFC_INT) {
308 tmp = readw(&host->regs->nfc_config2);
309 tmp &= ~NFC_INT;
310 writew(tmp, &host->regs->nfc_config2);
311 break;
312 }
313 udelay(1);
314 }
315 if (max_retries < 0) {
316 MTDDEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
317 __func__, param);
318 }
319}
320
321/*
322 * This function issues the specified command to the NAND device and
323 * waits for completion.
324 */
325static void send_cmd(struct mxc_nand_host *host, uint16_t cmd)
326{
327 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd);
328
329 writew(cmd, &host->regs->nfc_flash_cmd);
330 writew(NFC_CMD, &host->regs->nfc_config2);
331
332 /* Wait for operation to complete */
333 wait_op_done(host, TROP_US_DELAY, cmd);
334}
335
336/*
337 * This function sends an address (or partial address) to the
338 * NAND device. The address is used to select the source/destination for
339 * a NAND command.
340 */
341static void send_addr(struct mxc_nand_host *host, uint16_t addr)
342{
343 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr);
344
345 writew(addr, &host->regs->nfc_flash_addr);
346 writew(NFC_ADDR, &host->regs->nfc_config2);
347
348 /* Wait for operation to complete */
349 wait_op_done(host, TROP_US_DELAY, addr);
350}
351
352/*
353 * This function requests the NANDFC to initate the transfer
354 * of data currently in the NANDFC RAM buffer to the NAND device.
355 */
356static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
357 int spare_only)
358{
John Rigbyb081c2e2010-01-26 19:24:18 -0700359 if (spare_only)
360 MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only);
361
362 if (is_mxc_nfc_11()) {
363 int i;
364 /*
365 * The controller copies the 64 bytes of spare data from
366 * the first 16 bytes of each of the 4 64 byte spare buffers.
367 * Copy the contiguous data starting in spare_area[0] to
368 * the four spare area buffers.
369 */
370 for (i = 1; i < 4; i++) {
371 void __iomem *src = &host->regs->spare_area[0][i * 16];
372 void __iomem *dst = &host->regs->spare_area[i][0];
373
374 mxc_nand_memcpy32(dst, src, 16);
375 }
376 }
Ilya Yanok36fab992009-08-11 02:32:54 +0400377
378 writew(buf_id, &host->regs->nfc_buf_addr);
379
380 /* Configure spare or page+spare access */
381 if (!host->pagesize_2k) {
382 uint16_t config1 = readw(&host->regs->nfc_config1);
383 if (spare_only)
384 config1 |= NFC_SP_EN;
385 else
386 config1 &= ~(NFC_SP_EN);
387 writew(config1, &host->regs->nfc_config1);
388 }
389
390 writew(NFC_INPUT, &host->regs->nfc_config2);
391
392 /* Wait for operation to complete */
393 wait_op_done(host, TROP_US_DELAY, spare_only);
394}
395
396/*
397 * Requests NANDFC to initated the transfer of data from the
398 * NAND device into in the NANDFC ram buffer.
399 */
400static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
401 int spare_only)
402{
403 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
404
405 writew(buf_id, &host->regs->nfc_buf_addr);
406
407 /* Configure spare or page+spare access */
408 if (!host->pagesize_2k) {
409 uint32_t config1 = readw(&host->regs->nfc_config1);
410 if (spare_only)
411 config1 |= NFC_SP_EN;
412 else
413 config1 &= ~NFC_SP_EN;
414 writew(config1, &host->regs->nfc_config1);
415 }
416
417 writew(NFC_OUTPUT, &host->regs->nfc_config2);
418
419 /* Wait for operation to complete */
420 wait_op_done(host, TROP_US_DELAY, spare_only);
John Rigbyb081c2e2010-01-26 19:24:18 -0700421
422 if (is_mxc_nfc_11()) {
423 int i;
424
425 /*
426 * The controller copies the 64 bytes of spare data to
427 * the first 16 bytes of each of the 4 spare buffers.
428 * Make the data contiguous starting in spare_area[0].
429 */
430 for (i = 1; i < 4; i++) {
431 void __iomem *src = &host->regs->spare_area[i][0];
432 void __iomem *dst = &host->regs->spare_area[0][i * 16];
433
434 mxc_nand_memcpy32(dst, src, 16);
435 }
436 }
Ilya Yanok36fab992009-08-11 02:32:54 +0400437}
438
439/* Request the NANDFC to perform a read of the NAND device ID. */
440static void send_read_id(struct mxc_nand_host *host)
441{
442 uint16_t tmp;
443
444 /* NANDFC buffer 0 is used for device ID output */
445 writew(0x0, &host->regs->nfc_buf_addr);
446
447 /* Read ID into main buffer */
448 tmp = readw(&host->regs->nfc_config1);
449 tmp &= ~NFC_SP_EN;
450 writew(tmp, &host->regs->nfc_config1);
451
452 writew(NFC_ID, &host->regs->nfc_config2);
453
454 /* Wait for operation to complete */
455 wait_op_done(host, TROP_US_DELAY, 0);
456}
457
458/*
459 * This function requests the NANDFC to perform a read of the
460 * NAND device status and returns the current status.
461 */
462static uint16_t get_dev_status(struct mxc_nand_host *host)
463{
John Rigbyb081c2e2010-01-26 19:24:18 -0700464 void __iomem *main_buf = host->regs->main_area[1];
Ilya Yanok36fab992009-08-11 02:32:54 +0400465 uint32_t store;
466 uint16_t ret, tmp;
467 /* Issue status request to NAND device */
468
469 /* store the main area1 first word, later do recovery */
470 store = readl(main_buf);
471 /* NANDFC buffer 1 is used for device status */
472 writew(1, &host->regs->nfc_buf_addr);
473
474 /* Read status into main buffer */
475 tmp = readw(&host->regs->nfc_config1);
476 tmp &= ~NFC_SP_EN;
477 writew(tmp, &host->regs->nfc_config1);
478
479 writew(NFC_STATUS, &host->regs->nfc_config2);
480
481 /* Wait for operation to complete */
482 wait_op_done(host, TROP_US_DELAY, 0);
483
484 /*
485 * Status is placed in first word of main buffer
486 * get status, then recovery area 1 data
487 */
488 ret = readw(main_buf);
489 writel(store, main_buf);
490
491 return ret;
492}
493
494/* This function is used by upper layer to checks if device is ready */
495static int mxc_nand_dev_ready(struct mtd_info *mtd)
496{
497 /*
498 * NFC handles R/B internally. Therefore, this function
499 * always returns status as ready.
500 */
501 return 1;
502}
503
504#ifdef CONFIG_MXC_NAND_HWECC
505static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
506{
507 /*
508 * If HW ECC is enabled, we turn it on during init. There is
509 * no need to enable again here.
510 */
511}
512
John Rigbyb081c2e2010-01-26 19:24:18 -0700513#ifdef MXC_NFC_V1_1
514static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on)
515{
516 struct nand_chip *nand_chip = mtd->priv;
517 struct mxc_nand_host *host = nand_chip->priv;
518 uint16_t tmp = readw(&host->regs->nfc_config1);
519
520 if (on)
521 tmp |= NFC_ECC_EN;
522 else
523 tmp &= ~NFC_ECC_EN;
524 writew(tmp, &host->regs->nfc_config1);
525}
526
527static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
528 struct nand_chip *chip,
529 int page, int sndcmd)
530{
531 struct mxc_nand_host *host = chip->priv;
532 uint8_t *buf = chip->oob_poi;
533 int length = mtd->oobsize;
534 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
535 uint8_t *bufpoi = buf;
536 int i, toread;
537
538 MTDDEBUG(MTD_DEBUG_LEVEL0,
539 "%s: Reading OOB area of page %u to oob %p\n",
540 __FUNCTION__, host->page_addr, buf);
541
542 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, page);
543 for (i = 0; i < chip->ecc.steps; i++) {
544 toread = min_t(int, length, chip->ecc.prepad);
545 if (toread) {
546 chip->read_buf(mtd, bufpoi, toread);
547 bufpoi += toread;
548 length -= toread;
549 }
550 bufpoi += chip->ecc.bytes;
551 host->col_addr += chip->ecc.bytes;
552 length -= chip->ecc.bytes;
553
554 toread = min_t(int, length, chip->ecc.postpad);
555 if (toread) {
556 chip->read_buf(mtd, bufpoi, toread);
557 bufpoi += toread;
558 length -= toread;
559 }
560 }
561 if (length > 0)
562 chip->read_buf(mtd, bufpoi, length);
563
564 _mxc_nand_enable_hwecc(mtd, 0);
565 chip->cmdfunc(mtd, NAND_CMD_READOOB,
566 mtd->writesize + chip->ecc.prepad, page);
567 bufpoi = buf + chip->ecc.prepad;
568 length = mtd->oobsize - chip->ecc.prepad;
569 for (i = 0; i < chip->ecc.steps; i++) {
570 toread = min_t(int, length, chip->ecc.bytes);
571 chip->read_buf(mtd, bufpoi, toread);
572 bufpoi += eccpitch;
573 length -= eccpitch;
574 host->col_addr += chip->ecc.postpad + chip->ecc.prepad;
575 }
576 _mxc_nand_enable_hwecc(mtd, 1);
577 return 1;
578}
579
580static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd,
581 struct nand_chip *chip,
582 uint8_t *buf,
583 int page)
584{
585 struct mxc_nand_host *host = chip->priv;
586 int eccsize = chip->ecc.size;
587 int eccbytes = chip->ecc.bytes;
588 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
589 uint8_t *oob = chip->oob_poi;
590 int steps, size;
591 int n;
592
593 _mxc_nand_enable_hwecc(mtd, 0);
594 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, host->page_addr);
595
596 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
597 host->col_addr = n * eccsize;
598 chip->read_buf(mtd, buf, eccsize);
599 buf += eccsize;
600
601 host->col_addr = mtd->writesize + n * eccpitch;
602 if (chip->ecc.prepad) {
603 chip->read_buf(mtd, oob, chip->ecc.prepad);
604 oob += chip->ecc.prepad;
605 }
606
607 chip->read_buf(mtd, oob, eccbytes);
608 oob += eccbytes;
609
610 if (chip->ecc.postpad) {
611 chip->read_buf(mtd, oob, chip->ecc.postpad);
612 oob += chip->ecc.postpad;
613 }
614 }
615
616 size = mtd->oobsize - (oob - chip->oob_poi);
617 if (size)
618 chip->read_buf(mtd, oob, size);
619 _mxc_nand_enable_hwecc(mtd, 0);
620
621 return 0;
622}
623
624static int mxc_nand_read_page_syndrome(struct mtd_info *mtd,
625 struct nand_chip *chip,
626 uint8_t *buf,
627 int page)
628{
629 struct mxc_nand_host *host = chip->priv;
630 int n, eccsize = chip->ecc.size;
631 int eccbytes = chip->ecc.bytes;
632 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
633 int eccsteps = chip->ecc.steps;
634 uint8_t *p = buf;
635 uint8_t *oob = chip->oob_poi;
636
637 MTDDEBUG(MTD_DEBUG_LEVEL1, "Reading page %u to buf %p oob %p\n",
638 host->page_addr, buf, oob);
639
640 /* first read out the data area and the available portion of OOB */
641 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
642 int stat;
643
644 host->col_addr = n * eccsize;
645
646 chip->read_buf(mtd, p, eccsize);
647
648 host->col_addr = mtd->writesize + n * eccpitch;
649
650 if (chip->ecc.prepad) {
651 chip->read_buf(mtd, oob, chip->ecc.prepad);
652 oob += chip->ecc.prepad;
653 }
654
655 stat = chip->ecc.correct(mtd, p, oob, NULL);
656
657 if (stat < 0)
658 mtd->ecc_stats.failed++;
659 else
660 mtd->ecc_stats.corrected += stat;
661 oob += eccbytes;
662
663 if (chip->ecc.postpad) {
664 chip->read_buf(mtd, oob, chip->ecc.postpad);
665 oob += chip->ecc.postpad;
666 }
667 }
668
669 /* Calculate remaining oob bytes */
670 n = mtd->oobsize - (oob - chip->oob_poi);
671 if (n)
672 chip->read_buf(mtd, oob, n);
673
674 /* Then switch ECC off and read the OOB area to get the ECC code */
675 _mxc_nand_enable_hwecc(mtd, 0);
676 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, host->page_addr);
677 eccsteps = chip->ecc.steps;
678 oob = chip->oob_poi + chip->ecc.prepad;
679 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
680 host->col_addr = mtd->writesize +
681 n * eccpitch +
682 chip->ecc.prepad;
683 chip->read_buf(mtd, oob, eccbytes);
684 oob += eccbytes + chip->ecc.postpad;
685 }
686 _mxc_nand_enable_hwecc(mtd, 1);
687 return 0;
688}
689
690static int mxc_nand_write_oob_syndrome(struct mtd_info *mtd,
691 struct nand_chip *chip, int page)
692{
693 struct mxc_nand_host *host = chip->priv;
694 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
695 int length = mtd->oobsize;
696 int i, len, status, steps = chip->ecc.steps;
697 const uint8_t *bufpoi = chip->oob_poi;
698
699 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
700 for (i = 0; i < steps; i++) {
701 len = min_t(int, length, eccpitch);
702
703 chip->write_buf(mtd, bufpoi, len);
704 bufpoi += len;
705 length -= len;
706 host->col_addr += chip->ecc.prepad + chip->ecc.postpad;
707 }
708 if (length > 0)
709 chip->write_buf(mtd, bufpoi, length);
710
711 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
712 status = chip->waitfunc(mtd, chip);
713 return status & NAND_STATUS_FAIL ? -EIO : 0;
714}
715
716static void mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
717 struct nand_chip *chip,
718 const uint8_t *buf)
719{
720 struct mxc_nand_host *host = chip->priv;
721 int eccsize = chip->ecc.size;
722 int eccbytes = chip->ecc.bytes;
723 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
724 uint8_t *oob = chip->oob_poi;
725 int steps, size;
726 int n;
727
728 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
729 host->col_addr = n * eccsize;
730 chip->write_buf(mtd, buf, eccsize);
731 buf += eccsize;
732
733 host->col_addr = mtd->writesize + n * eccpitch;
734
735 if (chip->ecc.prepad) {
736 chip->write_buf(mtd, oob, chip->ecc.prepad);
737 oob += chip->ecc.prepad;
738 }
739
740 host->col_addr += eccbytes;
741 oob += eccbytes;
742
743 if (chip->ecc.postpad) {
744 chip->write_buf(mtd, oob, chip->ecc.postpad);
745 oob += chip->ecc.postpad;
746 }
747 }
748
749 size = mtd->oobsize - (oob - chip->oob_poi);
750 if (size)
751 chip->write_buf(mtd, oob, size);
752}
753
754static void mxc_nand_write_page_syndrome(struct mtd_info *mtd,
755 struct nand_chip *chip,
756 const uint8_t *buf)
757{
758 struct mxc_nand_host *host = chip->priv;
759 int i, n, eccsize = chip->ecc.size;
760 int eccbytes = chip->ecc.bytes;
761 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
762 int eccsteps = chip->ecc.steps;
763 const uint8_t *p = buf;
764 uint8_t *oob = chip->oob_poi;
765
766 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
767
768 for (i = n = 0;
769 eccsteps;
770 n++, eccsteps--, i += eccbytes, p += eccsize) {
771 host->col_addr = n * eccsize;
772
773 chip->write_buf(mtd, p, eccsize);
774
775 host->col_addr = mtd->writesize + n * eccpitch;
776
777 if (chip->ecc.prepad) {
778 chip->write_buf(mtd, oob, chip->ecc.prepad);
779 oob += chip->ecc.prepad;
780 }
781
782 chip->write_buf(mtd, oob, eccbytes);
783 oob += eccbytes;
784
785 if (chip->ecc.postpad) {
786 chip->write_buf(mtd, oob, chip->ecc.postpad);
787 oob += chip->ecc.postpad;
788 }
789 }
790
791 /* Calculate remaining oob bytes */
792 i = mtd->oobsize - (oob - chip->oob_poi);
793 if (i)
794 chip->write_buf(mtd, oob, i);
795}
796
797static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
798 u_char *read_ecc, u_char *calc_ecc)
799{
800 struct nand_chip *nand_chip = mtd->priv;
801 struct mxc_nand_host *host = nand_chip->priv;
802 uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result);
803 int subpages = mtd->writesize / nand_chip->subpagesize;
804 int pg2blk_shift = nand_chip->phys_erase_shift -
805 nand_chip->page_shift;
806
807 do {
808 if ((ecc_status & 0xf) > 4) {
809 static int last_bad = -1;
810
811 if (last_bad != host->page_addr >> pg2blk_shift) {
812 last_bad = host->page_addr >> pg2blk_shift;
813 printk(KERN_DEBUG
814 "MXC_NAND: HWECC uncorrectable ECC error"
815 " in block %u page %u subpage %d\n",
816 last_bad, host->page_addr,
817 mtd->writesize / nand_chip->subpagesize
818 - subpages);
819 }
820 return -1;
821 }
822 ecc_status >>= 4;
823 subpages--;
824 } while (subpages > 0);
825
826 return 0;
827}
828#else
829#define mxc_nand_read_page_syndrome NULL
830#define mxc_nand_read_page_raw_syndrome NULL
831#define mxc_nand_read_oob_syndrome NULL
832#define mxc_nand_write_page_syndrome NULL
833#define mxc_nand_write_page_raw_syndrome NULL
834#define mxc_nand_write_oob_syndrome NULL
835#define mxc_nfc_11_nand_correct_data NULL
836
Ilya Yanok36fab992009-08-11 02:32:54 +0400837static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
838 u_char *read_ecc, u_char *calc_ecc)
839{
840 struct nand_chip *nand_chip = mtd->priv;
841 struct mxc_nand_host *host = nand_chip->priv;
842
843 /*
844 * 1-Bit errors are automatically corrected in HW. No need for
845 * additional correction. 2-Bit errors cannot be corrected by
846 * HW ECC, so we need to return failure
847 */
848 uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result);
849
850 if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
851 MTDDEBUG(MTD_DEBUG_LEVEL0,
852 "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
853 return -1;
854 }
855
856 return 0;
857}
John Rigbyb081c2e2010-01-26 19:24:18 -0700858#endif
859
860
Ilya Yanok36fab992009-08-11 02:32:54 +0400861
862static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
863 u_char *ecc_code)
864{
865 return 0;
866}
867#endif
868
869static u_char mxc_nand_read_byte(struct mtd_info *mtd)
870{
871 struct nand_chip *nand_chip = mtd->priv;
872 struct mxc_nand_host *host = nand_chip->priv;
873 uint8_t ret = 0;
874 uint16_t col;
875 uint16_t __iomem *main_buf =
John Rigbyb081c2e2010-01-26 19:24:18 -0700876 (uint16_t __iomem *)host->regs->main_area[0];
Ilya Yanok36fab992009-08-11 02:32:54 +0400877 uint16_t __iomem *spare_buf =
John Rigbyb081c2e2010-01-26 19:24:18 -0700878 (uint16_t __iomem *)host->regs->spare_area[0];
Ilya Yanok36fab992009-08-11 02:32:54 +0400879 union {
880 uint16_t word;
881 uint8_t bytes[2];
882 } nfc_word;
883
884 /* Check for status request */
885 if (host->status_request)
886 return get_dev_status(host) & 0xFF;
887
888 /* Get column for 16-bit access */
889 col = host->col_addr >> 1;
890
891 /* If we are accessing the spare region */
892 if (host->spare_only)
893 nfc_word.word = readw(&spare_buf[col]);
894 else
895 nfc_word.word = readw(&main_buf[col]);
896
897 /* Pick upper/lower byte of word from RAM buffer */
898 ret = nfc_word.bytes[host->col_addr & 0x1];
899
900 /* Update saved column address */
901 if (nand_chip->options & NAND_BUSWIDTH_16)
902 host->col_addr += 2;
903 else
904 host->col_addr++;
905
906 return ret;
907}
908
909static uint16_t mxc_nand_read_word(struct mtd_info *mtd)
910{
911 struct nand_chip *nand_chip = mtd->priv;
912 struct mxc_nand_host *host = nand_chip->priv;
913 uint16_t col, ret;
914 uint16_t __iomem *p;
915
916 MTDDEBUG(MTD_DEBUG_LEVEL3,
917 "mxc_nand_read_word(col = %d)\n", host->col_addr);
918
919 col = host->col_addr;
920 /* Adjust saved column address */
921 if (col < mtd->writesize && host->spare_only)
922 col += mtd->writesize;
923
924 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700925 p = (uint16_t __iomem *)(host->regs->main_area[0] +
926 (col >> 1));
Ilya Yanok36fab992009-08-11 02:32:54 +0400927 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700928 p = (uint16_t __iomem *)(host->regs->spare_area[0] +
Ilya Yanok36fab992009-08-11 02:32:54 +0400929 ((col - mtd->writesize) >> 1));
930 }
931
932 if (col & 1) {
933 union {
934 uint16_t word;
935 uint8_t bytes[2];
936 } nfc_word[3];
937
938 nfc_word[0].word = readw(p);
939 nfc_word[1].word = readw(p + 1);
940
941 nfc_word[2].bytes[0] = nfc_word[0].bytes[1];
942 nfc_word[2].bytes[1] = nfc_word[1].bytes[0];
943
944 ret = nfc_word[2].word;
945 } else {
946 ret = readw(p);
947 }
948
949 /* Update saved column address */
950 host->col_addr = col + 2;
951
952 return ret;
953}
954
955/*
956 * Write data of length len to buffer buf. The data to be
957 * written on NAND Flash is first copied to RAMbuffer. After the Data Input
958 * Operation by the NFC, the data is written to NAND Flash
959 */
960static void mxc_nand_write_buf(struct mtd_info *mtd,
961 const u_char *buf, int len)
962{
963 struct nand_chip *nand_chip = mtd->priv;
964 struct mxc_nand_host *host = nand_chip->priv;
965 int n, col, i = 0;
966
967 MTDDEBUG(MTD_DEBUG_LEVEL3,
968 "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr,
969 len);
970
971 col = host->col_addr;
972
973 /* Adjust saved column address */
974 if (col < mtd->writesize && host->spare_only)
975 col += mtd->writesize;
976
977 n = mtd->writesize + mtd->oobsize - col;
978 n = min(len, n);
979
980 MTDDEBUG(MTD_DEBUG_LEVEL3,
981 "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n);
982
983 while (n > 0) {
984 void __iomem *p;
985
986 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700987 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanok36fab992009-08-11 02:32:54 +0400988 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700989 p = host->regs->spare_area[0] -
Ilya Yanok36fab992009-08-11 02:32:54 +0400990 mtd->writesize + (col & ~3);
991 }
992
993 MTDDEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__,
994 __LINE__, p);
995
996 if (((col | (unsigned long)&buf[i]) & 3) || n < 4) {
997 union {
998 uint32_t word;
999 uint8_t bytes[4];
1000 } nfc_word;
1001
1002 nfc_word.word = readl(p);
1003 nfc_word.bytes[col & 3] = buf[i++];
1004 n--;
1005 col++;
1006
1007 writel(nfc_word.word, p);
1008 } else {
1009 int m = mtd->writesize - col;
1010
1011 if (col >= mtd->writesize)
1012 m += mtd->oobsize;
1013
1014 m = min(n, m) & ~3;
1015
1016 MTDDEBUG(MTD_DEBUG_LEVEL3,
1017 "%s:%d: n = %d, m = %d, i = %d, col = %d\n",
1018 __func__, __LINE__, n, m, i, col);
1019
1020 mxc_nand_memcpy32(p, (uint32_t *)&buf[i], m);
1021 col += m;
1022 i += m;
1023 n -= m;
1024 }
1025 }
1026 /* Update saved column address */
1027 host->col_addr = col;
1028}
1029
1030/*
1031 * Read the data buffer from the NAND Flash. To read the data from NAND
1032 * Flash first the data output cycle is initiated by the NFC, which copies
1033 * the data to RAMbuffer. This data of length len is then copied to buffer buf.
1034 */
1035static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1036{
1037 struct nand_chip *nand_chip = mtd->priv;
1038 struct mxc_nand_host *host = nand_chip->priv;
1039 int n, col, i = 0;
1040
1041 MTDDEBUG(MTD_DEBUG_LEVEL3,
1042 "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len);
1043
1044 col = host->col_addr;
1045
1046 /* Adjust saved column address */
1047 if (col < mtd->writesize && host->spare_only)
1048 col += mtd->writesize;
1049
1050 n = mtd->writesize + mtd->oobsize - col;
1051 n = min(len, n);
1052
1053 while (n > 0) {
1054 void __iomem *p;
1055
1056 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -07001057 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanok36fab992009-08-11 02:32:54 +04001058 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -07001059 p = host->regs->spare_area[0] -
Ilya Yanok36fab992009-08-11 02:32:54 +04001060 mtd->writesize + (col & ~3);
1061 }
1062
1063 if (((col | (int)&buf[i]) & 3) || n < 4) {
1064 union {
1065 uint32_t word;
1066 uint8_t bytes[4];
1067 } nfc_word;
1068
1069 nfc_word.word = readl(p);
1070 buf[i++] = nfc_word.bytes[col & 3];
1071 n--;
1072 col++;
1073 } else {
1074 int m = mtd->writesize - col;
1075
1076 if (col >= mtd->writesize)
1077 m += mtd->oobsize;
1078
1079 m = min(n, m) & ~3;
1080 mxc_nand_memcpy32((uint32_t *)&buf[i], p, m);
1081
1082 col += m;
1083 i += m;
1084 n -= m;
1085 }
1086 }
1087 /* Update saved column address */
1088 host->col_addr = col;
1089}
1090
1091/*
1092 * Used by the upper layer to verify the data in NAND Flash
1093 * with the data in the buf.
1094 */
1095static int mxc_nand_verify_buf(struct mtd_info *mtd,
1096 const u_char *buf, int len)
1097{
1098 u_char tmp[256];
1099 uint bsize;
1100
1101 while (len) {
1102 bsize = min(len, 256);
1103 mxc_nand_read_buf(mtd, tmp, bsize);
1104
1105 if (memcmp(buf, tmp, bsize))
1106 return 1;
1107
1108 buf += bsize;
1109 len -= bsize;
1110 }
1111
1112 return 0;
1113}
1114
1115/*
1116 * This function is used by upper layer for select and
1117 * deselect of the NAND chip
1118 */
1119static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
1120{
1121 struct nand_chip *nand_chip = mtd->priv;
1122 struct mxc_nand_host *host = nand_chip->priv;
1123
1124 switch (chip) {
1125 case -1:
1126 /* TODO: Disable the NFC clock */
1127 if (host->clk_act)
1128 host->clk_act = 0;
1129 break;
1130 case 0:
1131 /* TODO: Enable the NFC clock */
1132 if (!host->clk_act)
1133 host->clk_act = 1;
1134 break;
1135
1136 default:
1137 break;
1138 }
1139}
1140
1141/*
1142 * Used by the upper layer to write command to NAND Flash for
1143 * different operations to be carried out on NAND Flash
1144 */
John Rigbyb081c2e2010-01-26 19:24:18 -07001145void mxc_nand_command(struct mtd_info *mtd, unsigned command,
Ilya Yanok36fab992009-08-11 02:32:54 +04001146 int column, int page_addr)
1147{
1148 struct nand_chip *nand_chip = mtd->priv;
1149 struct mxc_nand_host *host = nand_chip->priv;
1150
1151 MTDDEBUG(MTD_DEBUG_LEVEL3,
1152 "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
1153 command, column, page_addr);
1154
1155 /* Reset command state information */
1156 host->status_request = false;
1157
1158 /* Command pre-processing step */
1159 switch (command) {
1160
1161 case NAND_CMD_STATUS:
1162 host->col_addr = 0;
1163 host->status_request = true;
1164 break;
1165
1166 case NAND_CMD_READ0:
John Rigbyb081c2e2010-01-26 19:24:18 -07001167 host->page_addr = page_addr;
Ilya Yanok36fab992009-08-11 02:32:54 +04001168 host->col_addr = column;
1169 host->spare_only = false;
1170 break;
1171
1172 case NAND_CMD_READOOB:
1173 host->col_addr = column;
1174 host->spare_only = true;
1175 if (host->pagesize_2k)
1176 command = NAND_CMD_READ0; /* only READ0 is valid */
1177 break;
1178
1179 case NAND_CMD_SEQIN:
1180 if (column >= mtd->writesize) {
1181 /*
1182 * before sending SEQIN command for partial write,
1183 * we need read one page out. FSL NFC does not support
1184 * partial write. It alway send out 512+ecc+512+ecc ...
1185 * for large page nand flash. But for small page nand
1186 * flash, it does support SPARE ONLY operation.
1187 */
1188 if (host->pagesize_2k) {
1189 /* call ourself to read a page */
1190 mxc_nand_command(mtd, NAND_CMD_READ0, 0,
1191 page_addr);
1192 }
1193
1194 host->col_addr = column - mtd->writesize;
1195 host->spare_only = true;
1196
1197 /* Set program pointer to spare region */
1198 if (!host->pagesize_2k)
1199 send_cmd(host, NAND_CMD_READOOB);
1200 } else {
1201 host->spare_only = false;
1202 host->col_addr = column;
1203
1204 /* Set program pointer to page start */
1205 if (!host->pagesize_2k)
1206 send_cmd(host, NAND_CMD_READ0);
1207 }
1208 break;
1209
1210 case NAND_CMD_PAGEPROG:
1211 send_prog_page(host, 0, host->spare_only);
1212
John Rigbyb081c2e2010-01-26 19:24:18 -07001213 if (host->pagesize_2k && !is_mxc_nfc_11()) {
Ilya Yanok36fab992009-08-11 02:32:54 +04001214 /* data in 4 areas datas */
1215 send_prog_page(host, 1, host->spare_only);
1216 send_prog_page(host, 2, host->spare_only);
1217 send_prog_page(host, 3, host->spare_only);
1218 }
1219
1220 break;
1221 }
1222
1223 /* Write out the command to the device. */
1224 send_cmd(host, command);
1225
1226 /* Write out column address, if necessary */
1227 if (column != -1) {
1228 /*
1229 * MXC NANDFC can only perform full page+spare or
1230 * spare-only read/write. When the upper layers
1231 * layers perform a read/write buf operation,
1232 * we will used the saved column adress to index into
1233 * the full page.
1234 */
1235 send_addr(host, 0);
1236 if (host->pagesize_2k)
1237 /* another col addr cycle for 2k page */
1238 send_addr(host, 0);
1239 }
1240
1241 /* Write out page address, if necessary */
1242 if (page_addr != -1) {
John Rigbyb081c2e2010-01-26 19:24:18 -07001243 u32 page_mask = nand_chip->pagemask;
1244 do {
1245 send_addr(host, page_addr & 0xFF);
1246 page_addr >>= 8;
1247 page_mask >>= 8;
1248 } while (page_mask);
Ilya Yanok36fab992009-08-11 02:32:54 +04001249 }
1250
1251 /* Command post-processing step */
1252 switch (command) {
1253
1254 case NAND_CMD_RESET:
1255 break;
1256
1257 case NAND_CMD_READOOB:
1258 case NAND_CMD_READ0:
1259 if (host->pagesize_2k) {
1260 /* send read confirm command */
1261 send_cmd(host, NAND_CMD_READSTART);
1262 /* read for each AREA */
1263 send_read_page(host, 0, host->spare_only);
John Rigbyb081c2e2010-01-26 19:24:18 -07001264 if (!is_mxc_nfc_11()) {
1265 send_read_page(host, 1, host->spare_only);
1266 send_read_page(host, 2, host->spare_only);
1267 send_read_page(host, 3, host->spare_only);
1268 }
Ilya Yanok36fab992009-08-11 02:32:54 +04001269 } else {
1270 send_read_page(host, 0, host->spare_only);
1271 }
1272 break;
1273
1274 case NAND_CMD_READID:
1275 host->col_addr = 0;
1276 send_read_id(host);
1277 break;
1278
1279 case NAND_CMD_PAGEPROG:
1280 break;
1281
1282 case NAND_CMD_STATUS:
1283 break;
1284
1285 case NAND_CMD_ERASE2:
1286 break;
1287 }
1288}
1289
John Rigbyb081c2e2010-01-26 19:24:18 -07001290#ifdef MXC_NFC_V1_1
1291static void mxc_setup_config1(void)
1292{
1293 uint16_t tmp;
1294
1295 tmp = readw(&host->regs->nfc_config1);
1296 tmp |= NFC_ONE_CYCLE;
1297 tmp |= NFC_4_8N_ECC;
1298 writew(tmp, &host->regs->nfc_config1);
1299 if (host->pagesize_2k)
1300 writew(64/2, &host->regs->nfc_spare_area_size);
1301 else
1302 writew(16/2, &host->regs->nfc_spare_area_size);
1303}
1304#else
1305#define mxc_setup_config1()
1306#endif
1307
Ilya Yanok36fab992009-08-11 02:32:54 +04001308int board_nand_init(struct nand_chip *this)
1309{
Ilya Yanok36fab992009-08-11 02:32:54 +04001310 struct mtd_info *mtd;
1311 uint16_t tmp;
1312 int err = 0;
1313
1314 /* structures must be linked */
1315 mtd = &host->mtd;
1316 mtd->priv = this;
1317 host->nand = this;
1318
1319 /* 5 us command delay time */
1320 this->chip_delay = 5;
1321
1322 this->priv = host;
1323 this->dev_ready = mxc_nand_dev_ready;
1324 this->cmdfunc = mxc_nand_command;
1325 this->select_chip = mxc_nand_select_chip;
1326 this->read_byte = mxc_nand_read_byte;
1327 this->read_word = mxc_nand_read_word;
1328 this->write_buf = mxc_nand_write_buf;
1329 this->read_buf = mxc_nand_read_buf;
1330 this->verify_buf = mxc_nand_verify_buf;
1331
1332 host->regs = (struct nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
1333 host->clk_act = 1;
1334
1335#ifdef CONFIG_MXC_NAND_HWECC
1336 this->ecc.calculate = mxc_nand_calculate_ecc;
1337 this->ecc.hwctl = mxc_nand_enable_hwecc;
1338 this->ecc.correct = mxc_nand_correct_data;
John Rigbyb081c2e2010-01-26 19:24:18 -07001339 if (is_mxc_nfc_11()) {
1340 this->ecc.mode = NAND_ECC_HW_SYNDROME;
1341 this->ecc.read_page = mxc_nand_read_page_syndrome;
1342 this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome;
1343 this->ecc.read_oob = mxc_nand_read_oob_syndrome;
1344 this->ecc.write_page = mxc_nand_write_page_syndrome;
1345 this->ecc.write_page_raw = mxc_nand_write_page_raw_syndrome;
1346 this->ecc.write_oob = mxc_nand_write_oob_syndrome;
1347 this->ecc.bytes = 9;
1348 this->ecc.prepad = 7;
1349 } else {
1350 this->ecc.mode = NAND_ECC_HW;
1351 }
1352
1353 host->pagesize_2k = 0;
1354
Ilya Yanok36fab992009-08-11 02:32:54 +04001355 this->ecc.size = 512;
Ilya Yanok36fab992009-08-11 02:32:54 +04001356 tmp = readw(&host->regs->nfc_config1);
1357 tmp |= NFC_ECC_EN;
1358 writew(tmp, &host->regs->nfc_config1);
1359#else
1360 this->ecc.layout = &nand_soft_eccoob;
1361 this->ecc.mode = NAND_ECC_SOFT;
1362 tmp = readw(&host->regs->nfc_config1);
1363 tmp &= ~NFC_ECC_EN;
1364 writew(tmp, &host->regs->nfc_config1);
1365#endif
Ilya Yanok36fab992009-08-11 02:32:54 +04001366 /* Reset NAND */
1367 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1368
1369 /*
1370 * preset operation
1371 * Unlock the internal RAM Buffer
1372 */
1373 writew(0x2, &host->regs->nfc_config);
1374
1375 /* Blocks to be unlocked */
1376 writew(0x0, &host->regs->nfc_unlockstart_blkaddr);
1377 writew(0x4000, &host->regs->nfc_unlockend_blkaddr);
1378
1379 /* Unlock Block Command for given address range */
1380 writew(0x4, &host->regs->nfc_wrprot);
1381
1382 /* NAND bus width determines access funtions used by upper layer */
Magnus Liljaf6a97482009-11-11 20:18:43 +01001383 if (is_16bit_nand())
Ilya Yanok36fab992009-08-11 02:32:54 +04001384 this->options |= NAND_BUSWIDTH_16;
1385
Magnus Liljac4832df2010-01-17 17:46:10 +01001386#ifdef CONFIG_SYS_NAND_LARGEPAGE
1387 host->pagesize_2k = 1;
John Rigbyb081c2e2010-01-26 19:24:18 -07001388 this->ecc.layout = &nand_hw_eccoob2k;
Magnus Liljac4832df2010-01-17 17:46:10 +01001389#else
Ilya Yanok36fab992009-08-11 02:32:54 +04001390 host->pagesize_2k = 0;
John Rigbyb081c2e2010-01-26 19:24:18 -07001391 this->ecc.layout = &nand_hw_eccoob;
Magnus Liljac4832df2010-01-17 17:46:10 +01001392#endif
John Rigbyb081c2e2010-01-26 19:24:18 -07001393 mxc_setup_config1();
Ilya Yanok36fab992009-08-11 02:32:54 +04001394 return err;
1395}