]>
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 | 9 | * Additional technical information is available on |
c45912d8 | 10 | * http://www.linux-mtd.infradead.org/doc/nand.html |
ac7eb8a3 | 11 | * |
932394ac | 12 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
cfa460ad | 13 | * 2002-2006 Thomas Gleixner (tglx@linutronix.de) |
932394ac | 14 | * |
cfa460ad | 15 | * Credits: |
ac7eb8a3 WD |
16 | * David Woodhouse for adding multichip support |
17 | * | |
932394ac WD |
18 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the |
19 | * rework for 2K page size chips | |
20 | * | |
cfa460ad | 21 | * TODO: |
932394ac WD |
22 | * Enable cached programming for 2k page size chips |
23 | * Check, if mtd->ecctype should be set to MTD_ECC_HW | |
24 | * if we have HW ecc support. | |
25 | * The AG-AND chips have nice features for speed improvement, | |
26 | * which are not supported yet. Read / program 4 pages in one go. | |
c45912d8 | 27 | * BBT table is not serialized, has to be fixed |
932394ac | 28 | * |
932394ac WD |
29 | * This program is free software; you can redistribute it and/or modify |
30 | * it under the terms of the GNU General Public License version 2 as | |
31 | * published by the Free Software Foundation. | |
32 | * | |
33 | */ | |
34 | ||
35 | /* XXX U-BOOT XXX */ | |
36 | #if 0 | |
cfa460ad | 37 | #include <linux/module.h> |
932394ac WD |
38 | #include <linux/delay.h> |
39 | #include <linux/errno.h> | |
cfa460ad | 40 | #include <linux/err.h> |
932394ac WD |
41 | #include <linux/sched.h> |
42 | #include <linux/slab.h> | |
43 | #include <linux/types.h> | |
44 | #include <linux/mtd/mtd.h> | |
45 | #include <linux/mtd/nand.h> | |
46 | #include <linux/mtd/nand_ecc.h> | |
47 | #include <linux/mtd/compatmac.h> | |
48 | #include <linux/interrupt.h> | |
49 | #include <linux/bitops.h> | |
cfa460ad | 50 | #include <linux/leds.h> |
932394ac WD |
51 | #include <asm/io.h> |
52 | ||
53 | #ifdef CONFIG_MTD_PARTITIONS | |
54 | #include <linux/mtd/partitions.h> | |
55 | #endif | |
56 | ||
ac7eb8a3 | 57 | #endif |
932394ac WD |
58 | |
59 | #include <common.h> | |
addb2e16 | 60 | |
cfa460ad WJ |
61 | #define ENOTSUPP 524 /* Operation is not supported */ |
62 | ||
932394ac WD |
63 | #include <malloc.h> |
64 | #include <watchdog.h> | |
cfa460ad | 65 | #include <linux/err.h> |
932394ac WD |
66 | #include <linux/mtd/compat.h> |
67 | #include <linux/mtd/mtd.h> | |
68 | #include <linux/mtd/nand.h> | |
69 | #include <linux/mtd/nand_ecc.h> | |
70 | ||
10bb62d8 SR |
71 | #ifdef CONFIG_MTD_PARTITIONS |
72 | #include <linux/mtd/partitions.h> | |
73 | #endif | |
74 | ||
932394ac WD |
75 | #include <asm/io.h> |
76 | #include <asm/errno.h> | |
77 | ||
78 | #ifdef CONFIG_JFFS2_NAND | |
79 | #include <jffs2/jffs2.h> | |
80 | #endif | |
81 | ||
8da60128 PT |
82 | /* |
83 | * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting | |
84 | * a flash. NAND flash is initialized prior to interrupts so standard timers | |
85 | * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value | |
86 | * which is greater than (max NAND reset time / NAND status read time). | |
87 | * A conservative default of 200000 (500 us / 25 ns) is used as a default. | |
88 | */ | |
89 | #ifndef CONFIG_SYS_NAND_RESET_CNT | |
90 | #define CONFIG_SYS_NAND_RESET_CNT 200000 | |
91 | #endif | |
92 | ||
932394ac | 93 | /* Define default oob placement schemes for large and small page devices */ |
cfa460ad | 94 | static struct nand_ecclayout nand_oob_8 = { |
932394ac WD |
95 | .eccbytes = 3, |
96 | .eccpos = {0, 1, 2}, | |
cfa460ad WJ |
97 | .oobfree = { |
98 | {.offset = 3, | |
99 | .length = 2}, | |
100 | {.offset = 6, | |
101 | .length = 2}} | |
932394ac WD |
102 | }; |
103 | ||
cfa460ad | 104 | static struct nand_ecclayout nand_oob_16 = { |
932394ac WD |
105 | .eccbytes = 6, |
106 | .eccpos = {0, 1, 2, 3, 6, 7}, | |
cfa460ad WJ |
107 | .oobfree = { |
108 | {.offset = 8, | |
109 | . length = 8}} | |
932394ac WD |
110 | }; |
111 | ||
cfa460ad | 112 | static struct nand_ecclayout nand_oob_64 = { |
932394ac WD |
113 | .eccbytes = 24, |
114 | .eccpos = { | |
cfa460ad WJ |
115 | 40, 41, 42, 43, 44, 45, 46, 47, |
116 | 48, 49, 50, 51, 52, 53, 54, 55, | |
117 | 56, 57, 58, 59, 60, 61, 62, 63}, | |
118 | .oobfree = { | |
119 | {.offset = 2, | |
120 | .length = 38}} | |
932394ac WD |
121 | }; |
122 | ||
cfa460ad | 123 | static struct nand_ecclayout nand_oob_128 = { |
248ae5cf SP |
124 | .eccbytes = 48, |
125 | .eccpos = { | |
cfa460ad WJ |
126 | 80, 81, 82, 83, 84, 85, 86, 87, |
127 | 88, 89, 90, 91, 92, 93, 94, 95, | |
128 | 96, 97, 98, 99, 100, 101, 102, 103, | |
129 | 104, 105, 106, 107, 108, 109, 110, 111, | |
130 | 112, 113, 114, 115, 116, 117, 118, 119, | |
131 | 120, 121, 122, 123, 124, 125, 126, 127}, | |
132 | .oobfree = { | |
133 | {.offset = 2, | |
134 | .length = 78}} | |
932394ac WD |
135 | }; |
136 | ||
cfa460ad WJ |
137 | |
138 | static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, | |
139 | int new_state); | |
140 | ||
141 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |
142 | struct mtd_oob_ops *ops); | |
143 | ||
144 | static int nand_wait(struct mtd_info *mtd, struct nand_chip *this); | |
248ae5cf | 145 | |
932394ac | 146 | /* |
c45912d8 | 147 | * For devices which display every fart in the system on a separate LED. Is |
cfa460ad | 148 | * compiled away when LED support is disabled. |
932394ac | 149 | */ |
932394ac WD |
150 | /* XXX U-BOOT XXX */ |
151 | #if 0 | |
cfa460ad | 152 | DEFINE_LED_TRIGGER(nand_led_trigger); |
932394ac | 153 | #endif |
ac7eb8a3 | 154 | |
932394ac WD |
155 | /** |
156 | * nand_release_device - [GENERIC] release chip | |
157 | * @mtd: MTD device structure | |
ac7eb8a3 WD |
158 | * |
159 | * Deselect, release chip lock and wake up anyone waiting on the device | |
932394ac WD |
160 | */ |
161 | /* XXX U-BOOT XXX */ | |
162 | #if 0 | |
cfa460ad | 163 | static void nand_release_device(struct mtd_info *mtd) |
932394ac | 164 | { |
cfa460ad | 165 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
166 | |
167 | /* De-select the NAND device */ | |
cfa460ad WJ |
168 | chip->select_chip(mtd, -1); |
169 | ||
170 | /* Release the controller and the chip */ | |
171 | spin_lock(&chip->controller->lock); | |
172 | chip->controller->active = NULL; | |
173 | chip->state = FL_READY; | |
174 | wake_up(&chip->controller->wq); | |
175 | spin_unlock(&chip->controller->lock); | |
932394ac WD |
176 | } |
177 | #else | |
8e9655f8 WD |
178 | static void nand_release_device (struct mtd_info *mtd) |
179 | { | |
180 | struct nand_chip *this = mtd->priv; | |
181 | this->select_chip(mtd, -1); /* De-select the NAND device */ | |
182 | } | |
932394ac WD |
183 | #endif |
184 | ||
185 | /** | |
186 | * nand_read_byte - [DEFAULT] read one byte from the chip | |
187 | * @mtd: MTD device structure | |
188 | * | |
189 | * Default read function for 8bit buswith | |
190 | */ | |
cfa460ad | 191 | static uint8_t nand_read_byte(struct mtd_info *mtd) |
932394ac | 192 | { |
cfa460ad WJ |
193 | struct nand_chip *chip = mtd->priv; |
194 | return readb(chip->IO_ADDR_R); | |
932394ac WD |
195 | } |
196 | ||
197 | /** | |
198 | * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip | |
199 | * @mtd: MTD device structure | |
200 | * | |
ac7eb8a3 | 201 | * Default read function for 16bit buswith with |
932394ac WD |
202 | * endianess conversion |
203 | */ | |
cfa460ad | 204 | static uint8_t nand_read_byte16(struct mtd_info *mtd) |
932394ac | 205 | { |
cfa460ad WJ |
206 | struct nand_chip *chip = mtd->priv; |
207 | return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); | |
932394ac WD |
208 | } |
209 | ||
210 | /** | |
211 | * nand_read_word - [DEFAULT] read one word from the chip | |
212 | * @mtd: MTD device structure | |
213 | * | |
ac7eb8a3 | 214 | * Default read function for 16bit buswith without |
932394ac WD |
215 | * endianess conversion |
216 | */ | |
217 | static u16 nand_read_word(struct mtd_info *mtd) | |
218 | { | |
cfa460ad WJ |
219 | struct nand_chip *chip = mtd->priv; |
220 | return readw(chip->IO_ADDR_R); | |
932394ac WD |
221 | } |
222 | ||
223 | /** | |
224 | * nand_select_chip - [DEFAULT] control CE line | |
225 | * @mtd: MTD device structure | |
cfa460ad | 226 | * @chipnr: chipnumber to select, -1 for deselect |
932394ac WD |
227 | * |
228 | * Default select function for 1 chip devices. | |
229 | */ | |
cfa460ad | 230 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) |
932394ac | 231 | { |
cfa460ad WJ |
232 | struct nand_chip *chip = mtd->priv; |
233 | ||
234 | switch (chipnr) { | |
932394ac | 235 | case -1: |
cfa460ad | 236 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); |
932394ac WD |
237 | break; |
238 | case 0: | |
932394ac WD |
239 | break; |
240 | ||
241 | default: | |
242 | BUG(); | |
243 | } | |
244 | } | |
245 | ||
246 | /** | |
247 | * nand_write_buf - [DEFAULT] write buffer to chip | |
248 | * @mtd: MTD device structure | |
249 | * @buf: data buffer | |
250 | * @len: number of bytes to write | |
251 | * | |
252 | * Default write function for 8bit buswith | |
253 | */ | |
cfa460ad | 254 | static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
255 | { |
256 | int i; | |
cfa460ad | 257 | struct nand_chip *chip = mtd->priv; |
932394ac | 258 | |
cfa460ad WJ |
259 | for (i = 0; i < len; i++) |
260 | writeb(buf[i], chip->IO_ADDR_W); | |
932394ac WD |
261 | } |
262 | ||
263 | /** | |
ac7eb8a3 | 264 | * nand_read_buf - [DEFAULT] read chip data into buffer |
932394ac WD |
265 | * @mtd: MTD device structure |
266 | * @buf: buffer to store date | |
267 | * @len: number of bytes to read | |
268 | * | |
269 | * Default read function for 8bit buswith | |
270 | */ | |
cfa460ad | 271 | static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
932394ac WD |
272 | { |
273 | int i; | |
cfa460ad | 274 | struct nand_chip *chip = mtd->priv; |
932394ac | 275 | |
cfa460ad WJ |
276 | for (i = 0; i < len; i++) |
277 | buf[i] = readb(chip->IO_ADDR_R); | |
932394ac WD |
278 | } |
279 | ||
280 | /** | |
ac7eb8a3 | 281 | * nand_verify_buf - [DEFAULT] Verify chip data against buffer |
932394ac WD |
282 | * @mtd: MTD device structure |
283 | * @buf: buffer containing the data to compare | |
284 | * @len: number of bytes to compare | |
285 | * | |
286 | * Default verify function for 8bit buswith | |
287 | */ | |
cfa460ad | 288 | static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
289 | { |
290 | int i; | |
cfa460ad | 291 | struct nand_chip *chip = mtd->priv; |
932394ac | 292 | |
cfa460ad WJ |
293 | for (i = 0; i < len; i++) |
294 | if (buf[i] != readb(chip->IO_ADDR_R)) | |
932394ac | 295 | return -EFAULT; |
932394ac WD |
296 | return 0; |
297 | } | |
298 | ||
299 | /** | |
300 | * nand_write_buf16 - [DEFAULT] write buffer to chip | |
301 | * @mtd: MTD device structure | |
302 | * @buf: data buffer | |
303 | * @len: number of bytes to write | |
304 | * | |
305 | * Default write function for 16bit buswith | |
306 | */ | |
cfa460ad | 307 | static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
308 | { |
309 | int i; | |
cfa460ad | 310 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
311 | u16 *p = (u16 *) buf; |
312 | len >>= 1; | |
ac7eb8a3 | 313 | |
cfa460ad WJ |
314 | for (i = 0; i < len; i++) |
315 | writew(p[i], chip->IO_ADDR_W); | |
ac7eb8a3 | 316 | |
932394ac WD |
317 | } |
318 | ||
319 | /** | |
ac7eb8a3 | 320 | * nand_read_buf16 - [DEFAULT] read chip data into buffer |
932394ac WD |
321 | * @mtd: MTD device structure |
322 | * @buf: buffer to store date | |
323 | * @len: number of bytes to read | |
324 | * | |
325 | * Default read function for 16bit buswith | |
326 | */ | |
cfa460ad | 327 | static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) |
932394ac WD |
328 | { |
329 | int i; | |
cfa460ad | 330 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
331 | u16 *p = (u16 *) buf; |
332 | len >>= 1; | |
333 | ||
cfa460ad WJ |
334 | for (i = 0; i < len; i++) |
335 | p[i] = readw(chip->IO_ADDR_R); | |
932394ac WD |
336 | } |
337 | ||
338 | /** | |
ac7eb8a3 | 339 | * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer |
932394ac WD |
340 | * @mtd: MTD device structure |
341 | * @buf: buffer containing the data to compare | |
342 | * @len: number of bytes to compare | |
343 | * | |
344 | * Default verify function for 16bit buswith | |
345 | */ | |
cfa460ad | 346 | static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
347 | { |
348 | int i; | |
cfa460ad | 349 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
350 | u16 *p = (u16 *) buf; |
351 | len >>= 1; | |
352 | ||
cfa460ad WJ |
353 | for (i = 0; i < len; i++) |
354 | if (p[i] != readw(chip->IO_ADDR_R)) | |
932394ac WD |
355 | return -EFAULT; |
356 | ||
357 | return 0; | |
358 | } | |
359 | ||
360 | /** | |
361 | * nand_block_bad - [DEFAULT] Read bad block marker from the chip | |
362 | * @mtd: MTD device structure | |
363 | * @ofs: offset from device start | |
364 | * @getchip: 0, if the chip is already selected | |
365 | * | |
ac7eb8a3 | 366 | * Check, if the block is bad. |
932394ac WD |
367 | */ |
368 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |
369 | { | |
370 | int page, chipnr, res = 0; | |
cfa460ad | 371 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
372 | u16 bad; |
373 | ||
cfa460ad | 374 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; |
a7988659 | 375 | |
932394ac | 376 | if (getchip) { |
cfa460ad | 377 | chipnr = (int)(ofs >> chip->chip_shift); |
932394ac | 378 | |
cfa460ad | 379 | nand_get_device(chip, mtd, FL_READING); |
932394ac WD |
380 | |
381 | /* Select the NAND device */ | |
cfa460ad | 382 | chip->select_chip(mtd, chipnr); |
a7988659 | 383 | } |
932394ac | 384 | |
cfa460ad WJ |
385 | if (chip->options & NAND_BUSWIDTH_16) { |
386 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE, | |
387 | page); | |
388 | bad = cpu_to_le16(chip->read_word(mtd)); | |
389 | if (chip->badblockpos & 0x1) | |
390 | bad >>= 8; | |
932394ac WD |
391 | if ((bad & 0xFF) != 0xff) |
392 | res = 1; | |
393 | } else { | |
cfa460ad WJ |
394 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page); |
395 | if (chip->read_byte(mtd) != 0xff) | |
932394ac WD |
396 | res = 1; |
397 | } | |
ac7eb8a3 | 398 | |
cfa460ad | 399 | if (getchip) |
932394ac | 400 | nand_release_device(mtd); |
ac7eb8a3 | 401 | |
932394ac WD |
402 | return res; |
403 | } | |
404 | ||
405 | /** | |
406 | * nand_default_block_markbad - [DEFAULT] mark a block bad | |
407 | * @mtd: MTD device structure | |
408 | * @ofs: offset from device start | |
409 | * | |
410 | * This is the default implementation, which can be overridden by | |
411 | * a hardware specific driver. | |
412 | */ | |
413 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |
414 | { | |
cfa460ad WJ |
415 | struct nand_chip *chip = mtd->priv; |
416 | uint8_t buf[2] = { 0, 0 }; | |
417 | int block, ret; | |
ac7eb8a3 | 418 | |
932394ac | 419 | /* Get block number */ |
cfa460ad WJ |
420 | block = (int)(ofs >> chip->bbt_erase_shift); |
421 | if (chip->bbt) | |
422 | chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); | |
932394ac WD |
423 | |
424 | /* Do we have a flash based bad block table ? */ | |
cfa460ad WJ |
425 | if (chip->options & NAND_USE_FLASH_BBT) |
426 | ret = nand_update_bbt(mtd, ofs); | |
427 | else { | |
428 | /* We write two bytes, so we dont have to mess with 16 bit | |
429 | * access | |
430 | */ | |
c45912d8 | 431 | nand_get_device(chip, mtd, FL_WRITING); |
cfa460ad WJ |
432 | ofs += mtd->oobsize; |
433 | chip->ops.len = chip->ops.ooblen = 2; | |
434 | chip->ops.datbuf = NULL; | |
435 | chip->ops.oobbuf = buf; | |
436 | chip->ops.ooboffs = chip->badblockpos & ~0x01; | |
ac7eb8a3 | 437 | |
cfa460ad | 438 | ret = nand_do_write_oob(mtd, ofs, &chip->ops); |
c45912d8 | 439 | nand_release_device(mtd); |
cfa460ad WJ |
440 | } |
441 | if (!ret) | |
442 | mtd->ecc_stats.badblocks++; | |
c45912d8 | 443 | |
cfa460ad | 444 | return ret; |
932394ac WD |
445 | } |
446 | ||
ac7eb8a3 | 447 | /** |
932394ac WD |
448 | * nand_check_wp - [GENERIC] check if the chip is write protected |
449 | * @mtd: MTD device structure | |
ac7eb8a3 | 450 | * Check, if the device is write protected |
932394ac | 451 | * |
ac7eb8a3 | 452 | * The function expects, that the device is already selected |
932394ac | 453 | */ |
cfa460ad | 454 | static int nand_check_wp(struct mtd_info *mtd) |
932394ac | 455 | { |
cfa460ad | 456 | struct nand_chip *chip = mtd->priv; |
932394ac | 457 | /* Check the WP bit */ |
cfa460ad WJ |
458 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
459 | return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; | |
932394ac | 460 | } |