]>
Commit | Line | Data |
---|---|---|
932394ac WD |
1 | /* |
2 | * drivers/mtd/nand.c | |
3 | * | |
4 | * Overview: | |
5 | * This is the generic MTD driver for NAND flash devices. It should be | |
6 | * capable of working with almost all NAND chips currently available. | |
7 | * Basic support for AG-AND chips is provided. | |
ac7eb8a3 | 8 | * |
932394ac WD |
9 | * Additional technical information is available on |
10 | * http://www.linux-mtd.infradead.org/tech/nand.html | |
ac7eb8a3 | 11 | * |
932394ac | 12 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
53677ef1 | 13 | * 2002 Thomas Gleixner (tglx@linutronix.de) |
932394ac | 14 | * |
ac7eb8a3 | 15 | * 02-08-2004 tglx: support for strange chips, which cannot auto increment |
932394ac WD |
16 | * pages on read / read_oob |
17 | * | |
18 | * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes | |
19 | * pointed this out, as he marked an auto increment capable chip | |
20 | * as NOAUTOINCR in the board driver. | |
21 | * Make reads over block boundaries work too | |
22 | * | |
23 | * 04-14-2004 tglx: first working version for 2k page size chips | |
ac7eb8a3 | 24 | * |
932394ac WD |
25 | * 05-19-2004 tglx: Basic support for Renesas AG-AND chips |
26 | * | |
27 | * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared | |
28 | * among multiple independend devices. Suggestions and initial patch | |
29 | * from Ben Dooks <ben-mtd@fluff.org> | |
30 | * | |
31 | * Credits: | |
ac7eb8a3 WD |
32 | * David Woodhouse for adding multichip support |
33 | * | |
932394ac WD |
34 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the |
35 | * rework for 2K page size chips | |
36 | * | |
37 | * TODO: | |
38 | * Enable cached programming for 2k page size chips | |
39 | * Check, if mtd->ecctype should be set to MTD_ECC_HW | |
40 | * if we have HW ecc support. | |
41 | * The AG-AND chips have nice features for speed improvement, | |
42 | * which are not supported yet. Read / program 4 pages in one go. | |
43 | * | |
44 | * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $ | |
45 | * | |
46 | * This program is free software; you can redistribute it and/or modify | |
47 | * it under the terms of the GNU General Public License version 2 as | |
48 | * published by the Free Software Foundation. | |
49 | * | |
50 | */ | |
51 | ||
52 | /* XXX U-BOOT XXX */ | |
53 | #if 0 | |
54 | #include <linux/delay.h> | |
55 | #include <linux/errno.h> | |
56 | #include <linux/sched.h> | |
57 | #include <linux/slab.h> | |
58 | #include <linux/types.h> | |
59 | #include <linux/mtd/mtd.h> | |
60 | #include <linux/mtd/nand.h> | |
61 | #include <linux/mtd/nand_ecc.h> | |
62 | #include <linux/mtd/compatmac.h> | |
63 | #include <linux/interrupt.h> | |
64 | #include <linux/bitops.h> | |
65 | #include <asm/io.h> | |
66 | ||
67 | #ifdef CONFIG_MTD_PARTITIONS | |
68 | #include <linux/mtd/partitions.h> | |
69 | #endif | |
70 | ||
ac7eb8a3 | 71 | #endif |
932394ac WD |
72 | |
73 | #include <common.h> | |
addb2e16 | 74 | |
cb51c0bf | 75 | #if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) |
932394ac WD |
76 | |
77 | #include <malloc.h> | |
78 | #include <watchdog.h> | |
79 | #include <linux/mtd/compat.h> | |
80 | #include <linux/mtd/mtd.h> | |
81 | #include <linux/mtd/nand.h> | |
82 | #include <linux/mtd/nand_ecc.h> | |
83 | ||
84 | #include <asm/io.h> | |
85 | #include <asm/errno.h> | |
86 | ||
87 | #ifdef CONFIG_JFFS2_NAND | |
88 | #include <jffs2/jffs2.h> | |
89 | #endif | |
90 | ||
932394ac WD |
91 | /* Define default oob placement schemes for large and small page devices */ |
92 | static struct nand_oobinfo nand_oob_8 = { | |
93 | .useecc = MTD_NANDECC_AUTOPLACE, | |
94 | .eccbytes = 3, | |
95 | .eccpos = {0, 1, 2}, | |
96 | .oobfree = { {3, 2}, {6, 2} } | |
97 | }; | |
98 | ||
99 | static struct nand_oobinfo nand_oob_16 = { | |
100 | .useecc = MTD_NANDECC_AUTOPLACE, | |
101 | .eccbytes = 6, | |
102 | .eccpos = {0, 1, 2, 3, 6, 7}, | |
103 | .oobfree = { {8, 8} } | |
104 | }; | |
105 | ||
106 | static struct nand_oobinfo nand_oob_64 = { | |
107 | .useecc = MTD_NANDECC_AUTOPLACE, | |
108 | .eccbytes = 24, | |
109 | .eccpos = { | |
ac7eb8a3 WD |
110 | 40, 41, 42, 43, 44, 45, 46, 47, |
111 | 48, 49, 50, 51, 52, 53, 54, 55, | |
932394ac WD |
112 | 56, 57, 58, 59, 60, 61, 62, 63}, |
113 | .oobfree = { {2, 38} } | |
114 | }; | |
115 | ||
248ae5cf SP |
116 | static struct nand_oobinfo nand_oob_128 = { |
117 | .useecc = MTD_NANDECC_AUTOPLACE, | |
118 | .eccbytes = 48, | |
119 | .eccpos = { | |
120 | 80, 81, 82, 83, 84, 85, 86, 87, | |
121 | 88, 89, 90, 91, 92, 93, 94, 95, | |
122 | 96, 97, 98, 99, 100, 101, 102, 103, | |
123 | 104, 105, 106, 107, 108, 109, 110, 111, | |
124 | 112, 113, 114, 115, 116, 117, 118, 119, | |
125 | 120, 121, 122, 123, 124, 125, 126, 127}, | |
126 | .oobfree = { {2, 78} } | |
932394ac WD |
127 | }; |
128 | ||
248ae5cf SP |
129 | /* This is used for padding purposes in nand_write_oob */ |
130 | static u_char *ffchars; | |
131 | ||
932394ac WD |
132 | /* |
133 | * NAND low-level MTD interface functions | |
134 | */ | |
135 | static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len); | |
136 | static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len); | |
137 | static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len); | |
138 | ||
139 | static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); | |
140 | static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |
141 | size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); | |
142 | static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); | |
143 | static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf); | |
144 | static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |
145 | size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); | |
146 | static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf); | |
147 | /* XXX U-BOOT XXX */ | |
148 | #if 0 | |
149 | static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, | |
150 | unsigned long count, loff_t to, size_t * retlen); | |
151 | static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, | |
152 | unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | |
153 | #endif | |
154 | static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); | |
155 | static void nand_sync (struct mtd_info *mtd); | |
156 | ||
157 | /* Some internal functions */ | |
158 | static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, | |
159 | struct nand_oobinfo *oobsel, int mode); | |
160 | #ifdef CONFIG_MTD_NAND_VERIFY_WRITE | |
ac7eb8a3 | 161 | static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, |
932394ac WD |
162 | u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); |
163 | #else | |
164 | #define nand_verify_pages(...) (0) | |
165 | #endif | |
ac7eb8a3 | 166 | |
932394ac WD |
167 | static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); |
168 | ||
169 | /** | |
170 | * nand_release_device - [GENERIC] release chip | |
171 | * @mtd: MTD device structure | |
ac7eb8a3 WD |
172 | * |
173 | * Deselect, release chip lock and wake up anyone waiting on the device | |
932394ac WD |
174 | */ |
175 | /* XXX U-BOOT XXX */ | |
176 | #if 0 | |
177 | static void nand_release_device (struct mtd_info *mtd) | |
178 | { | |
179 | struct nand_chip *this = mtd->priv; | |
180 | ||
181 | /* De-select the NAND device */ | |
182 | this->select_chip(mtd, -1); | |
183 | /* Do we have a hardware controller ? */ | |
184 | if (this->controller) { | |
185 | spin_lock(&this->controller->lock); | |
186 | this->controller->active = NULL; | |
187 | spin_unlock(&this->controller->lock); | |
188 | } | |
189 | /* Release the chip */ | |
190 | spin_lock (&this->chip_lock); | |
191 | this->state = FL_READY; | |
192 | wake_up (&this->wq); | |
193 | spin_unlock (&this->chip_lock); | |
194 | } | |
195 | #else | |
8e9655f8 WD |
196 | static void nand_release_device (struct mtd_info *mtd) |
197 | { | |
198 | struct nand_chip *this = mtd->priv; | |
199 | this->select_chip(mtd, -1); /* De-select the NAND device */ | |
248ae5cf SP |
200 | if (ffchars) { |
201 | kfree(ffchars); | |
202 | ffchars = NULL; | |
203 | } | |
8e9655f8 | 204 | } |
932394ac WD |
205 | #endif |
206 | ||
207 | /** | |
208 | * nand_read_byte - [DEFAULT] read one byte from the chip | |
209 | * @mtd: MTD device structure | |
210 | * | |
211 | * Default read function for 8bit buswith | |
212 | */ | |
213 | static u_char nand_read_byte(struct mtd_info *mtd) | |
214 | { | |
215 | struct nand_chip *this = mtd->priv; | |
216 | return readb(this->IO_ADDR_R); | |
217 | } | |
218 | ||
219 | /** | |
220 | * nand_write_byte - [DEFAULT] write one byte to the chip | |
221 | * @mtd: MTD device structure | |
222 | * @byte: pointer to data byte to write | |
223 | * | |
224 | * Default write function for 8it buswith | |
225 | */ | |
226 | static void nand_write_byte(struct mtd_info *mtd, u_char byte) | |
227 | { | |
228 | struct nand_chip *this = mtd->priv; | |
229 | writeb(byte, this->IO_ADDR_W); | |
230 | } | |
231 | ||
232 | /** | |
233 | * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip | |
234 | * @mtd: MTD device structure | |
235 | * | |
ac7eb8a3 | 236 | * Default read function for 16bit buswith with |
932394ac WD |
237 | * endianess conversion |
238 | */ | |
239 | static u_char nand_read_byte16(struct mtd_info *mtd) | |
240 | { | |
241 | struct nand_chip *this = mtd->priv; | |
242 | return (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); | |
243 | } | |
244 | ||
245 | /** | |
246 | * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip | |
247 | * @mtd: MTD device structure | |
248 | * @byte: pointer to data byte to write | |
249 | * | |
250 | * Default write function for 16bit buswith with | |
251 | * endianess conversion | |
252 | */ | |
253 | static void nand_write_byte16(struct mtd_info *mtd, u_char byte) | |
254 | { | |
255 | struct nand_chip *this = mtd->priv; | |
256 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); | |
257 | } | |
258 | ||
259 | /** | |
260 | * nand_read_word - [DEFAULT] read one word from the chip | |
261 | * @mtd: MTD device structure | |
262 | * | |
ac7eb8a3 | 263 | * Default read function for 16bit buswith without |
932394ac WD |
264 | * endianess conversion |
265 | */ | |
266 | static u16 nand_read_word(struct mtd_info *mtd) | |
267 | { | |
268 | struct nand_chip *this = mtd->priv; | |
269 | return readw(this->IO_ADDR_R); | |
270 | } | |
271 | ||
272 | /** | |
273 | * nand_write_word - [DEFAULT] write one word to the chip | |
274 | * @mtd: MTD device structure | |
275 | * @word: data word to write | |
276 | * | |
ac7eb8a3 | 277 | * Default write function for 16bit buswith without |
932394ac WD |
278 | * endianess conversion |
279 | */ | |
280 | static void nand_write_word(struct mtd_info *mtd, u16 word) | |
281 | { | |
282 | struct nand_chip *this = mtd->priv; | |
283 | writew(word, this->IO_ADDR_W); | |
284 | } | |
285 | ||
286 | /** | |
287 | * nand_select_chip - [DEFAULT] control CE line | |
288 | * @mtd: MTD device structure | |
289 | * @chip: chipnumber to select, -1 for deselect | |
290 | * | |
291 | * Default select function for 1 chip devices. | |
292 | */ | |
293 | static void nand_select_chip(struct mtd_info *mtd, int chip) | |
294 | { | |
295 | struct nand_chip *this = mtd->priv; | |
296 | switch(chip) { | |
297 | case -1: | |
ac7eb8a3 | 298 | this->hwcontrol(mtd, NAND_CTL_CLRNCE); |
932394ac WD |
299 | break; |
300 | case 0: | |
301 | this->hwcontrol(mtd, NAND_CTL_SETNCE); | |
302 | break; | |
303 | ||
304 | default: | |
305 | BUG(); | |
306 | } | |
307 | } | |
308 | ||
309 | /** | |
310 | * nand_write_buf - [DEFAULT] write buffer to chip | |
311 | * @mtd: MTD device structure | |
312 | * @buf: data buffer | |
313 | * @len: number of bytes to write | |
314 | * | |
315 | * Default write function for 8bit buswith | |
316 | */ | |
317 | static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |
318 | { | |
319 | int i; | |
320 | struct nand_chip *this = mtd->priv; | |
321 | ||
322 | for (i=0; i<len; i++) | |
323 | writeb(buf[i], this->IO_ADDR_W); | |
324 | } | |
325 | ||
326 | /** | |
ac7eb8a3 | 327 | * nand_read_buf - [DEFAULT] read chip data into buffer |
932394ac WD |
328 | * @mtd: MTD device structure |
329 | * @buf: buffer to store date | |
330 | * @len: number of bytes to read | |
331 | * | |
332 | * Default read function for 8bit buswith | |
333 | */ | |
334 | static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |
335 | { | |
336 | int i; | |
337 | struct nand_chip *this = mtd->priv; | |
338 | ||
339 | for (i=0; i<len; i++) | |
340 | buf[i] = readb(this->IO_ADDR_R); | |
341 | } | |
342 | ||
343 | /** | |
ac7eb8a3 | 344 | * nand_verify_buf - [DEFAULT] Verify chip data against buffer |
932394ac WD |
345 | * @mtd: MTD device structure |
346 | * @buf: buffer containing the data to compare | |
347 | * @len: number of bytes to compare | |
348 | * | |
349 | * Default verify function for 8bit buswith | |
350 | */ | |
351 | static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | |
352 | { | |
353 | int i; | |
354 | struct nand_chip *this = mtd->priv; | |
355 | ||
356 | for (i=0; i<len; i++) | |
357 | if (buf[i] != readb(this->IO_ADDR_R)) | |
358 | return -EFAULT; | |
359 | ||
360 | return 0; | |
361 | } | |
362 | ||
363 | /** | |
364 | * nand_write_buf16 - [DEFAULT] write buffer to chip | |
365 | * @mtd: MTD device structure | |
366 | * @buf: data buffer | |
367 | * @len: number of bytes to write | |
368 | * | |
369 | * Default write function for 16bit buswith | |
370 | */ | |
371 | static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |
372 | { | |
373 | int i; | |
374 | struct nand_chip *this = mtd->priv; | |
375 | u16 *p = (u16 *) buf; | |
376 | len >>= 1; | |
ac7eb8a3 | 377 | |
932394ac WD |
378 | for (i=0; i<len; i++) |
379 | writew(p[i], this->IO_ADDR_W); | |
ac7eb8a3 | 380 | |
932394ac WD |
381 | } |
382 | ||
383 | /** | |
ac7eb8a3 | 384 | * nand_read_buf16 - [DEFAULT] read chip data into buffer |
932394ac WD |
385 | * @mtd: MTD device structure |
386 | * @buf: buffer to store date | |
387 | * @len: number of bytes to read | |
388 | * | |
389 | * Default read function for 16bit buswith | |
390 | */ | |
391 | static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |
392 | { | |
393 | int i; | |
394 | struct nand_chip *this = mtd->priv; | |
395 | u16 *p = (u16 *) buf; | |
396 | len >>= 1; | |
397 | ||
398 | for (i=0; i<len; i++) | |
399 | p[i] = readw(this->IO_ADDR_R); | |
400 | } | |
401 | ||
402 | /** | |
ac7eb8a3 | 403 | * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer |
932394ac WD |
404 | * @mtd: MTD device structure |
405 | * @buf: buffer containing the data to compare | |
406 | * @len: number of bytes to compare | |
407 | * | |
408 | * Default verify function for 16bit buswith | |
409 | */ | |
410 | static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |
411 | { | |
412 | int i; | |
413 | struct nand_chip *this = mtd->priv; | |
414 | u16 *p = (u16 *) buf; | |
415 | len >>= 1; | |
416 | ||
417 | for (i=0; i<len; i++) | |
418 | if (p[i] != readw(this->IO_ADDR_R)) | |
419 | return -EFAULT; | |
420 | ||
421 | return 0; | |
422 | } | |
423 | ||
424 | /** | |
425 | * nand_block_bad - [DEFAULT] Read bad block marker from the chip | |
426 | * @mtd: MTD device structure | |
427 | * @ofs: offset from device start | |
428 | * @getchip: 0, if the chip is already selected | |
429 | * | |
ac7eb8a3 | 430 | * Check, if the block is bad. |
932394ac WD |
431 | */ |
432 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |
433 | { | |
434 | int page, chipnr, res = 0; | |
435 | struct nand_chip *this = mtd->priv; | |
436 | u16 bad; | |
437 | ||
a7988659 TK |
438 | page = (int)(ofs >> this->page_shift) & this->pagemask; |
439 | ||
932394ac | 440 | if (getchip) { |
932394ac WD |
441 | chipnr = (int)(ofs >> this->chip_shift); |
442 | ||
443 | /* Grab the lock and see if the device is available */ | |
444 | nand_get_device (this, mtd, FL_READING); | |
445 | ||
446 | /* Select the NAND device */ | |
447 | this->select_chip(mtd, chipnr); | |
a7988659 | 448 | } |
932394ac WD |
449 | |
450 | if (this->options & NAND_BUSWIDTH_16) { | |
a7988659 | 451 | this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page); |
932394ac WD |
452 | bad = cpu_to_le16(this->read_word(mtd)); |
453 | if (this->badblockpos & 0x1) | |
454 | bad >>= 1; | |
455 | if ((bad & 0xFF) != 0xff) | |
456 | res = 1; | |
457 | } else { | |
a7988659 | 458 | this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page); |
932394ac WD |
459 | if (this->read_byte(mtd) != 0xff) |
460 | res = 1; | |
461 | } | |
ac7eb8a3 | 462 | |
932394ac WD |
463 | if (getchip) { |
464 | /* Deselect and wake up anyone waiting on the device */ | |
465 | nand_release_device(mtd); | |
ac7eb8a3 WD |
466 | } |
467 | ||
932394ac WD |
468 | return res; |
469 | } | |
470 | ||
471 | /** | |
472 | * nand_default_block_markbad - [DEFAULT] mark a block bad | |
473 | * @mtd: MTD device structure | |
474 | * @ofs: offset from device start | |
475 | * | |
476 | * This is the default implementation, which can be overridden by | |
477 | * a hardware specific driver. | |
478 | */ | |
479 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |
480 | { | |
481 | struct nand_chip *this = mtd->priv; | |
482 | u_char buf[2] = {0, 0}; | |
483 | size_t retlen; | |
484 | int block; | |
ac7eb8a3 | 485 | |
932394ac WD |
486 | /* Get block number */ |
487 | block = ((int) ofs) >> this->bbt_erase_shift; | |
488 | this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); | |
489 | ||
490 | /* Do we have a flash based bad block table ? */ | |
491 | if (this->options & NAND_USE_FLASH_BBT) | |
492 | return nand_update_bbt (mtd, ofs); | |
ac7eb8a3 | 493 | |
932394ac WD |
494 | /* We write two bytes, so we dont have to mess with 16 bit access */ |
495 | ofs += mtd->oobsize + (this->badblockpos & ~0x01); | |
496 | return nand_write_oob (mtd, ofs , 2, &retlen, buf); | |
497 | } | |
498 | ||
ac7eb8a3 | 499 | /** |
932394ac WD |
500 | * nand_check_wp - [GENERIC] check if the chip is write protected |
501 | * @mtd: MTD device structure | |
ac7eb8a3 | 502 | * Check, if the device is write protected |
932394ac | 503 | * |
ac7eb8a3 | 504 | * The function expects, that the device is already selected |
932394ac WD |
505 | */ |
506 | static int nand_check_wp (struct mtd_info *mtd) | |
507 | { | |
508 | struct nand_chip *this = mtd->priv; | |
509 | /* Check the WP bit */ | |
510 | this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); | |
ac7eb8a3 | 511 | return (this->read_byte(mtd) & 0x80) ? 0 : 1; |
932394ac | 512 | } |