blob: bb475f2f68d62470bc6c90edec0fe33ab44afd7d [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
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +020080#elif defined(MXC_NFC_V2_1)
John Rigbyb081c2e2010-01-26 19:24:18 -070081#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 +0100101static int is_16bit_nand(void)
102{
Fabio Estevama430e912013-04-11 09:35:35 +0000103#if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
104 return 1;
Magnus Liljaf6a97482009-11-11 20:18:43 +0100105#else
Magnus Liljaf6a97482009-11-11 20:18:43 +0100106 return 0;
Magnus Liljaf6a97482009-11-11 20:18:43 +0100107#endif
Fabio Estevama430e912013-04-11 09:35:35 +0000108}
Magnus Liljaf6a97482009-11-11 20:18:43 +0100109
Ilya Yanok36fab992009-08-11 02:32:54 +0400110static uint32_t *mxc_nand_memcpy32(uint32_t *dest, uint32_t *source, size_t size)
111{
112 uint32_t *d = dest;
113
114 size >>= 2;
115 while (size--)
116 __raw_writel(__raw_readl(source++), d++);
117 return dest;
118}
119
120/*
121 * This function polls the NANDFC to wait for the basic operation to
122 * complete by checking the INT bit of config2 register.
123 */
124static void wait_op_done(struct mxc_nand_host *host, int max_retries,
125 uint16_t param)
126{
127 uint32_t tmp;
128
129 while (max_retries-- > 0) {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200130 if (readw(&host->regs->config2) & NFC_INT) {
131 tmp = readw(&host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400132 tmp &= ~NFC_INT;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200133 writew(tmp, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400134 break;
135 }
136 udelay(1);
137 }
138 if (max_retries < 0) {
139 MTDDEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
140 __func__, param);
141 }
142}
143
144/*
145 * This function issues the specified command to the NAND device and
146 * waits for completion.
147 */
148static void send_cmd(struct mxc_nand_host *host, uint16_t cmd)
149{
150 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd);
151
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200152 writew(cmd, &host->regs->flash_cmd);
153 writew(NFC_CMD, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400154
155 /* Wait for operation to complete */
156 wait_op_done(host, TROP_US_DELAY, cmd);
157}
158
159/*
160 * This function sends an address (or partial address) to the
161 * NAND device. The address is used to select the source/destination for
162 * a NAND command.
163 */
164static void send_addr(struct mxc_nand_host *host, uint16_t addr)
165{
166 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr);
167
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200168 writew(addr, &host->regs->flash_addr);
169 writew(NFC_ADDR, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400170
171 /* Wait for operation to complete */
172 wait_op_done(host, TROP_US_DELAY, addr);
173}
174
175/*
Helmut Raiger780f30b2011-07-06 09:40:28 +0200176 * This function requests the NANDFC to initiate the transfer
Ilya Yanok36fab992009-08-11 02:32:54 +0400177 * of data currently in the NANDFC RAM buffer to the NAND device.
178 */
179static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
180 int spare_only)
181{
John Rigbyb081c2e2010-01-26 19:24:18 -0700182 if (spare_only)
183 MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only);
184
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +0200185 if (is_mxc_nfc_21()) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700186 int i;
187 /*
188 * The controller copies the 64 bytes of spare data from
189 * the first 16 bytes of each of the 4 64 byte spare buffers.
190 * Copy the contiguous data starting in spare_area[0] to
191 * the four spare area buffers.
192 */
193 for (i = 1; i < 4; i++) {
194 void __iomem *src = &host->regs->spare_area[0][i * 16];
195 void __iomem *dst = &host->regs->spare_area[i][0];
196
197 mxc_nand_memcpy32(dst, src, 16);
198 }
199 }
Ilya Yanok36fab992009-08-11 02:32:54 +0400200
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200201 writew(buf_id, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400202
203 /* Configure spare or page+spare access */
204 if (!host->pagesize_2k) {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200205 uint16_t config1 = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400206 if (spare_only)
207 config1 |= NFC_SP_EN;
208 else
Benoît Thébaudeau365b2c02012-08-13 22:48:26 +0200209 config1 &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200210 writew(config1, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400211 }
212
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200213 writew(NFC_INPUT, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400214
215 /* Wait for operation to complete */
216 wait_op_done(host, TROP_US_DELAY, spare_only);
217}
218
219/*
Helmut Raiger780f30b2011-07-06 09:40:28 +0200220 * Requests NANDFC to initiate the transfer of data from the
Ilya Yanok36fab992009-08-11 02:32:54 +0400221 * NAND device into in the NANDFC ram buffer.
222 */
223static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
224 int spare_only)
225{
226 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
227
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200228 writew(buf_id, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400229
230 /* Configure spare or page+spare access */
231 if (!host->pagesize_2k) {
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200232 uint32_t config1 = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400233 if (spare_only)
234 config1 |= NFC_SP_EN;
235 else
236 config1 &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200237 writew(config1, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400238 }
239
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200240 writew(NFC_OUTPUT, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400241
242 /* Wait for operation to complete */
243 wait_op_done(host, TROP_US_DELAY, spare_only);
John Rigbyb081c2e2010-01-26 19:24:18 -0700244
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +0200245 if (is_mxc_nfc_21()) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700246 int i;
247
248 /*
249 * The controller copies the 64 bytes of spare data to
250 * the first 16 bytes of each of the 4 spare buffers.
251 * Make the data contiguous starting in spare_area[0].
252 */
253 for (i = 1; i < 4; i++) {
254 void __iomem *src = &host->regs->spare_area[i][0];
255 void __iomem *dst = &host->regs->spare_area[0][i * 16];
256
257 mxc_nand_memcpy32(dst, src, 16);
258 }
259 }
Ilya Yanok36fab992009-08-11 02:32:54 +0400260}
261
262/* Request the NANDFC to perform a read of the NAND device ID. */
263static void send_read_id(struct mxc_nand_host *host)
264{
265 uint16_t tmp;
266
267 /* NANDFC buffer 0 is used for device ID output */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200268 writew(0x0, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400269
270 /* Read ID into main buffer */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200271 tmp = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400272 tmp &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200273 writew(tmp, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400274
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200275 writew(NFC_ID, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400276
277 /* Wait for operation to complete */
278 wait_op_done(host, TROP_US_DELAY, 0);
279}
280
281/*
282 * This function requests the NANDFC to perform a read of the
283 * NAND device status and returns the current status.
284 */
285static uint16_t get_dev_status(struct mxc_nand_host *host)
286{
John Rigbyb081c2e2010-01-26 19:24:18 -0700287 void __iomem *main_buf = host->regs->main_area[1];
Ilya Yanok36fab992009-08-11 02:32:54 +0400288 uint32_t store;
289 uint16_t ret, tmp;
290 /* Issue status request to NAND device */
291
292 /* store the main area1 first word, later do recovery */
293 store = readl(main_buf);
294 /* NANDFC buffer 1 is used for device status */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200295 writew(1, &host->regs->buf_addr);
Ilya Yanok36fab992009-08-11 02:32:54 +0400296
297 /* Read status into main buffer */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200298 tmp = readw(&host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400299 tmp &= ~NFC_SP_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200300 writew(tmp, &host->regs->config1);
Ilya Yanok36fab992009-08-11 02:32:54 +0400301
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200302 writew(NFC_STATUS, &host->regs->config2);
Ilya Yanok36fab992009-08-11 02:32:54 +0400303
304 /* Wait for operation to complete */
305 wait_op_done(host, TROP_US_DELAY, 0);
306
307 /*
308 * Status is placed in first word of main buffer
309 * get status, then recovery area 1 data
310 */
311 ret = readw(main_buf);
312 writel(store, main_buf);
313
314 return ret;
315}
316
317/* This function is used by upper layer to checks if device is ready */
318static int mxc_nand_dev_ready(struct mtd_info *mtd)
319{
320 /*
321 * NFC handles R/B internally. Therefore, this function
322 * always returns status as ready.
323 */
324 return 1;
325}
326
John Rigbyb081c2e2010-01-26 19:24:18 -0700327static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on)
328{
329 struct nand_chip *nand_chip = mtd->priv;
330 struct mxc_nand_host *host = nand_chip->priv;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200331 uint16_t tmp = readw(&host->regs->config1);
John Rigbyb081c2e2010-01-26 19:24:18 -0700332
333 if (on)
334 tmp |= NFC_ECC_EN;
335 else
336 tmp &= ~NFC_ECC_EN;
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200337 writew(tmp, &host->regs->config1);
John Rigbyb081c2e2010-01-26 19:24:18 -0700338}
339
Benoît Thébaudeau0e499b02012-08-13 22:50:07 +0200340#ifdef CONFIG_MXC_NAND_HWECC
341static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
342{
343 /*
344 * If HW ECC is enabled, we turn it on during init. There is
345 * no need to enable again here.
346 */
347}
348
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +0200349#ifdef MXC_NFC_V2_1
John Rigbyb081c2e2010-01-26 19:24:18 -0700350static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
351 struct nand_chip *chip,
352 int page, int sndcmd)
353{
354 struct mxc_nand_host *host = chip->priv;
355 uint8_t *buf = chip->oob_poi;
356 int length = mtd->oobsize;
357 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
358 uint8_t *bufpoi = buf;
359 int i, toread;
360
361 MTDDEBUG(MTD_DEBUG_LEVEL0,
362 "%s: Reading OOB area of page %u to oob %p\n",
363 __FUNCTION__, host->page_addr, buf);
364
365 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, page);
366 for (i = 0; i < chip->ecc.steps; i++) {
367 toread = min_t(int, length, chip->ecc.prepad);
368 if (toread) {
369 chip->read_buf(mtd, bufpoi, toread);
370 bufpoi += toread;
371 length -= toread;
372 }
373 bufpoi += chip->ecc.bytes;
374 host->col_addr += chip->ecc.bytes;
375 length -= chip->ecc.bytes;
376
377 toread = min_t(int, length, chip->ecc.postpad);
378 if (toread) {
379 chip->read_buf(mtd, bufpoi, toread);
380 bufpoi += toread;
381 length -= toread;
382 }
383 }
384 if (length > 0)
385 chip->read_buf(mtd, bufpoi, length);
386
387 _mxc_nand_enable_hwecc(mtd, 0);
388 chip->cmdfunc(mtd, NAND_CMD_READOOB,
389 mtd->writesize + chip->ecc.prepad, page);
390 bufpoi = buf + chip->ecc.prepad;
391 length = mtd->oobsize - chip->ecc.prepad;
392 for (i = 0; i < chip->ecc.steps; i++) {
393 toread = min_t(int, length, chip->ecc.bytes);
394 chip->read_buf(mtd, bufpoi, toread);
395 bufpoi += eccpitch;
396 length -= eccpitch;
397 host->col_addr += chip->ecc.postpad + chip->ecc.prepad;
398 }
399 _mxc_nand_enable_hwecc(mtd, 1);
400 return 1;
401}
402
403static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd,
404 struct nand_chip *chip,
405 uint8_t *buf,
406 int page)
407{
408 struct mxc_nand_host *host = chip->priv;
409 int eccsize = chip->ecc.size;
410 int eccbytes = chip->ecc.bytes;
411 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
412 uint8_t *oob = chip->oob_poi;
413 int steps, size;
414 int n;
415
416 _mxc_nand_enable_hwecc(mtd, 0);
417 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, host->page_addr);
418
419 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
420 host->col_addr = n * eccsize;
421 chip->read_buf(mtd, buf, eccsize);
422 buf += eccsize;
423
424 host->col_addr = mtd->writesize + n * eccpitch;
425 if (chip->ecc.prepad) {
426 chip->read_buf(mtd, oob, chip->ecc.prepad);
427 oob += chip->ecc.prepad;
428 }
429
430 chip->read_buf(mtd, oob, eccbytes);
431 oob += eccbytes;
432
433 if (chip->ecc.postpad) {
434 chip->read_buf(mtd, oob, chip->ecc.postpad);
435 oob += chip->ecc.postpad;
436 }
437 }
438
439 size = mtd->oobsize - (oob - chip->oob_poi);
440 if (size)
441 chip->read_buf(mtd, oob, size);
Benoît Thébaudeau7c28a1c2012-08-13 22:50:19 +0200442 _mxc_nand_enable_hwecc(mtd, 1);
John Rigbyb081c2e2010-01-26 19:24:18 -0700443
444 return 0;
445}
446
447static int mxc_nand_read_page_syndrome(struct mtd_info *mtd,
448 struct nand_chip *chip,
449 uint8_t *buf,
450 int page)
451{
452 struct mxc_nand_host *host = chip->priv;
453 int n, eccsize = chip->ecc.size;
454 int eccbytes = chip->ecc.bytes;
455 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
456 int eccsteps = chip->ecc.steps;
457 uint8_t *p = buf;
458 uint8_t *oob = chip->oob_poi;
459
460 MTDDEBUG(MTD_DEBUG_LEVEL1, "Reading page %u to buf %p oob %p\n",
461 host->page_addr, buf, oob);
462
Helmut Raiger780f30b2011-07-06 09:40:28 +0200463 /* first read the data area and the available portion of OOB */
John Rigbyb081c2e2010-01-26 19:24:18 -0700464 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
465 int stat;
466
467 host->col_addr = n * eccsize;
468
469 chip->read_buf(mtd, p, eccsize);
470
471 host->col_addr = mtd->writesize + n * eccpitch;
472
473 if (chip->ecc.prepad) {
474 chip->read_buf(mtd, oob, chip->ecc.prepad);
475 oob += chip->ecc.prepad;
476 }
477
478 stat = chip->ecc.correct(mtd, p, oob, NULL);
479
480 if (stat < 0)
481 mtd->ecc_stats.failed++;
482 else
483 mtd->ecc_stats.corrected += stat;
484 oob += eccbytes;
485
486 if (chip->ecc.postpad) {
487 chip->read_buf(mtd, oob, chip->ecc.postpad);
488 oob += chip->ecc.postpad;
489 }
490 }
491
492 /* Calculate remaining oob bytes */
493 n = mtd->oobsize - (oob - chip->oob_poi);
494 if (n)
495 chip->read_buf(mtd, oob, n);
496
497 /* Then switch ECC off and read the OOB area to get the ECC code */
498 _mxc_nand_enable_hwecc(mtd, 0);
499 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, host->page_addr);
500 eccsteps = chip->ecc.steps;
501 oob = chip->oob_poi + chip->ecc.prepad;
502 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
503 host->col_addr = mtd->writesize +
504 n * eccpitch +
505 chip->ecc.prepad;
506 chip->read_buf(mtd, oob, eccbytes);
507 oob += eccbytes + chip->ecc.postpad;
508 }
509 _mxc_nand_enable_hwecc(mtd, 1);
510 return 0;
511}
512
513static int mxc_nand_write_oob_syndrome(struct mtd_info *mtd,
514 struct nand_chip *chip, int page)
515{
516 struct mxc_nand_host *host = chip->priv;
517 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
518 int length = mtd->oobsize;
519 int i, len, status, steps = chip->ecc.steps;
520 const uint8_t *bufpoi = chip->oob_poi;
521
522 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
523 for (i = 0; i < steps; i++) {
524 len = min_t(int, length, eccpitch);
525
526 chip->write_buf(mtd, bufpoi, len);
527 bufpoi += len;
528 length -= len;
529 host->col_addr += chip->ecc.prepad + chip->ecc.postpad;
530 }
531 if (length > 0)
532 chip->write_buf(mtd, bufpoi, length);
533
534 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
535 status = chip->waitfunc(mtd, chip);
536 return status & NAND_STATUS_FAIL ? -EIO : 0;
537}
538
539static void mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
540 struct nand_chip *chip,
541 const uint8_t *buf)
542{
543 struct mxc_nand_host *host = chip->priv;
544 int eccsize = chip->ecc.size;
545 int eccbytes = chip->ecc.bytes;
546 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
547 uint8_t *oob = chip->oob_poi;
548 int steps, size;
549 int n;
550
551 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
552 host->col_addr = n * eccsize;
553 chip->write_buf(mtd, buf, eccsize);
554 buf += eccsize;
555
556 host->col_addr = mtd->writesize + n * eccpitch;
557
558 if (chip->ecc.prepad) {
559 chip->write_buf(mtd, oob, chip->ecc.prepad);
560 oob += chip->ecc.prepad;
561 }
562
563 host->col_addr += eccbytes;
564 oob += eccbytes;
565
566 if (chip->ecc.postpad) {
567 chip->write_buf(mtd, oob, chip->ecc.postpad);
568 oob += chip->ecc.postpad;
569 }
570 }
571
572 size = mtd->oobsize - (oob - chip->oob_poi);
573 if (size)
574 chip->write_buf(mtd, oob, size);
575}
576
577static void mxc_nand_write_page_syndrome(struct mtd_info *mtd,
578 struct nand_chip *chip,
579 const uint8_t *buf)
580{
581 struct mxc_nand_host *host = chip->priv;
582 int i, n, eccsize = chip->ecc.size;
583 int eccbytes = chip->ecc.bytes;
584 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
585 int eccsteps = chip->ecc.steps;
586 const uint8_t *p = buf;
587 uint8_t *oob = chip->oob_poi;
588
589 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
590
591 for (i = n = 0;
592 eccsteps;
593 n++, eccsteps--, i += eccbytes, p += eccsize) {
594 host->col_addr = n * eccsize;
595
596 chip->write_buf(mtd, p, eccsize);
597
598 host->col_addr = mtd->writesize + n * eccpitch;
599
600 if (chip->ecc.prepad) {
601 chip->write_buf(mtd, oob, chip->ecc.prepad);
602 oob += chip->ecc.prepad;
603 }
604
605 chip->write_buf(mtd, oob, eccbytes);
606 oob += eccbytes;
607
608 if (chip->ecc.postpad) {
609 chip->write_buf(mtd, oob, chip->ecc.postpad);
610 oob += chip->ecc.postpad;
611 }
612 }
613
614 /* Calculate remaining oob bytes */
615 i = mtd->oobsize - (oob - chip->oob_poi);
616 if (i)
617 chip->write_buf(mtd, oob, i);
618}
619
620static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
621 u_char *read_ecc, u_char *calc_ecc)
622{
623 struct nand_chip *nand_chip = mtd->priv;
624 struct mxc_nand_host *host = nand_chip->priv;
Benoît Thébaudeauc1db8dd2012-08-13 22:49:42 +0200625 uint32_t ecc_status = readl(&host->regs->ecc_status_result);
John Rigbyb081c2e2010-01-26 19:24:18 -0700626 int subpages = mtd->writesize / nand_chip->subpagesize;
627 int pg2blk_shift = nand_chip->phys_erase_shift -
628 nand_chip->page_shift;
629
630 do {
631 if ((ecc_status & 0xf) > 4) {
632 static int last_bad = -1;
633
634 if (last_bad != host->page_addr >> pg2blk_shift) {
635 last_bad = host->page_addr >> pg2blk_shift;
636 printk(KERN_DEBUG
637 "MXC_NAND: HWECC uncorrectable ECC error"
638 " in block %u page %u subpage %d\n",
639 last_bad, host->page_addr,
640 mtd->writesize / nand_chip->subpagesize
641 - subpages);
642 }
643 return -1;
644 }
645 ecc_status >>= 4;
646 subpages--;
647 } while (subpages > 0);
648
649 return 0;
650}
651#else
652#define mxc_nand_read_page_syndrome NULL
653#define mxc_nand_read_page_raw_syndrome NULL
654#define mxc_nand_read_oob_syndrome NULL
655#define mxc_nand_write_page_syndrome NULL
656#define mxc_nand_write_page_raw_syndrome NULL
657#define mxc_nand_write_oob_syndrome NULL
John Rigbyb081c2e2010-01-26 19:24:18 -0700658
Ilya Yanok36fab992009-08-11 02:32:54 +0400659static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
660 u_char *read_ecc, u_char *calc_ecc)
661{
662 struct nand_chip *nand_chip = mtd->priv;
663 struct mxc_nand_host *host = nand_chip->priv;
664
665 /*
666 * 1-Bit errors are automatically corrected in HW. No need for
667 * additional correction. 2-Bit errors cannot be corrected by
668 * HW ECC, so we need to return failure
669 */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +0200670 uint16_t ecc_status = readw(&host->regs->ecc_status_result);
Ilya Yanok36fab992009-08-11 02:32:54 +0400671
672 if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
673 MTDDEBUG(MTD_DEBUG_LEVEL0,
674 "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
675 return -1;
676 }
677
678 return 0;
679}
John Rigbyb081c2e2010-01-26 19:24:18 -0700680#endif
681
Ilya Yanok36fab992009-08-11 02:32:54 +0400682static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
683 u_char *ecc_code)
684{
685 return 0;
686}
687#endif
688
689static u_char mxc_nand_read_byte(struct mtd_info *mtd)
690{
691 struct nand_chip *nand_chip = mtd->priv;
692 struct mxc_nand_host *host = nand_chip->priv;
693 uint8_t ret = 0;
694 uint16_t col;
695 uint16_t __iomem *main_buf =
John Rigbyb081c2e2010-01-26 19:24:18 -0700696 (uint16_t __iomem *)host->regs->main_area[0];
Ilya Yanok36fab992009-08-11 02:32:54 +0400697 uint16_t __iomem *spare_buf =
John Rigbyb081c2e2010-01-26 19:24:18 -0700698 (uint16_t __iomem *)host->regs->spare_area[0];
Ilya Yanok36fab992009-08-11 02:32:54 +0400699 union {
700 uint16_t word;
701 uint8_t bytes[2];
702 } nfc_word;
703
704 /* Check for status request */
705 if (host->status_request)
706 return get_dev_status(host) & 0xFF;
707
708 /* Get column for 16-bit access */
709 col = host->col_addr >> 1;
710
711 /* If we are accessing the spare region */
712 if (host->spare_only)
713 nfc_word.word = readw(&spare_buf[col]);
714 else
715 nfc_word.word = readw(&main_buf[col]);
716
717 /* Pick upper/lower byte of word from RAM buffer */
718 ret = nfc_word.bytes[host->col_addr & 0x1];
719
720 /* Update saved column address */
721 if (nand_chip->options & NAND_BUSWIDTH_16)
722 host->col_addr += 2;
723 else
724 host->col_addr++;
725
726 return ret;
727}
728
729static uint16_t mxc_nand_read_word(struct mtd_info *mtd)
730{
731 struct nand_chip *nand_chip = mtd->priv;
732 struct mxc_nand_host *host = nand_chip->priv;
733 uint16_t col, ret;
734 uint16_t __iomem *p;
735
736 MTDDEBUG(MTD_DEBUG_LEVEL3,
737 "mxc_nand_read_word(col = %d)\n", host->col_addr);
738
739 col = host->col_addr;
740 /* Adjust saved column address */
741 if (col < mtd->writesize && host->spare_only)
742 col += mtd->writesize;
743
744 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700745 p = (uint16_t __iomem *)(host->regs->main_area[0] +
746 (col >> 1));
Ilya Yanok36fab992009-08-11 02:32:54 +0400747 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700748 p = (uint16_t __iomem *)(host->regs->spare_area[0] +
Ilya Yanok36fab992009-08-11 02:32:54 +0400749 ((col - mtd->writesize) >> 1));
750 }
751
752 if (col & 1) {
753 union {
754 uint16_t word;
755 uint8_t bytes[2];
756 } nfc_word[3];
757
758 nfc_word[0].word = readw(p);
759 nfc_word[1].word = readw(p + 1);
760
761 nfc_word[2].bytes[0] = nfc_word[0].bytes[1];
762 nfc_word[2].bytes[1] = nfc_word[1].bytes[0];
763
764 ret = nfc_word[2].word;
765 } else {
766 ret = readw(p);
767 }
768
769 /* Update saved column address */
770 host->col_addr = col + 2;
771
772 return ret;
773}
774
775/*
776 * Write data of length len to buffer buf. The data to be
777 * written on NAND Flash is first copied to RAMbuffer. After the Data Input
778 * Operation by the NFC, the data is written to NAND Flash
779 */
780static void mxc_nand_write_buf(struct mtd_info *mtd,
781 const u_char *buf, int len)
782{
783 struct nand_chip *nand_chip = mtd->priv;
784 struct mxc_nand_host *host = nand_chip->priv;
785 int n, col, i = 0;
786
787 MTDDEBUG(MTD_DEBUG_LEVEL3,
788 "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr,
789 len);
790
791 col = host->col_addr;
792
793 /* Adjust saved column address */
794 if (col < mtd->writesize && host->spare_only)
795 col += mtd->writesize;
796
797 n = mtd->writesize + mtd->oobsize - col;
798 n = min(len, n);
799
800 MTDDEBUG(MTD_DEBUG_LEVEL3,
801 "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n);
802
803 while (n > 0) {
804 void __iomem *p;
805
806 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700807 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanok36fab992009-08-11 02:32:54 +0400808 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700809 p = host->regs->spare_area[0] -
Ilya Yanok36fab992009-08-11 02:32:54 +0400810 mtd->writesize + (col & ~3);
811 }
812
813 MTDDEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__,
814 __LINE__, p);
815
816 if (((col | (unsigned long)&buf[i]) & 3) || n < 4) {
817 union {
818 uint32_t word;
819 uint8_t bytes[4];
820 } nfc_word;
821
822 nfc_word.word = readl(p);
823 nfc_word.bytes[col & 3] = buf[i++];
824 n--;
825 col++;
826
827 writel(nfc_word.word, p);
828 } else {
829 int m = mtd->writesize - col;
830
831 if (col >= mtd->writesize)
832 m += mtd->oobsize;
833
834 m = min(n, m) & ~3;
835
836 MTDDEBUG(MTD_DEBUG_LEVEL3,
837 "%s:%d: n = %d, m = %d, i = %d, col = %d\n",
838 __func__, __LINE__, n, m, i, col);
839
840 mxc_nand_memcpy32(p, (uint32_t *)&buf[i], m);
841 col += m;
842 i += m;
843 n -= m;
844 }
845 }
846 /* Update saved column address */
847 host->col_addr = col;
848}
849
850/*
851 * Read the data buffer from the NAND Flash. To read the data from NAND
852 * Flash first the data output cycle is initiated by the NFC, which copies
853 * the data to RAMbuffer. This data of length len is then copied to buffer buf.
854 */
855static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
856{
857 struct nand_chip *nand_chip = mtd->priv;
858 struct mxc_nand_host *host = nand_chip->priv;
859 int n, col, i = 0;
860
861 MTDDEBUG(MTD_DEBUG_LEVEL3,
862 "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len);
863
864 col = host->col_addr;
865
866 /* Adjust saved column address */
867 if (col < mtd->writesize && host->spare_only)
868 col += mtd->writesize;
869
870 n = mtd->writesize + mtd->oobsize - col;
871 n = min(len, n);
872
873 while (n > 0) {
874 void __iomem *p;
875
876 if (col < mtd->writesize) {
John Rigbyb081c2e2010-01-26 19:24:18 -0700877 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanok36fab992009-08-11 02:32:54 +0400878 } else {
John Rigbyb081c2e2010-01-26 19:24:18 -0700879 p = host->regs->spare_area[0] -
Ilya Yanok36fab992009-08-11 02:32:54 +0400880 mtd->writesize + (col & ~3);
881 }
882
883 if (((col | (int)&buf[i]) & 3) || n < 4) {
884 union {
885 uint32_t word;
886 uint8_t bytes[4];
887 } nfc_word;
888
889 nfc_word.word = readl(p);
890 buf[i++] = nfc_word.bytes[col & 3];
891 n--;
892 col++;
893 } else {
894 int m = mtd->writesize - col;
895
896 if (col >= mtd->writesize)
897 m += mtd->oobsize;
898
899 m = min(n, m) & ~3;
900 mxc_nand_memcpy32((uint32_t *)&buf[i], p, m);
901
902 col += m;
903 i += m;
904 n -= m;
905 }
906 }
907 /* Update saved column address */
908 host->col_addr = col;
909}
910
911/*
912 * Used by the upper layer to verify the data in NAND Flash
913 * with the data in the buf.
914 */
915static int mxc_nand_verify_buf(struct mtd_info *mtd,
916 const u_char *buf, int len)
917{
918 u_char tmp[256];
919 uint bsize;
920
921 while (len) {
922 bsize = min(len, 256);
923 mxc_nand_read_buf(mtd, tmp, bsize);
924
925 if (memcmp(buf, tmp, bsize))
926 return 1;
927
928 buf += bsize;
929 len -= bsize;
930 }
931
932 return 0;
933}
934
935/*
936 * This function is used by upper layer for select and
937 * deselect of the NAND chip
938 */
939static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
940{
941 struct nand_chip *nand_chip = mtd->priv;
942 struct mxc_nand_host *host = nand_chip->priv;
943
944 switch (chip) {
945 case -1:
946 /* TODO: Disable the NFC clock */
947 if (host->clk_act)
948 host->clk_act = 0;
949 break;
950 case 0:
951 /* TODO: Enable the NFC clock */
952 if (!host->clk_act)
953 host->clk_act = 1;
954 break;
955
956 default:
957 break;
958 }
959}
960
961/*
962 * Used by the upper layer to write command to NAND Flash for
963 * different operations to be carried out on NAND Flash
964 */
John Rigbyb081c2e2010-01-26 19:24:18 -0700965void mxc_nand_command(struct mtd_info *mtd, unsigned command,
Ilya Yanok36fab992009-08-11 02:32:54 +0400966 int column, int page_addr)
967{
968 struct nand_chip *nand_chip = mtd->priv;
969 struct mxc_nand_host *host = nand_chip->priv;
970
971 MTDDEBUG(MTD_DEBUG_LEVEL3,
972 "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
973 command, column, page_addr);
974
975 /* Reset command state information */
976 host->status_request = false;
977
978 /* Command pre-processing step */
979 switch (command) {
980
981 case NAND_CMD_STATUS:
982 host->col_addr = 0;
983 host->status_request = true;
984 break;
985
986 case NAND_CMD_READ0:
John Rigbyb081c2e2010-01-26 19:24:18 -0700987 host->page_addr = page_addr;
Ilya Yanok36fab992009-08-11 02:32:54 +0400988 host->col_addr = column;
989 host->spare_only = false;
990 break;
991
992 case NAND_CMD_READOOB:
993 host->col_addr = column;
994 host->spare_only = true;
995 if (host->pagesize_2k)
996 command = NAND_CMD_READ0; /* only READ0 is valid */
997 break;
998
999 case NAND_CMD_SEQIN:
1000 if (column >= mtd->writesize) {
1001 /*
1002 * before sending SEQIN command for partial write,
1003 * we need read one page out. FSL NFC does not support
Helmut Raiger780f30b2011-07-06 09:40:28 +02001004 * partial write. It always sends out 512+ecc+512+ecc
Ilya Yanok36fab992009-08-11 02:32:54 +04001005 * for large page nand flash. But for small page nand
1006 * flash, it does support SPARE ONLY operation.
1007 */
1008 if (host->pagesize_2k) {
1009 /* call ourself to read a page */
1010 mxc_nand_command(mtd, NAND_CMD_READ0, 0,
1011 page_addr);
1012 }
1013
1014 host->col_addr = column - mtd->writesize;
1015 host->spare_only = true;
1016
1017 /* Set program pointer to spare region */
1018 if (!host->pagesize_2k)
1019 send_cmd(host, NAND_CMD_READOOB);
1020 } else {
1021 host->spare_only = false;
1022 host->col_addr = column;
1023
1024 /* Set program pointer to page start */
1025 if (!host->pagesize_2k)
1026 send_cmd(host, NAND_CMD_READ0);
1027 }
1028 break;
1029
1030 case NAND_CMD_PAGEPROG:
1031 send_prog_page(host, 0, host->spare_only);
1032
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +02001033 if (host->pagesize_2k && is_mxc_nfc_1()) {
Helmut Raiger780f30b2011-07-06 09:40:28 +02001034 /* data in 4 areas */
Ilya Yanok36fab992009-08-11 02:32:54 +04001035 send_prog_page(host, 1, host->spare_only);
1036 send_prog_page(host, 2, host->spare_only);
1037 send_prog_page(host, 3, host->spare_only);
1038 }
1039
1040 break;
1041 }
1042
1043 /* Write out the command to the device. */
1044 send_cmd(host, command);
1045
1046 /* Write out column address, if necessary */
1047 if (column != -1) {
1048 /*
1049 * MXC NANDFC can only perform full page+spare or
Helmut Raiger780f30b2011-07-06 09:40:28 +02001050 * spare-only read/write. When the upper layers perform
1051 * a read/write buffer operation, we will use the saved
1052 * column address to index into the full page.
Ilya Yanok36fab992009-08-11 02:32:54 +04001053 */
1054 send_addr(host, 0);
1055 if (host->pagesize_2k)
1056 /* another col addr cycle for 2k page */
1057 send_addr(host, 0);
1058 }
1059
1060 /* Write out page address, if necessary */
1061 if (page_addr != -1) {
John Rigbyb081c2e2010-01-26 19:24:18 -07001062 u32 page_mask = nand_chip->pagemask;
1063 do {
1064 send_addr(host, page_addr & 0xFF);
1065 page_addr >>= 8;
1066 page_mask >>= 8;
1067 } while (page_mask);
Ilya Yanok36fab992009-08-11 02:32:54 +04001068 }
1069
1070 /* Command post-processing step */
1071 switch (command) {
1072
1073 case NAND_CMD_RESET:
1074 break;
1075
1076 case NAND_CMD_READOOB:
1077 case NAND_CMD_READ0:
1078 if (host->pagesize_2k) {
1079 /* send read confirm command */
1080 send_cmd(host, NAND_CMD_READSTART);
1081 /* read for each AREA */
1082 send_read_page(host, 0, host->spare_only);
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +02001083 if (is_mxc_nfc_1()) {
John Rigbyb081c2e2010-01-26 19:24:18 -07001084 send_read_page(host, 1, host->spare_only);
1085 send_read_page(host, 2, host->spare_only);
1086 send_read_page(host, 3, host->spare_only);
1087 }
Ilya Yanok36fab992009-08-11 02:32:54 +04001088 } else {
1089 send_read_page(host, 0, host->spare_only);
1090 }
1091 break;
1092
1093 case NAND_CMD_READID:
1094 host->col_addr = 0;
1095 send_read_id(host);
1096 break;
1097
1098 case NAND_CMD_PAGEPROG:
1099 break;
1100
1101 case NAND_CMD_STATUS:
1102 break;
1103
1104 case NAND_CMD_ERASE2:
1105 break;
1106 }
1107}
1108
Timo Ketolaa1028732012-04-18 22:55:31 +00001109#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
1110
1111static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
1112static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
1113
1114static struct nand_bbt_descr bbt_main_descr = {
1115 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1116 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1117 .offs = 0,
1118 .len = 4,
1119 .veroffs = 4,
1120 .maxblocks = 4,
1121 .pattern = bbt_pattern,
1122};
1123
1124static struct nand_bbt_descr bbt_mirror_descr = {
1125 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1126 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1127 .offs = 0,
1128 .len = 4,
1129 .veroffs = 4,
1130 .maxblocks = 4,
1131 .pattern = mirror_pattern,
1132};
1133
1134#endif
1135
Ilya Yanok36fab992009-08-11 02:32:54 +04001136int board_nand_init(struct nand_chip *this)
1137{
Ilya Yanok36fab992009-08-11 02:32:54 +04001138 struct mtd_info *mtd;
Tom Riniefa1f432012-09-18 09:24:22 -07001139#ifdef MXC_NFC_V2_1
Ilya Yanok36fab992009-08-11 02:32:54 +04001140 uint16_t tmp;
Tom Riniefa1f432012-09-18 09:24:22 -07001141#endif
Ilya Yanok36fab992009-08-11 02:32:54 +04001142
Timo Ketolaa1028732012-04-18 22:55:31 +00001143#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
1144 this->options |= NAND_USE_FLASH_BBT;
1145 this->bbt_td = &bbt_main_descr;
1146 this->bbt_md = &bbt_mirror_descr;
1147#endif
1148
Ilya Yanok36fab992009-08-11 02:32:54 +04001149 /* structures must be linked */
1150 mtd = &host->mtd;
1151 mtd->priv = this;
1152 host->nand = this;
1153
1154 /* 5 us command delay time */
1155 this->chip_delay = 5;
1156
1157 this->priv = host;
1158 this->dev_ready = mxc_nand_dev_ready;
1159 this->cmdfunc = mxc_nand_command;
1160 this->select_chip = mxc_nand_select_chip;
1161 this->read_byte = mxc_nand_read_byte;
1162 this->read_word = mxc_nand_read_word;
1163 this->write_buf = mxc_nand_write_buf;
1164 this->read_buf = mxc_nand_read_buf;
1165 this->verify_buf = mxc_nand_verify_buf;
1166
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001167 host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
Ilya Yanok36fab992009-08-11 02:32:54 +04001168 host->clk_act = 1;
1169
1170#ifdef CONFIG_MXC_NAND_HWECC
1171 this->ecc.calculate = mxc_nand_calculate_ecc;
1172 this->ecc.hwctl = mxc_nand_enable_hwecc;
1173 this->ecc.correct = mxc_nand_correct_data;
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +02001174 if (is_mxc_nfc_21()) {
John Rigbyb081c2e2010-01-26 19:24:18 -07001175 this->ecc.mode = NAND_ECC_HW_SYNDROME;
1176 this->ecc.read_page = mxc_nand_read_page_syndrome;
1177 this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome;
1178 this->ecc.read_oob = mxc_nand_read_oob_syndrome;
1179 this->ecc.write_page = mxc_nand_write_page_syndrome;
1180 this->ecc.write_page_raw = mxc_nand_write_page_raw_syndrome;
1181 this->ecc.write_oob = mxc_nand_write_oob_syndrome;
1182 this->ecc.bytes = 9;
1183 this->ecc.prepad = 7;
1184 } else {
1185 this->ecc.mode = NAND_ECC_HW;
1186 }
1187
1188 host->pagesize_2k = 0;
1189
Ilya Yanok36fab992009-08-11 02:32:54 +04001190 this->ecc.size = 512;
Benoît Thébaudeau0e499b02012-08-13 22:50:07 +02001191 _mxc_nand_enable_hwecc(mtd, 1);
Ilya Yanok36fab992009-08-11 02:32:54 +04001192#else
1193 this->ecc.layout = &nand_soft_eccoob;
1194 this->ecc.mode = NAND_ECC_SOFT;
Benoît Thébaudeau0e499b02012-08-13 22:50:07 +02001195 _mxc_nand_enable_hwecc(mtd, 0);
Ilya Yanok36fab992009-08-11 02:32:54 +04001196#endif
Ilya Yanok36fab992009-08-11 02:32:54 +04001197 /* Reset NAND */
1198 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1199
Benoît Thébaudeau13927f02012-08-13 22:50:30 +02001200 /* NAND bus width determines access functions used by upper layer */
1201 if (is_16bit_nand())
1202 this->options |= NAND_BUSWIDTH_16;
1203
1204#ifdef CONFIG_SYS_NAND_LARGEPAGE
1205 host->pagesize_2k = 1;
1206 this->ecc.layout = &nand_hw_eccoob2k;
1207#else
1208 host->pagesize_2k = 0;
1209 this->ecc.layout = &nand_hw_eccoob;
1210#endif
1211
Benoît Thébaudeau9c60e752012-08-13 22:50:53 +02001212#ifdef MXC_NFC_V2_1
Benoît Thébaudeau13927f02012-08-13 22:50:30 +02001213 tmp = readw(&host->regs->config1);
1214 tmp |= NFC_ONE_CYCLE;
1215 tmp |= NFC_4_8N_ECC;
1216 writew(tmp, &host->regs->config1);
1217 if (host->pagesize_2k)
1218 writew(64/2, &host->regs->spare_area_size);
1219 else
1220 writew(16/2, &host->regs->spare_area_size);
1221#endif
1222
Ilya Yanok36fab992009-08-11 02:32:54 +04001223 /*
1224 * preset operation
1225 * Unlock the internal RAM Buffer
1226 */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001227 writew(0x2, &host->regs->config);
Ilya Yanok36fab992009-08-11 02:32:54 +04001228
1229 /* Blocks to be unlocked */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001230 writew(0x0, &host->regs->unlockstart_blkaddr);
Helmut Raigerb4b1e762011-07-06 19:04:41 +02001231 /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the
1232 * unlockend_blkaddr, but the magic 0x4000 does not always work
1233 * when writing more than some 32 megabytes (on 2k page nands)
1234 * However 0xFFFF doesn't seem to have this kind
1235 * of limitation (tried it back and forth several times).
1236 * The linux kernel driver sets this to 0xFFFF for the v2 controller
1237 * only, but probably this was not tested there for v1.
1238 * The very same limitation seems to apply to this kernel driver.
1239 * This might be NAND chip specific and the i.MX31 datasheet is
1240 * extremely vague about the semantics of this register.
1241 */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001242 writew(0xFFFF, &host->regs->unlockend_blkaddr);
Ilya Yanok36fab992009-08-11 02:32:54 +04001243
1244 /* Unlock Block Command for given address range */
Benoît Thébaudeau80c8ab72012-08-13 22:48:12 +02001245 writew(0x4, &host->regs->wrprot);
Ilya Yanok36fab992009-08-11 02:32:54 +04001246
Benoît Thébaudeau365b2c02012-08-13 22:48:26 +02001247 return 0;
Ilya Yanok36fab992009-08-11 02:32:54 +04001248}