blob: 04836c00626bdd5f70bc6011b5885ab846d5880c [file] [log] [blame]
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001/*
Scott Wood454a4262009-09-02 16:45:31 -05002 * Copyright 2004-2007 Freescale Semiconductor, Inc.
Ilya Yanokf9e2bee2009-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 Babic63103012011-01-14 03:35:21 +000025#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35)
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040026#include <asm/arch/imx-regs.h>
27#endif
Benoît Thébaudeau3f775192012-08-13 22:48:12 +020028#include <fsl_nfc.h>
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040029
30#define DRIVER_NAME "mxc_nand"
31
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040032struct mxc_nand_host {
Benoît Thébaudeau3f775192012-08-13 22:48:12 +020033 struct mtd_info mtd;
34 struct nand_chip *nand;
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040035
Benoît Thébaudeau3f775192012-08-13 22:48:12 +020036 struct fsl_nfc_regs __iomem *regs;
37 int spare_only;
38 int status_request;
39 int pagesize_2k;
40 int clk_act;
41 uint16_t col_addr;
42 unsigned int page_addr;
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040043};
44
45static struct mxc_nand_host mxc_host;
46static struct mxc_nand_host *host = &mxc_host;
47
48/* Define delays in microsec for NAND device operations */
49#define TROP_US_DELAY 2000
50/* Macros to get byte and bit positions of ECC */
51#define COLPOS(x) ((x) >> 3)
52#define BITPOS(x) ((x) & 0xf)
53
54/* Define single bit Error positions in Main & Spare area */
55#define MAIN_SINGLEBIT_ERROR 0x4
56#define SPARE_SINGLEBIT_ERROR 0x1
57
58/* OOB placement block for use with hardware ecc generation */
John Rigby3c285c72010-01-26 19:24:18 -070059#if defined(MXC_NFC_V1)
60#ifndef CONFIG_SYS_NAND_LARGEPAGE
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040061static struct nand_ecclayout nand_hw_eccoob = {
62 .eccbytes = 5,
63 .eccpos = {6, 7, 8, 9, 10},
John Rigby3c285c72010-01-26 19:24:18 -070064 .oobfree = { {0, 5}, {11, 5}, }
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040065};
66#else
John Rigby3c285c72010-01-26 19:24:18 -070067static struct nand_ecclayout nand_hw_eccoob2k = {
68 .eccbytes = 20,
69 .eccpos = {
70 6, 7, 8, 9, 10,
71 22, 23, 24, 25, 26,
72 38, 39, 40, 41, 42,
73 54, 55, 56, 57, 58,
74 },
75 .oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} },
Ilya Yanokf9e2bee2009-08-11 02:32:54 +040076};
77#endif
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +020078#elif defined(MXC_NFC_V2_1)
John Rigby3c285c72010-01-26 19:24:18 -070079#ifndef CONFIG_SYS_NAND_LARGEPAGE
80static struct nand_ecclayout nand_hw_eccoob = {
81 .eccbytes = 9,
82 .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
83 .oobfree = { {2, 5} }
84};
85#else
86static struct nand_ecclayout nand_hw_eccoob2k = {
87 .eccbytes = 36,
88 .eccpos = {
89 7, 8, 9, 10, 11, 12, 13, 14, 15,
90 23, 24, 25, 26, 27, 28, 29, 30, 31,
91 39, 40, 41, 42, 43, 44, 45, 46, 47,
92 55, 56, 57, 58, 59, 60, 61, 62, 63,
93 },
94 .oobfree = { {2, 5}, {16, 7}, {32, 7}, {48, 7} },
Magnus Liljaab5b3b62010-01-17 17:46:10 +010095};
John Rigby3c285c72010-01-26 19:24:18 -070096#endif
97#endif
Magnus Liljaab5b3b62010-01-17 17:46:10 +010098
Magnus Lilja6e0dbd82009-11-11 20:18:43 +010099#ifdef CONFIG_MX27
100static int is_16bit_nand(void)
101{
102 struct system_control_regs *sc_regs =
103 (struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
104
105 if (readl(&sc_regs->fmcr) & NF_16BIT_SEL)
106 return 1;
107 else
108 return 0;
109}
110#elif defined(CONFIG_MX31)
111static int is_16bit_nand(void)
112{
113 struct clock_control_regs *sc_regs =
114 (struct clock_control_regs *)CCM_BASE;
115
116 if (readl(&sc_regs->rcsr) & CCM_RCSR_NF16B)
117 return 1;
118 else
119 return 0;
120}
Stefano Babic63103012011-01-14 03:35:21 +0000121#elif defined(CONFIG_MX25) || defined(CONFIG_MX35)
John Rigby3c285c72010-01-26 19:24:18 -0700122static int is_16bit_nand(void)
123{
Benoît Thébaudeau32ae5b42012-08-13 22:48:26 +0200124 struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
John Rigby3c285c72010-01-26 19:24:18 -0700125
126 if (readl(&ccm->rcsr) & CCM_RCSR_NF_16BIT_SEL)
127 return 1;
128 else
129 return 0;
130}
Magnus Lilja6e0dbd82009-11-11 20:18:43 +0100131#else
132#warning "8/16 bit NAND autodetection not supported"
133static int is_16bit_nand(void)
134{
135 return 0;
136}
137#endif
138
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400139static uint32_t *mxc_nand_memcpy32(uint32_t *dest, uint32_t *source, size_t size)
140{
141 uint32_t *d = dest;
142
143 size >>= 2;
144 while (size--)
145 __raw_writel(__raw_readl(source++), d++);
146 return dest;
147}
148
149/*
150 * This function polls the NANDFC to wait for the basic operation to
151 * complete by checking the INT bit of config2 register.
152 */
153static void wait_op_done(struct mxc_nand_host *host, int max_retries,
154 uint16_t param)
155{
156 uint32_t tmp;
157
158 while (max_retries-- > 0) {
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200159 if (readw(&host->regs->config2) & NFC_INT) {
160 tmp = readw(&host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400161 tmp &= ~NFC_INT;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200162 writew(tmp, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400163 break;
164 }
165 udelay(1);
166 }
167 if (max_retries < 0) {
168 MTDDEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
169 __func__, param);
170 }
171}
172
173/*
174 * This function issues the specified command to the NAND device and
175 * waits for completion.
176 */
177static void send_cmd(struct mxc_nand_host *host, uint16_t cmd)
178{
179 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd);
180
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200181 writew(cmd, &host->regs->flash_cmd);
182 writew(NFC_CMD, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400183
184 /* Wait for operation to complete */
185 wait_op_done(host, TROP_US_DELAY, cmd);
186}
187
188/*
189 * This function sends an address (or partial address) to the
190 * NAND device. The address is used to select the source/destination for
191 * a NAND command.
192 */
193static void send_addr(struct mxc_nand_host *host, uint16_t addr)
194{
195 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr);
196
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200197 writew(addr, &host->regs->flash_addr);
198 writew(NFC_ADDR, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400199
200 /* Wait for operation to complete */
201 wait_op_done(host, TROP_US_DELAY, addr);
202}
203
204/*
Helmut Raigerc8f4a4c2011-07-06 09:40:28 +0200205 * This function requests the NANDFC to initiate the transfer
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400206 * of data currently in the NANDFC RAM buffer to the NAND device.
207 */
208static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
209 int spare_only)
210{
John Rigby3c285c72010-01-26 19:24:18 -0700211 if (spare_only)
212 MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only);
213
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +0200214 if (is_mxc_nfc_21()) {
John Rigby3c285c72010-01-26 19:24:18 -0700215 int i;
216 /*
217 * The controller copies the 64 bytes of spare data from
218 * the first 16 bytes of each of the 4 64 byte spare buffers.
219 * Copy the contiguous data starting in spare_area[0] to
220 * the four spare area buffers.
221 */
222 for (i = 1; i < 4; i++) {
223 void __iomem *src = &host->regs->spare_area[0][i * 16];
224 void __iomem *dst = &host->regs->spare_area[i][0];
225
226 mxc_nand_memcpy32(dst, src, 16);
227 }
228 }
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400229
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200230 writew(buf_id, &host->regs->buf_addr);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400231
232 /* Configure spare or page+spare access */
233 if (!host->pagesize_2k) {
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200234 uint16_t config1 = readw(&host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400235 if (spare_only)
236 config1 |= NFC_SP_EN;
237 else
Benoît Thébaudeau32ae5b42012-08-13 22:48:26 +0200238 config1 &= ~NFC_SP_EN;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200239 writew(config1, &host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400240 }
241
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200242 writew(NFC_INPUT, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400243
244 /* Wait for operation to complete */
245 wait_op_done(host, TROP_US_DELAY, spare_only);
246}
247
248/*
Helmut Raigerc8f4a4c2011-07-06 09:40:28 +0200249 * Requests NANDFC to initiate the transfer of data from the
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400250 * NAND device into in the NANDFC ram buffer.
251 */
252static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
253 int spare_only)
254{
255 MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
256
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200257 writew(buf_id, &host->regs->buf_addr);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400258
259 /* Configure spare or page+spare access */
260 if (!host->pagesize_2k) {
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200261 uint32_t config1 = readw(&host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400262 if (spare_only)
263 config1 |= NFC_SP_EN;
264 else
265 config1 &= ~NFC_SP_EN;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200266 writew(config1, &host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400267 }
268
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200269 writew(NFC_OUTPUT, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400270
271 /* Wait for operation to complete */
272 wait_op_done(host, TROP_US_DELAY, spare_only);
John Rigby3c285c72010-01-26 19:24:18 -0700273
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +0200274 if (is_mxc_nfc_21()) {
John Rigby3c285c72010-01-26 19:24:18 -0700275 int i;
276
277 /*
278 * The controller copies the 64 bytes of spare data to
279 * the first 16 bytes of each of the 4 spare buffers.
280 * Make the data contiguous starting in spare_area[0].
281 */
282 for (i = 1; i < 4; i++) {
283 void __iomem *src = &host->regs->spare_area[i][0];
284 void __iomem *dst = &host->regs->spare_area[0][i * 16];
285
286 mxc_nand_memcpy32(dst, src, 16);
287 }
288 }
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400289}
290
291/* Request the NANDFC to perform a read of the NAND device ID. */
292static void send_read_id(struct mxc_nand_host *host)
293{
294 uint16_t tmp;
295
296 /* NANDFC buffer 0 is used for device ID output */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200297 writew(0x0, &host->regs->buf_addr);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400298
299 /* Read ID into main buffer */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200300 tmp = readw(&host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400301 tmp &= ~NFC_SP_EN;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200302 writew(tmp, &host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400303
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200304 writew(NFC_ID, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400305
306 /* Wait for operation to complete */
307 wait_op_done(host, TROP_US_DELAY, 0);
308}
309
310/*
311 * This function requests the NANDFC to perform a read of the
312 * NAND device status and returns the current status.
313 */
314static uint16_t get_dev_status(struct mxc_nand_host *host)
315{
John Rigby3c285c72010-01-26 19:24:18 -0700316 void __iomem *main_buf = host->regs->main_area[1];
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400317 uint32_t store;
318 uint16_t ret, tmp;
319 /* Issue status request to NAND device */
320
321 /* store the main area1 first word, later do recovery */
322 store = readl(main_buf);
323 /* NANDFC buffer 1 is used for device status */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200324 writew(1, &host->regs->buf_addr);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400325
326 /* Read status into main buffer */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200327 tmp = readw(&host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400328 tmp &= ~NFC_SP_EN;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200329 writew(tmp, &host->regs->config1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400330
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200331 writew(NFC_STATUS, &host->regs->config2);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400332
333 /* Wait for operation to complete */
334 wait_op_done(host, TROP_US_DELAY, 0);
335
336 /*
337 * Status is placed in first word of main buffer
338 * get status, then recovery area 1 data
339 */
340 ret = readw(main_buf);
341 writel(store, main_buf);
342
343 return ret;
344}
345
346/* This function is used by upper layer to checks if device is ready */
347static int mxc_nand_dev_ready(struct mtd_info *mtd)
348{
349 /*
350 * NFC handles R/B internally. Therefore, this function
351 * always returns status as ready.
352 */
353 return 1;
354}
355
John Rigby3c285c72010-01-26 19:24:18 -0700356static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on)
357{
358 struct nand_chip *nand_chip = mtd->priv;
359 struct mxc_nand_host *host = nand_chip->priv;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200360 uint16_t tmp = readw(&host->regs->config1);
John Rigby3c285c72010-01-26 19:24:18 -0700361
362 if (on)
363 tmp |= NFC_ECC_EN;
364 else
365 tmp &= ~NFC_ECC_EN;
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200366 writew(tmp, &host->regs->config1);
John Rigby3c285c72010-01-26 19:24:18 -0700367}
368
Benoît Thébaudeau9166d5f2012-08-13 22:50:07 +0200369#ifdef CONFIG_MXC_NAND_HWECC
370static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
371{
372 /*
373 * If HW ECC is enabled, we turn it on during init. There is
374 * no need to enable again here.
375 */
376}
377
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +0200378#ifdef MXC_NFC_V2_1
John Rigby3c285c72010-01-26 19:24:18 -0700379static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
380 struct nand_chip *chip,
381 int page, int sndcmd)
382{
383 struct mxc_nand_host *host = chip->priv;
384 uint8_t *buf = chip->oob_poi;
385 int length = mtd->oobsize;
386 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
387 uint8_t *bufpoi = buf;
388 int i, toread;
389
390 MTDDEBUG(MTD_DEBUG_LEVEL0,
391 "%s: Reading OOB area of page %u to oob %p\n",
392 __FUNCTION__, host->page_addr, buf);
393
394 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, page);
395 for (i = 0; i < chip->ecc.steps; i++) {
396 toread = min_t(int, length, chip->ecc.prepad);
397 if (toread) {
398 chip->read_buf(mtd, bufpoi, toread);
399 bufpoi += toread;
400 length -= toread;
401 }
402 bufpoi += chip->ecc.bytes;
403 host->col_addr += chip->ecc.bytes;
404 length -= chip->ecc.bytes;
405
406 toread = min_t(int, length, chip->ecc.postpad);
407 if (toread) {
408 chip->read_buf(mtd, bufpoi, toread);
409 bufpoi += toread;
410 length -= toread;
411 }
412 }
413 if (length > 0)
414 chip->read_buf(mtd, bufpoi, length);
415
416 _mxc_nand_enable_hwecc(mtd, 0);
417 chip->cmdfunc(mtd, NAND_CMD_READOOB,
418 mtd->writesize + chip->ecc.prepad, page);
419 bufpoi = buf + chip->ecc.prepad;
420 length = mtd->oobsize - chip->ecc.prepad;
421 for (i = 0; i < chip->ecc.steps; i++) {
422 toread = min_t(int, length, chip->ecc.bytes);
423 chip->read_buf(mtd, bufpoi, toread);
424 bufpoi += eccpitch;
425 length -= eccpitch;
426 host->col_addr += chip->ecc.postpad + chip->ecc.prepad;
427 }
428 _mxc_nand_enable_hwecc(mtd, 1);
429 return 1;
430}
431
432static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd,
433 struct nand_chip *chip,
434 uint8_t *buf,
435 int page)
436{
437 struct mxc_nand_host *host = chip->priv;
438 int eccsize = chip->ecc.size;
439 int eccbytes = chip->ecc.bytes;
440 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
441 uint8_t *oob = chip->oob_poi;
442 int steps, size;
443 int n;
444
445 _mxc_nand_enable_hwecc(mtd, 0);
446 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, host->page_addr);
447
448 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
449 host->col_addr = n * eccsize;
450 chip->read_buf(mtd, buf, eccsize);
451 buf += eccsize;
452
453 host->col_addr = mtd->writesize + n * eccpitch;
454 if (chip->ecc.prepad) {
455 chip->read_buf(mtd, oob, chip->ecc.prepad);
456 oob += chip->ecc.prepad;
457 }
458
459 chip->read_buf(mtd, oob, eccbytes);
460 oob += eccbytes;
461
462 if (chip->ecc.postpad) {
463 chip->read_buf(mtd, oob, chip->ecc.postpad);
464 oob += chip->ecc.postpad;
465 }
466 }
467
468 size = mtd->oobsize - (oob - chip->oob_poi);
469 if (size)
470 chip->read_buf(mtd, oob, size);
Benoît Thébaudeauc1578272012-08-13 22:50:19 +0200471 _mxc_nand_enable_hwecc(mtd, 1);
John Rigby3c285c72010-01-26 19:24:18 -0700472
473 return 0;
474}
475
476static int mxc_nand_read_page_syndrome(struct mtd_info *mtd,
477 struct nand_chip *chip,
478 uint8_t *buf,
479 int page)
480{
481 struct mxc_nand_host *host = chip->priv;
482 int n, eccsize = chip->ecc.size;
483 int eccbytes = chip->ecc.bytes;
484 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
485 int eccsteps = chip->ecc.steps;
486 uint8_t *p = buf;
487 uint8_t *oob = chip->oob_poi;
488
489 MTDDEBUG(MTD_DEBUG_LEVEL1, "Reading page %u to buf %p oob %p\n",
490 host->page_addr, buf, oob);
491
Helmut Raigerc8f4a4c2011-07-06 09:40:28 +0200492 /* first read the data area and the available portion of OOB */
John Rigby3c285c72010-01-26 19:24:18 -0700493 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
494 int stat;
495
496 host->col_addr = n * eccsize;
497
498 chip->read_buf(mtd, p, eccsize);
499
500 host->col_addr = mtd->writesize + n * eccpitch;
501
502 if (chip->ecc.prepad) {
503 chip->read_buf(mtd, oob, chip->ecc.prepad);
504 oob += chip->ecc.prepad;
505 }
506
507 stat = chip->ecc.correct(mtd, p, oob, NULL);
508
509 if (stat < 0)
510 mtd->ecc_stats.failed++;
511 else
512 mtd->ecc_stats.corrected += stat;
513 oob += eccbytes;
514
515 if (chip->ecc.postpad) {
516 chip->read_buf(mtd, oob, chip->ecc.postpad);
517 oob += chip->ecc.postpad;
518 }
519 }
520
521 /* Calculate remaining oob bytes */
522 n = mtd->oobsize - (oob - chip->oob_poi);
523 if (n)
524 chip->read_buf(mtd, oob, n);
525
526 /* Then switch ECC off and read the OOB area to get the ECC code */
527 _mxc_nand_enable_hwecc(mtd, 0);
528 chip->cmdfunc(mtd, NAND_CMD_READOOB, mtd->writesize, host->page_addr);
529 eccsteps = chip->ecc.steps;
530 oob = chip->oob_poi + chip->ecc.prepad;
531 for (n = 0; eccsteps; n++, eccsteps--, p += eccsize) {
532 host->col_addr = mtd->writesize +
533 n * eccpitch +
534 chip->ecc.prepad;
535 chip->read_buf(mtd, oob, eccbytes);
536 oob += eccbytes + chip->ecc.postpad;
537 }
538 _mxc_nand_enable_hwecc(mtd, 1);
539 return 0;
540}
541
542static int mxc_nand_write_oob_syndrome(struct mtd_info *mtd,
543 struct nand_chip *chip, int page)
544{
545 struct mxc_nand_host *host = chip->priv;
546 int eccpitch = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
547 int length = mtd->oobsize;
548 int i, len, status, steps = chip->ecc.steps;
549 const uint8_t *bufpoi = chip->oob_poi;
550
551 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
552 for (i = 0; i < steps; i++) {
553 len = min_t(int, length, eccpitch);
554
555 chip->write_buf(mtd, bufpoi, len);
556 bufpoi += len;
557 length -= len;
558 host->col_addr += chip->ecc.prepad + chip->ecc.postpad;
559 }
560 if (length > 0)
561 chip->write_buf(mtd, bufpoi, length);
562
563 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
564 status = chip->waitfunc(mtd, chip);
565 return status & NAND_STATUS_FAIL ? -EIO : 0;
566}
567
568static void mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
569 struct nand_chip *chip,
570 const uint8_t *buf)
571{
572 struct mxc_nand_host *host = chip->priv;
573 int eccsize = chip->ecc.size;
574 int eccbytes = chip->ecc.bytes;
575 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
576 uint8_t *oob = chip->oob_poi;
577 int steps, size;
578 int n;
579
580 for (n = 0, steps = chip->ecc.steps; steps > 0; n++, steps--) {
581 host->col_addr = n * eccsize;
582 chip->write_buf(mtd, buf, eccsize);
583 buf += eccsize;
584
585 host->col_addr = mtd->writesize + n * eccpitch;
586
587 if (chip->ecc.prepad) {
588 chip->write_buf(mtd, oob, chip->ecc.prepad);
589 oob += chip->ecc.prepad;
590 }
591
592 host->col_addr += eccbytes;
593 oob += eccbytes;
594
595 if (chip->ecc.postpad) {
596 chip->write_buf(mtd, oob, chip->ecc.postpad);
597 oob += chip->ecc.postpad;
598 }
599 }
600
601 size = mtd->oobsize - (oob - chip->oob_poi);
602 if (size)
603 chip->write_buf(mtd, oob, size);
604}
605
606static void mxc_nand_write_page_syndrome(struct mtd_info *mtd,
607 struct nand_chip *chip,
608 const uint8_t *buf)
609{
610 struct mxc_nand_host *host = chip->priv;
611 int i, n, eccsize = chip->ecc.size;
612 int eccbytes = chip->ecc.bytes;
613 int eccpitch = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
614 int eccsteps = chip->ecc.steps;
615 const uint8_t *p = buf;
616 uint8_t *oob = chip->oob_poi;
617
618 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
619
620 for (i = n = 0;
621 eccsteps;
622 n++, eccsteps--, i += eccbytes, p += eccsize) {
623 host->col_addr = n * eccsize;
624
625 chip->write_buf(mtd, p, eccsize);
626
627 host->col_addr = mtd->writesize + n * eccpitch;
628
629 if (chip->ecc.prepad) {
630 chip->write_buf(mtd, oob, chip->ecc.prepad);
631 oob += chip->ecc.prepad;
632 }
633
634 chip->write_buf(mtd, oob, eccbytes);
635 oob += eccbytes;
636
637 if (chip->ecc.postpad) {
638 chip->write_buf(mtd, oob, chip->ecc.postpad);
639 oob += chip->ecc.postpad;
640 }
641 }
642
643 /* Calculate remaining oob bytes */
644 i = mtd->oobsize - (oob - chip->oob_poi);
645 if (i)
646 chip->write_buf(mtd, oob, i);
647}
648
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400649static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
650 u_char *read_ecc, u_char *calc_ecc)
651{
652 struct nand_chip *nand_chip = mtd->priv;
653 struct mxc_nand_host *host = nand_chip->priv;
Benoît Thébaudeaud29aeba2012-08-13 22:49:42 +0200654 uint32_t ecc_status = readl(&host->regs->ecc_status_result);
John Rigby3c285c72010-01-26 19:24:18 -0700655 int subpages = mtd->writesize / nand_chip->subpagesize;
656 int pg2blk_shift = nand_chip->phys_erase_shift -
657 nand_chip->page_shift;
658
659 do {
660 if ((ecc_status & 0xf) > 4) {
661 static int last_bad = -1;
662
663 if (last_bad != host->page_addr >> pg2blk_shift) {
664 last_bad = host->page_addr >> pg2blk_shift;
665 printk(KERN_DEBUG
666 "MXC_NAND: HWECC uncorrectable ECC error"
667 " in block %u page %u subpage %d\n",
668 last_bad, host->page_addr,
669 mtd->writesize / nand_chip->subpagesize
670 - subpages);
671 }
672 return -1;
673 }
674 ecc_status >>= 4;
675 subpages--;
676 } while (subpages > 0);
677
678 return 0;
679}
680#else
681#define mxc_nand_read_page_syndrome NULL
682#define mxc_nand_read_page_raw_syndrome NULL
683#define mxc_nand_read_oob_syndrome NULL
684#define mxc_nand_write_page_syndrome NULL
685#define mxc_nand_write_page_raw_syndrome NULL
686#define mxc_nand_write_oob_syndrome NULL
John Rigby3c285c72010-01-26 19:24:18 -0700687
688static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
689 u_char *read_ecc, u_char *calc_ecc)
690{
691 struct nand_chip *nand_chip = mtd->priv;
692 struct mxc_nand_host *host = nand_chip->priv;
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400693
694 /*
695 * 1-Bit errors are automatically corrected in HW. No need for
696 * additional correction. 2-Bit errors cannot be corrected by
697 * HW ECC, so we need to return failure
698 */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +0200699 uint16_t ecc_status = readw(&host->regs->ecc_status_result);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400700
701 if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
702 MTDDEBUG(MTD_DEBUG_LEVEL0,
703 "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
704 return -1;
705 }
706
707 return 0;
708}
John Rigby3c285c72010-01-26 19:24:18 -0700709#endif
710
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400711static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
712 u_char *ecc_code)
713{
714 return 0;
715}
716#endif
717
718static u_char mxc_nand_read_byte(struct mtd_info *mtd)
719{
720 struct nand_chip *nand_chip = mtd->priv;
721 struct mxc_nand_host *host = nand_chip->priv;
722 uint8_t ret = 0;
723 uint16_t col;
724 uint16_t __iomem *main_buf =
John Rigby3c285c72010-01-26 19:24:18 -0700725 (uint16_t __iomem *)host->regs->main_area[0];
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400726 uint16_t __iomem *spare_buf =
John Rigby3c285c72010-01-26 19:24:18 -0700727 (uint16_t __iomem *)host->regs->spare_area[0];
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400728 union {
729 uint16_t word;
730 uint8_t bytes[2];
731 } nfc_word;
732
733 /* Check for status request */
734 if (host->status_request)
735 return get_dev_status(host) & 0xFF;
736
737 /* Get column for 16-bit access */
738 col = host->col_addr >> 1;
739
740 /* If we are accessing the spare region */
741 if (host->spare_only)
742 nfc_word.word = readw(&spare_buf[col]);
743 else
744 nfc_word.word = readw(&main_buf[col]);
745
746 /* Pick upper/lower byte of word from RAM buffer */
747 ret = nfc_word.bytes[host->col_addr & 0x1];
748
749 /* Update saved column address */
750 if (nand_chip->options & NAND_BUSWIDTH_16)
751 host->col_addr += 2;
752 else
753 host->col_addr++;
754
755 return ret;
756}
757
758static uint16_t mxc_nand_read_word(struct mtd_info *mtd)
759{
760 struct nand_chip *nand_chip = mtd->priv;
761 struct mxc_nand_host *host = nand_chip->priv;
762 uint16_t col, ret;
763 uint16_t __iomem *p;
764
765 MTDDEBUG(MTD_DEBUG_LEVEL3,
766 "mxc_nand_read_word(col = %d)\n", host->col_addr);
767
768 col = host->col_addr;
769 /* Adjust saved column address */
770 if (col < mtd->writesize && host->spare_only)
771 col += mtd->writesize;
772
773 if (col < mtd->writesize) {
John Rigby3c285c72010-01-26 19:24:18 -0700774 p = (uint16_t __iomem *)(host->regs->main_area[0] +
775 (col >> 1));
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400776 } else {
John Rigby3c285c72010-01-26 19:24:18 -0700777 p = (uint16_t __iomem *)(host->regs->spare_area[0] +
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400778 ((col - mtd->writesize) >> 1));
779 }
780
781 if (col & 1) {
782 union {
783 uint16_t word;
784 uint8_t bytes[2];
785 } nfc_word[3];
786
787 nfc_word[0].word = readw(p);
788 nfc_word[1].word = readw(p + 1);
789
790 nfc_word[2].bytes[0] = nfc_word[0].bytes[1];
791 nfc_word[2].bytes[1] = nfc_word[1].bytes[0];
792
793 ret = nfc_word[2].word;
794 } else {
795 ret = readw(p);
796 }
797
798 /* Update saved column address */
799 host->col_addr = col + 2;
800
801 return ret;
802}
803
804/*
805 * Write data of length len to buffer buf. The data to be
806 * written on NAND Flash is first copied to RAMbuffer. After the Data Input
807 * Operation by the NFC, the data is written to NAND Flash
808 */
809static void mxc_nand_write_buf(struct mtd_info *mtd,
810 const u_char *buf, int len)
811{
812 struct nand_chip *nand_chip = mtd->priv;
813 struct mxc_nand_host *host = nand_chip->priv;
814 int n, col, i = 0;
815
816 MTDDEBUG(MTD_DEBUG_LEVEL3,
817 "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr,
818 len);
819
820 col = host->col_addr;
821
822 /* Adjust saved column address */
823 if (col < mtd->writesize && host->spare_only)
824 col += mtd->writesize;
825
826 n = mtd->writesize + mtd->oobsize - col;
827 n = min(len, n);
828
829 MTDDEBUG(MTD_DEBUG_LEVEL3,
830 "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n);
831
832 while (n > 0) {
833 void __iomem *p;
834
835 if (col < mtd->writesize) {
John Rigby3c285c72010-01-26 19:24:18 -0700836 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400837 } else {
John Rigby3c285c72010-01-26 19:24:18 -0700838 p = host->regs->spare_area[0] -
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400839 mtd->writesize + (col & ~3);
840 }
841
842 MTDDEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__,
843 __LINE__, p);
844
845 if (((col | (unsigned long)&buf[i]) & 3) || n < 4) {
846 union {
847 uint32_t word;
848 uint8_t bytes[4];
849 } nfc_word;
850
851 nfc_word.word = readl(p);
852 nfc_word.bytes[col & 3] = buf[i++];
853 n--;
854 col++;
855
856 writel(nfc_word.word, p);
857 } else {
858 int m = mtd->writesize - col;
859
860 if (col >= mtd->writesize)
861 m += mtd->oobsize;
862
863 m = min(n, m) & ~3;
864
865 MTDDEBUG(MTD_DEBUG_LEVEL3,
866 "%s:%d: n = %d, m = %d, i = %d, col = %d\n",
867 __func__, __LINE__, n, m, i, col);
868
869 mxc_nand_memcpy32(p, (uint32_t *)&buf[i], m);
870 col += m;
871 i += m;
872 n -= m;
873 }
874 }
875 /* Update saved column address */
876 host->col_addr = col;
877}
878
879/*
880 * Read the data buffer from the NAND Flash. To read the data from NAND
881 * Flash first the data output cycle is initiated by the NFC, which copies
882 * the data to RAMbuffer. This data of length len is then copied to buffer buf.
883 */
884static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
885{
886 struct nand_chip *nand_chip = mtd->priv;
887 struct mxc_nand_host *host = nand_chip->priv;
888 int n, col, i = 0;
889
890 MTDDEBUG(MTD_DEBUG_LEVEL3,
891 "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len);
892
893 col = host->col_addr;
894
895 /* Adjust saved column address */
896 if (col < mtd->writesize && host->spare_only)
897 col += mtd->writesize;
898
899 n = mtd->writesize + mtd->oobsize - col;
900 n = min(len, n);
901
902 while (n > 0) {
903 void __iomem *p;
904
905 if (col < mtd->writesize) {
John Rigby3c285c72010-01-26 19:24:18 -0700906 p = host->regs->main_area[0] + (col & ~3);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400907 } else {
John Rigby3c285c72010-01-26 19:24:18 -0700908 p = host->regs->spare_area[0] -
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400909 mtd->writesize + (col & ~3);
910 }
911
912 if (((col | (int)&buf[i]) & 3) || n < 4) {
913 union {
914 uint32_t word;
915 uint8_t bytes[4];
916 } nfc_word;
917
918 nfc_word.word = readl(p);
919 buf[i++] = nfc_word.bytes[col & 3];
920 n--;
921 col++;
922 } else {
923 int m = mtd->writesize - col;
924
925 if (col >= mtd->writesize)
926 m += mtd->oobsize;
927
928 m = min(n, m) & ~3;
929 mxc_nand_memcpy32((uint32_t *)&buf[i], p, m);
930
931 col += m;
932 i += m;
933 n -= m;
934 }
935 }
936 /* Update saved column address */
937 host->col_addr = col;
938}
939
940/*
941 * Used by the upper layer to verify the data in NAND Flash
942 * with the data in the buf.
943 */
944static int mxc_nand_verify_buf(struct mtd_info *mtd,
945 const u_char *buf, int len)
946{
947 u_char tmp[256];
948 uint bsize;
949
950 while (len) {
951 bsize = min(len, 256);
952 mxc_nand_read_buf(mtd, tmp, bsize);
953
954 if (memcmp(buf, tmp, bsize))
955 return 1;
956
957 buf += bsize;
958 len -= bsize;
959 }
960
961 return 0;
962}
963
964/*
965 * This function is used by upper layer for select and
966 * deselect of the NAND chip
967 */
968static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
969{
970 struct nand_chip *nand_chip = mtd->priv;
971 struct mxc_nand_host *host = nand_chip->priv;
972
973 switch (chip) {
974 case -1:
975 /* TODO: Disable the NFC clock */
976 if (host->clk_act)
977 host->clk_act = 0;
978 break;
979 case 0:
980 /* TODO: Enable the NFC clock */
981 if (!host->clk_act)
982 host->clk_act = 1;
983 break;
984
985 default:
986 break;
987 }
988}
989
990/*
991 * Used by the upper layer to write command to NAND Flash for
992 * different operations to be carried out on NAND Flash
993 */
John Rigby3c285c72010-01-26 19:24:18 -0700994void mxc_nand_command(struct mtd_info *mtd, unsigned command,
Ilya Yanokf9e2bee2009-08-11 02:32:54 +0400995 int column, int page_addr)
996{
997 struct nand_chip *nand_chip = mtd->priv;
998 struct mxc_nand_host *host = nand_chip->priv;
999
1000 MTDDEBUG(MTD_DEBUG_LEVEL3,
1001 "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
1002 command, column, page_addr);
1003
1004 /* Reset command state information */
1005 host->status_request = false;
1006
1007 /* Command pre-processing step */
1008 switch (command) {
1009
1010 case NAND_CMD_STATUS:
1011 host->col_addr = 0;
1012 host->status_request = true;
1013 break;
1014
1015 case NAND_CMD_READ0:
John Rigby3c285c72010-01-26 19:24:18 -07001016 host->page_addr = page_addr;
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001017 host->col_addr = column;
1018 host->spare_only = false;
1019 break;
1020
1021 case NAND_CMD_READOOB:
1022 host->col_addr = column;
1023 host->spare_only = true;
1024 if (host->pagesize_2k)
1025 command = NAND_CMD_READ0; /* only READ0 is valid */
1026 break;
1027
1028 case NAND_CMD_SEQIN:
1029 if (column >= mtd->writesize) {
1030 /*
1031 * before sending SEQIN command for partial write,
1032 * we need read one page out. FSL NFC does not support
Helmut Raigerc8f4a4c2011-07-06 09:40:28 +02001033 * partial write. It always sends out 512+ecc+512+ecc
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001034 * for large page nand flash. But for small page nand
1035 * flash, it does support SPARE ONLY operation.
1036 */
1037 if (host->pagesize_2k) {
1038 /* call ourself to read a page */
1039 mxc_nand_command(mtd, NAND_CMD_READ0, 0,
1040 page_addr);
1041 }
1042
1043 host->col_addr = column - mtd->writesize;
1044 host->spare_only = true;
1045
1046 /* Set program pointer to spare region */
1047 if (!host->pagesize_2k)
1048 send_cmd(host, NAND_CMD_READOOB);
1049 } else {
1050 host->spare_only = false;
1051 host->col_addr = column;
1052
1053 /* Set program pointer to page start */
1054 if (!host->pagesize_2k)
1055 send_cmd(host, NAND_CMD_READ0);
1056 }
1057 break;
1058
1059 case NAND_CMD_PAGEPROG:
1060 send_prog_page(host, 0, host->spare_only);
1061
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +02001062 if (host->pagesize_2k && is_mxc_nfc_1()) {
Helmut Raigerc8f4a4c2011-07-06 09:40:28 +02001063 /* data in 4 areas */
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001064 send_prog_page(host, 1, host->spare_only);
1065 send_prog_page(host, 2, host->spare_only);
1066 send_prog_page(host, 3, host->spare_only);
1067 }
1068
1069 break;
1070 }
1071
1072 /* Write out the command to the device. */
1073 send_cmd(host, command);
1074
1075 /* Write out column address, if necessary */
1076 if (column != -1) {
1077 /*
1078 * MXC NANDFC can only perform full page+spare or
Helmut Raigerc8f4a4c2011-07-06 09:40:28 +02001079 * spare-only read/write. When the upper layers perform
1080 * a read/write buffer operation, we will use the saved
1081 * column address to index into the full page.
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001082 */
1083 send_addr(host, 0);
1084 if (host->pagesize_2k)
1085 /* another col addr cycle for 2k page */
1086 send_addr(host, 0);
1087 }
1088
1089 /* Write out page address, if necessary */
1090 if (page_addr != -1) {
John Rigby3c285c72010-01-26 19:24:18 -07001091 u32 page_mask = nand_chip->pagemask;
1092 do {
1093 send_addr(host, page_addr & 0xFF);
1094 page_addr >>= 8;
1095 page_mask >>= 8;
1096 } while (page_mask);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001097 }
1098
1099 /* Command post-processing step */
1100 switch (command) {
1101
1102 case NAND_CMD_RESET:
1103 break;
1104
1105 case NAND_CMD_READOOB:
1106 case NAND_CMD_READ0:
1107 if (host->pagesize_2k) {
1108 /* send read confirm command */
1109 send_cmd(host, NAND_CMD_READSTART);
1110 /* read for each AREA */
1111 send_read_page(host, 0, host->spare_only);
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +02001112 if (is_mxc_nfc_1()) {
John Rigby3c285c72010-01-26 19:24:18 -07001113 send_read_page(host, 1, host->spare_only);
1114 send_read_page(host, 2, host->spare_only);
1115 send_read_page(host, 3, host->spare_only);
1116 }
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001117 } else {
1118 send_read_page(host, 0, host->spare_only);
1119 }
1120 break;
1121
1122 case NAND_CMD_READID:
1123 host->col_addr = 0;
1124 send_read_id(host);
1125 break;
1126
1127 case NAND_CMD_PAGEPROG:
1128 break;
1129
1130 case NAND_CMD_STATUS:
1131 break;
1132
1133 case NAND_CMD_ERASE2:
1134 break;
1135 }
1136}
1137
Timo Ketolaad85f952012-04-18 22:55:31 +00001138#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
1139
1140static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
1141static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
1142
1143static struct nand_bbt_descr bbt_main_descr = {
1144 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1145 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1146 .offs = 0,
1147 .len = 4,
1148 .veroffs = 4,
1149 .maxblocks = 4,
1150 .pattern = bbt_pattern,
1151};
1152
1153static struct nand_bbt_descr bbt_mirror_descr = {
1154 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
1155 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1156 .offs = 0,
1157 .len = 4,
1158 .veroffs = 4,
1159 .maxblocks = 4,
1160 .pattern = mirror_pattern,
1161};
1162
1163#endif
1164
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001165int board_nand_init(struct nand_chip *this)
1166{
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001167 struct mtd_info *mtd;
Tom Rini05ae4c92012-09-18 09:24:22 -07001168#ifdef MXC_NFC_V2_1
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001169 uint16_t tmp;
Tom Rini05ae4c92012-09-18 09:24:22 -07001170#endif
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001171
Timo Ketolaad85f952012-04-18 22:55:31 +00001172#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
1173 this->options |= NAND_USE_FLASH_BBT;
1174 this->bbt_td = &bbt_main_descr;
1175 this->bbt_md = &bbt_mirror_descr;
1176#endif
1177
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001178 /* structures must be linked */
1179 mtd = &host->mtd;
1180 mtd->priv = this;
1181 host->nand = this;
1182
1183 /* 5 us command delay time */
1184 this->chip_delay = 5;
1185
1186 this->priv = host;
1187 this->dev_ready = mxc_nand_dev_ready;
1188 this->cmdfunc = mxc_nand_command;
1189 this->select_chip = mxc_nand_select_chip;
1190 this->read_byte = mxc_nand_read_byte;
1191 this->read_word = mxc_nand_read_word;
1192 this->write_buf = mxc_nand_write_buf;
1193 this->read_buf = mxc_nand_read_buf;
1194 this->verify_buf = mxc_nand_verify_buf;
1195
Benoît Thébaudeau3f775192012-08-13 22:48:12 +02001196 host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE;
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001197 host->clk_act = 1;
1198
1199#ifdef CONFIG_MXC_NAND_HWECC
1200 this->ecc.calculate = mxc_nand_calculate_ecc;
1201 this->ecc.hwctl = mxc_nand_enable_hwecc;
1202 this->ecc.correct = mxc_nand_correct_data;
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +02001203 if (is_mxc_nfc_21()) {
John Rigby3c285c72010-01-26 19:24:18 -07001204 this->ecc.mode = NAND_ECC_HW_SYNDROME;
1205 this->ecc.read_page = mxc_nand_read_page_syndrome;
1206 this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome;
1207 this->ecc.read_oob = mxc_nand_read_oob_syndrome;
1208 this->ecc.write_page = mxc_nand_write_page_syndrome;
1209 this->ecc.write_page_raw = mxc_nand_write_page_raw_syndrome;
1210 this->ecc.write_oob = mxc_nand_write_oob_syndrome;
1211 this->ecc.bytes = 9;
1212 this->ecc.prepad = 7;
1213 } else {
1214 this->ecc.mode = NAND_ECC_HW;
1215 }
1216
1217 host->pagesize_2k = 0;
1218
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001219 this->ecc.size = 512;
Benoît Thébaudeau9166d5f2012-08-13 22:50:07 +02001220 _mxc_nand_enable_hwecc(mtd, 1);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001221#else
1222 this->ecc.layout = &nand_soft_eccoob;
1223 this->ecc.mode = NAND_ECC_SOFT;
Benoît Thébaudeau9166d5f2012-08-13 22:50:07 +02001224 _mxc_nand_enable_hwecc(mtd, 0);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001225#endif
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001226 /* Reset NAND */
1227 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1228
Benoît Thébaudeau0452dcd2012-08-13 22:50:30 +02001229 /* NAND bus width determines access functions used by upper layer */
1230 if (is_16bit_nand())
1231 this->options |= NAND_BUSWIDTH_16;
1232
1233#ifdef CONFIG_SYS_NAND_LARGEPAGE
1234 host->pagesize_2k = 1;
1235 this->ecc.layout = &nand_hw_eccoob2k;
1236#else
1237 host->pagesize_2k = 0;
1238 this->ecc.layout = &nand_hw_eccoob;
1239#endif
1240
Benoît Thébaudeauc5b4eb12012-08-13 22:50:53 +02001241#ifdef MXC_NFC_V2_1
Benoît Thébaudeau0452dcd2012-08-13 22:50:30 +02001242 tmp = readw(&host->regs->config1);
1243 tmp |= NFC_ONE_CYCLE;
1244 tmp |= NFC_4_8N_ECC;
1245 writew(tmp, &host->regs->config1);
1246 if (host->pagesize_2k)
1247 writew(64/2, &host->regs->spare_area_size);
1248 else
1249 writew(16/2, &host->regs->spare_area_size);
1250#endif
1251
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001252 /*
1253 * preset operation
1254 * Unlock the internal RAM Buffer
1255 */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +02001256 writew(0x2, &host->regs->config);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001257
1258 /* Blocks to be unlocked */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +02001259 writew(0x0, &host->regs->unlockstart_blkaddr);
Helmut Raiger38ba3242011-07-06 19:04:41 +02001260 /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the
1261 * unlockend_blkaddr, but the magic 0x4000 does not always work
1262 * when writing more than some 32 megabytes (on 2k page nands)
1263 * However 0xFFFF doesn't seem to have this kind
1264 * of limitation (tried it back and forth several times).
1265 * The linux kernel driver sets this to 0xFFFF for the v2 controller
1266 * only, but probably this was not tested there for v1.
1267 * The very same limitation seems to apply to this kernel driver.
1268 * This might be NAND chip specific and the i.MX31 datasheet is
1269 * extremely vague about the semantics of this register.
1270 */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +02001271 writew(0xFFFF, &host->regs->unlockend_blkaddr);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001272
1273 /* Unlock Block Command for given address range */
Benoît Thébaudeau3f775192012-08-13 22:48:12 +02001274 writew(0x4, &host->regs->wrprot);
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001275
Benoît Thébaudeau32ae5b42012-08-13 22:48:26 +02001276 return 0;
Ilya Yanokf9e2bee2009-08-11 02:32:54 +04001277}