]>
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. | |
ac7eb8a3 | 7 | * |
932394ac | 8 | * Additional technical information is available on |
c45912d8 | 9 | * http://www.linux-mtd.infradead.org/doc/nand.html |
ac7eb8a3 | 10 | * |
932394ac | 11 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
cfa460ad | 12 | * 2002-2006 Thomas Gleixner (tglx@linutronix.de) |
932394ac | 13 | * |
cfa460ad | 14 | * Credits: |
ac7eb8a3 WD |
15 | * David Woodhouse for adding multichip support |
16 | * | |
932394ac WD |
17 | * Aleph One Ltd. and Toby Churchill Ltd. for supporting the |
18 | * rework for 2K page size chips | |
19 | * | |
cfa460ad | 20 | * TODO: |
932394ac WD |
21 | * Enable cached programming for 2k page size chips |
22 | * Check, if mtd->ecctype should be set to MTD_ECC_HW | |
dfe64e2c | 23 | * if we have HW ECC support. |
c45912d8 | 24 | * BBT table is not serialized, has to be fixed |
932394ac | 25 | * |
932394ac WD |
26 | * This program is free software; you can redistribute it and/or modify |
27 | * it under the terms of the GNU General Public License version 2 as | |
28 | * published by the Free Software Foundation. | |
29 | * | |
30 | */ | |
31 | ||
ff94bc40 HS |
32 | #define __UBOOT__ |
33 | #ifndef __UBOOT__ | |
34 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
cfa460ad | 35 | |
ff94bc40 HS |
36 | #include <linux/module.h> |
37 | #include <linux/delay.h> | |
38 | #include <linux/errno.h> | |
39 | #include <linux/err.h> | |
40 | #include <linux/sched.h> | |
41 | #include <linux/slab.h> | |
42 | #include <linux/types.h> | |
43 | #include <linux/mtd/mtd.h> | |
44 | #include <linux/mtd/nand.h> | |
45 | #include <linux/mtd/nand_ecc.h> | |
46 | #include <linux/mtd/nand_bch.h> | |
47 | #include <linux/interrupt.h> | |
48 | #include <linux/bitops.h> | |
49 | #include <linux/leds.h> | |
50 | #include <linux/io.h> | |
51 | #include <linux/mtd/partitions.h> | |
52 | #else | |
53 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
54 | #include <common.h> | |
932394ac WD |
55 | #include <malloc.h> |
56 | #include <watchdog.h> | |
cfa460ad | 57 | #include <linux/err.h> |
7b15e2bb | 58 | #include <linux/compat.h> |
932394ac WD |
59 | #include <linux/mtd/mtd.h> |
60 | #include <linux/mtd/nand.h> | |
61 | #include <linux/mtd/nand_ecc.h> | |
4c6de856 | 62 | #include <linux/mtd/nand_bch.h> |
10bb62d8 SR |
63 | #ifdef CONFIG_MTD_PARTITIONS |
64 | #include <linux/mtd/partitions.h> | |
65 | #endif | |
932394ac WD |
66 | #include <asm/io.h> |
67 | #include <asm/errno.h> | |
68 | ||
8da60128 PT |
69 | /* |
70 | * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting | |
71 | * a flash. NAND flash is initialized prior to interrupts so standard timers | |
72 | * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value | |
73 | * which is greater than (max NAND reset time / NAND status read time). | |
74 | * A conservative default of 200000 (500 us / 25 ns) is used as a default. | |
75 | */ | |
76 | #ifndef CONFIG_SYS_NAND_RESET_CNT | |
77 | #define CONFIG_SYS_NAND_RESET_CNT 200000 | |
78 | #endif | |
79 | ||
ff94bc40 HS |
80 | static bool is_module_text_address(unsigned long addr) {return 0;} |
81 | #endif | |
82 | ||
932394ac | 83 | /* Define default oob placement schemes for large and small page devices */ |
cfa460ad | 84 | static struct nand_ecclayout nand_oob_8 = { |
932394ac WD |
85 | .eccbytes = 3, |
86 | .eccpos = {0, 1, 2}, | |
cfa460ad WJ |
87 | .oobfree = { |
88 | {.offset = 3, | |
89 | .length = 2}, | |
90 | {.offset = 6, | |
90e3f395 | 91 | .length = 2} } |
932394ac WD |
92 | }; |
93 | ||
cfa460ad | 94 | static struct nand_ecclayout nand_oob_16 = { |
932394ac WD |
95 | .eccbytes = 6, |
96 | .eccpos = {0, 1, 2, 3, 6, 7}, | |
cfa460ad WJ |
97 | .oobfree = { |
98 | {.offset = 8, | |
90e3f395 | 99 | . length = 8} } |
932394ac WD |
100 | }; |
101 | ||
cfa460ad | 102 | static struct nand_ecclayout nand_oob_64 = { |
932394ac WD |
103 | .eccbytes = 24, |
104 | .eccpos = { | |
cfa460ad WJ |
105 | 40, 41, 42, 43, 44, 45, 46, 47, |
106 | 48, 49, 50, 51, 52, 53, 54, 55, | |
107 | 56, 57, 58, 59, 60, 61, 62, 63}, | |
108 | .oobfree = { | |
109 | {.offset = 2, | |
90e3f395 | 110 | .length = 38} } |
932394ac WD |
111 | }; |
112 | ||
cfa460ad | 113 | static struct nand_ecclayout nand_oob_128 = { |
248ae5cf SP |
114 | .eccbytes = 48, |
115 | .eccpos = { | |
90e3f395 CH |
116 | 80, 81, 82, 83, 84, 85, 86, 87, |
117 | 88, 89, 90, 91, 92, 93, 94, 95, | |
118 | 96, 97, 98, 99, 100, 101, 102, 103, | |
cfa460ad WJ |
119 | 104, 105, 106, 107, 108, 109, 110, 111, |
120 | 112, 113, 114, 115, 116, 117, 118, 119, | |
121 | 120, 121, 122, 123, 124, 125, 126, 127}, | |
122 | .oobfree = { | |
123 | {.offset = 2, | |
90e3f395 | 124 | .length = 78} } |
932394ac WD |
125 | }; |
126 | ||
ff94bc40 | 127 | static int nand_get_device(struct mtd_info *mtd, int new_state); |
cfa460ad WJ |
128 | |
129 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |
130 | struct mtd_oob_ops *ops); | |
131 | ||
ff94bc40 HS |
132 | /* |
133 | * For devices which display every fart in the system on a separate LED. Is | |
134 | * compiled away when LED support is disabled. | |
135 | */ | |
136 | DEFINE_LED_TRIGGER(nand_led_trigger); | |
248ae5cf | 137 | |
2a8e0fc8 CH |
138 | static int check_offs_len(struct mtd_info *mtd, |
139 | loff_t ofs, uint64_t len) | |
140 | { | |
141 | struct nand_chip *chip = mtd->priv; | |
142 | int ret = 0; | |
143 | ||
144 | /* Start address must align on block boundary */ | |
ff94bc40 HS |
145 | if (ofs & ((1ULL << chip->phys_erase_shift) - 1)) { |
146 | pr_debug("%s: unaligned address\n", __func__); | |
2a8e0fc8 CH |
147 | ret = -EINVAL; |
148 | } | |
149 | ||
150 | /* Length must align on block boundary */ | |
ff94bc40 HS |
151 | if (len & ((1ULL << chip->phys_erase_shift) - 1)) { |
152 | pr_debug("%s: length not block aligned\n", __func__); | |
2a8e0fc8 CH |
153 | ret = -EINVAL; |
154 | } | |
155 | ||
2a8e0fc8 CH |
156 | return ret; |
157 | } | |
158 | ||
932394ac WD |
159 | /** |
160 | * nand_release_device - [GENERIC] release chip | |
dfe64e2c | 161 | * @mtd: MTD device structure |
ac7eb8a3 | 162 | * |
ff94bc40 | 163 | * Release chip lock and wake up anyone waiting on the device. |
932394ac | 164 | */ |
90e3f395 | 165 | static void nand_release_device(struct mtd_info *mtd) |
8e9655f8 | 166 | { |
2a8e0fc8 CH |
167 | struct nand_chip *chip = mtd->priv; |
168 | ||
ff94bc40 HS |
169 | #ifndef __UBOOT__ |
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); | |
176 | #else | |
2a8e0fc8 CH |
177 | /* De-select the NAND device */ |
178 | chip->select_chip(mtd, -1); | |
ff94bc40 | 179 | #endif |
8e9655f8 | 180 | } |
932394ac WD |
181 | |
182 | /** | |
183 | * nand_read_byte - [DEFAULT] read one byte from the chip | |
dfe64e2c | 184 | * @mtd: MTD device structure |
932394ac | 185 | * |
ff94bc40 | 186 | * Default read function for 8bit buswidth |
932394ac | 187 | */ |
ff94bc40 HS |
188 | #ifndef __UBOOT__ |
189 | static uint8_t nand_read_byte(struct mtd_info *mtd) | |
190 | #else | |
82645f81 | 191 | uint8_t nand_read_byte(struct mtd_info *mtd) |
ff94bc40 | 192 | #endif |
932394ac | 193 | { |
cfa460ad WJ |
194 | struct nand_chip *chip = mtd->priv; |
195 | return readb(chip->IO_ADDR_R); | |
932394ac WD |
196 | } |
197 | ||
198 | /** | |
ff94bc40 | 199 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip |
dfe64e2c SL |
200 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip |
201 | * @mtd: MTD device structure | |
202 | * | |
203 | * Default read function for 16bit buswidth with endianness conversion. | |
932394ac | 204 | * |
932394ac | 205 | */ |
cfa460ad | 206 | static uint8_t nand_read_byte16(struct mtd_info *mtd) |
932394ac | 207 | { |
cfa460ad WJ |
208 | struct nand_chip *chip = mtd->priv; |
209 | return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); | |
932394ac WD |
210 | } |
211 | ||
212 | /** | |
213 | * nand_read_word - [DEFAULT] read one word from the chip | |
dfe64e2c | 214 | * @mtd: MTD device structure |
932394ac | 215 | * |
dfe64e2c | 216 | * Default read function for 16bit buswidth without endianness conversion. |
932394ac WD |
217 | */ |
218 | static u16 nand_read_word(struct mtd_info *mtd) | |
219 | { | |
cfa460ad WJ |
220 | struct nand_chip *chip = mtd->priv; |
221 | return readw(chip->IO_ADDR_R); | |
932394ac WD |
222 | } |
223 | ||
224 | /** | |
225 | * nand_select_chip - [DEFAULT] control CE line | |
dfe64e2c SL |
226 | * @mtd: MTD device structure |
227 | * @chipnr: chipnumber to select, -1 for deselect | |
932394ac WD |
228 | * |
229 | * Default select function for 1 chip devices. | |
230 | */ | |
cfa460ad | 231 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) |
932394ac | 232 | { |
cfa460ad WJ |
233 | struct nand_chip *chip = mtd->priv; |
234 | ||
235 | switch (chipnr) { | |
932394ac | 236 | case -1: |
cfa460ad | 237 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); |
932394ac WD |
238 | break; |
239 | case 0: | |
932394ac WD |
240 | break; |
241 | ||
242 | default: | |
243 | BUG(); | |
244 | } | |
245 | } | |
246 | ||
ff94bc40 HS |
247 | /** |
248 | * nand_write_byte - [DEFAULT] write single byte to chip | |
249 | * @mtd: MTD device structure | |
250 | * @byte: value to write | |
251 | * | |
252 | * Default function to write a byte to I/O[7:0] | |
253 | */ | |
254 | static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) | |
255 | { | |
256 | struct nand_chip *chip = mtd->priv; | |
257 | ||
258 | chip->write_buf(mtd, &byte, 1); | |
259 | } | |
260 | ||
261 | /** | |
262 | * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16 | |
263 | * @mtd: MTD device structure | |
264 | * @byte: value to write | |
265 | * | |
266 | * Default function to write a byte to I/O[7:0] on a 16-bit wide chip. | |
267 | */ | |
268 | static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) | |
269 | { | |
270 | struct nand_chip *chip = mtd->priv; | |
271 | uint16_t word = byte; | |
272 | ||
273 | /* | |
274 | * It's not entirely clear what should happen to I/O[15:8] when writing | |
275 | * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads: | |
276 | * | |
277 | * When the host supports a 16-bit bus width, only data is | |
278 | * transferred at the 16-bit width. All address and command line | |
279 | * transfers shall use only the lower 8-bits of the data bus. During | |
280 | * command transfers, the host may place any value on the upper | |
281 | * 8-bits of the data bus. During address transfers, the host shall | |
282 | * set the upper 8-bits of the data bus to 00h. | |
283 | * | |
284 | * One user of the write_byte callback is nand_onfi_set_features. The | |
285 | * four parameters are specified to be written to I/O[7:0], but this is | |
286 | * neither an address nor a command transfer. Let's assume a 0 on the | |
287 | * upper I/O lines is OK. | |
288 | */ | |
289 | chip->write_buf(mtd, (uint8_t *)&word, 2); | |
290 | } | |
291 | ||
292 | #if defined(__UBOOT__) && !defined(CONFIG_BLACKFIN) | |
293 | static void iowrite8_rep(void *addr, const uint8_t *buf, int len) | |
294 | { | |
295 | int i; | |
296 | ||
297 | for (i = 0; i < len; i++) | |
298 | writeb(buf[i], addr); | |
299 | } | |
300 | static void ioread8_rep(void *addr, uint8_t *buf, int len) | |
301 | { | |
302 | int i; | |
303 | ||
304 | for (i = 0; i < len; i++) | |
305 | buf[i] = readb(addr); | |
306 | } | |
307 | ||
308 | static void ioread16_rep(void *addr, void *buf, int len) | |
309 | { | |
310 | int i; | |
311 | u16 *p = (u16 *) buf; | |
312 | len >>= 1; | |
313 | ||
314 | for (i = 0; i < len; i++) | |
315 | p[i] = readw(addr); | |
316 | } | |
317 | ||
318 | static void iowrite16_rep(void *addr, void *buf, int len) | |
319 | { | |
320 | int i; | |
321 | u16 *p = (u16 *) buf; | |
322 | len >>= 1; | |
323 | ||
324 | for (i = 0; i < len; i++) | |
325 | writew(p[i], addr); | |
326 | } | |
327 | #endif | |
328 | ||
932394ac WD |
329 | /** |
330 | * nand_write_buf - [DEFAULT] write buffer to chip | |
dfe64e2c SL |
331 | * @mtd: MTD device structure |
332 | * @buf: data buffer | |
333 | * @len: number of bytes to write | |
932394ac | 334 | * |
dfe64e2c | 335 | * Default write function for 8bit buswidth. |
932394ac | 336 | */ |
ff94bc40 HS |
337 | #ifndef __UBOOT__ |
338 | static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |
339 | #else | |
82645f81 | 340 | void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
ff94bc40 | 341 | #endif |
932394ac | 342 | { |
cfa460ad | 343 | struct nand_chip *chip = mtd->priv; |
932394ac | 344 | |
ff94bc40 | 345 | iowrite8_rep(chip->IO_ADDR_W, buf, len); |
932394ac WD |
346 | } |
347 | ||
348 | /** | |
ac7eb8a3 | 349 | * nand_read_buf - [DEFAULT] read chip data into buffer |
dfe64e2c SL |
350 | * @mtd: MTD device structure |
351 | * @buf: buffer to store date | |
352 | * @len: number of bytes to read | |
932394ac | 353 | * |
dfe64e2c | 354 | * Default read function for 8bit buswidth. |
932394ac | 355 | */ |
ff94bc40 HS |
356 | #ifndef __UBOOT__ |
357 | static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |
358 | #else | |
12c2f1ee | 359 | void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
ff94bc40 | 360 | #endif |
932394ac | 361 | { |
cfa460ad | 362 | struct nand_chip *chip = mtd->priv; |
932394ac | 363 | |
ff94bc40 | 364 | ioread8_rep(chip->IO_ADDR_R, buf, len); |
932394ac WD |
365 | } |
366 | ||
ff94bc40 HS |
367 | #ifdef __UBOOT__ |
368 | #if defined(CONFIG_MTD_NAND_VERIFY_WRITE) | |
932394ac | 369 | /** |
ac7eb8a3 | 370 | * nand_verify_buf - [DEFAULT] Verify chip data against buffer |
dfe64e2c SL |
371 | * @mtd: MTD device structure |
372 | * @buf: buffer containing the data to compare | |
373 | * @len: number of bytes to compare | |
932394ac | 374 | * |
dfe64e2c | 375 | * Default verify function for 8bit buswidth. |
932394ac | 376 | */ |
cfa460ad | 377 | static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
378 | { |
379 | int i; | |
cfa460ad | 380 | struct nand_chip *chip = mtd->priv; |
932394ac | 381 | |
cfa460ad WJ |
382 | for (i = 0; i < len; i++) |
383 | if (buf[i] != readb(chip->IO_ADDR_R)) | |
932394ac | 384 | return -EFAULT; |
932394ac WD |
385 | return 0; |
386 | } | |
387 | ||
388 | /** | |
ff94bc40 | 389 | * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer |
dfe64e2c | 390 | * @mtd: MTD device structure |
ff94bc40 HS |
391 | * @buf: buffer containing the data to compare |
392 | * @len: number of bytes to compare | |
932394ac | 393 | * |
ff94bc40 | 394 | * Default verify function for 16bit buswidth. |
932394ac | 395 | */ |
ff94bc40 | 396 | static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
932394ac WD |
397 | { |
398 | int i; | |
cfa460ad | 399 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
400 | u16 *p = (u16 *) buf; |
401 | len >>= 1; | |
ac7eb8a3 | 402 | |
cfa460ad | 403 | for (i = 0; i < len; i++) |
ff94bc40 HS |
404 | if (p[i] != readw(chip->IO_ADDR_R)) |
405 | return -EFAULT; | |
ac7eb8a3 | 406 | |
ff94bc40 | 407 | return 0; |
932394ac | 408 | } |
ff94bc40 HS |
409 | #endif |
410 | #endif | |
932394ac WD |
411 | |
412 | /** | |
ff94bc40 | 413 | * nand_write_buf16 - [DEFAULT] write buffer to chip |
dfe64e2c | 414 | * @mtd: MTD device structure |
ff94bc40 HS |
415 | * @buf: data buffer |
416 | * @len: number of bytes to write | |
932394ac | 417 | * |
ff94bc40 | 418 | * Default write function for 16bit buswidth. |
932394ac | 419 | */ |
ff94bc40 HS |
420 | #ifndef __UBOOT__ |
421 | static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | |
422 | #else | |
423 | void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | |
424 | #endif | |
932394ac | 425 | { |
cfa460ad | 426 | struct nand_chip *chip = mtd->priv; |
932394ac | 427 | u16 *p = (u16 *) buf; |
932394ac | 428 | |
ff94bc40 | 429 | iowrite16_rep(chip->IO_ADDR_W, p, len >> 1); |
932394ac WD |
430 | } |
431 | ||
432 | /** | |
ff94bc40 | 433 | * nand_read_buf16 - [DEFAULT] read chip data into buffer |
dfe64e2c | 434 | * @mtd: MTD device structure |
ff94bc40 HS |
435 | * @buf: buffer to store date |
436 | * @len: number of bytes to read | |
932394ac | 437 | * |
ff94bc40 | 438 | * Default read function for 16bit buswidth. |
932394ac | 439 | */ |
ff94bc40 HS |
440 | #ifndef __UBOOT__ |
441 | static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) | |
442 | #else | |
443 | void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) | |
444 | #endif | |
932394ac | 445 | { |
cfa460ad | 446 | struct nand_chip *chip = mtd->priv; |
932394ac | 447 | u16 *p = (u16 *) buf; |
932394ac | 448 | |
ff94bc40 | 449 | ioread16_rep(chip->IO_ADDR_R, p, len >> 1); |
932394ac WD |
450 | } |
451 | ||
452 | /** | |
453 | * nand_block_bad - [DEFAULT] Read bad block marker from the chip | |
dfe64e2c SL |
454 | * @mtd: MTD device structure |
455 | * @ofs: offset from device start | |
456 | * @getchip: 0, if the chip is already selected | |
932394ac | 457 | * |
ac7eb8a3 | 458 | * Check, if the block is bad. |
932394ac WD |
459 | */ |
460 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |
461 | { | |
dfe64e2c | 462 | int page, chipnr, res = 0, i = 0; |
cfa460ad | 463 | struct nand_chip *chip = mtd->priv; |
932394ac WD |
464 | u16 bad; |
465 | ||
dfe64e2c | 466 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) |
2a8e0fc8 CH |
467 | ofs += mtd->erasesize - mtd->writesize; |
468 | ||
cfa460ad | 469 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; |
a7988659 | 470 | |
932394ac | 471 | if (getchip) { |
cfa460ad | 472 | chipnr = (int)(ofs >> chip->chip_shift); |
932394ac | 473 | |
ff94bc40 | 474 | nand_get_device(mtd, FL_READING); |
932394ac WD |
475 | |
476 | /* Select the NAND device */ | |
cfa460ad | 477 | chip->select_chip(mtd, chipnr); |
a7988659 | 478 | } |
932394ac | 479 | |
dfe64e2c SL |
480 | do { |
481 | if (chip->options & NAND_BUSWIDTH_16) { | |
482 | chip->cmdfunc(mtd, NAND_CMD_READOOB, | |
483 | chip->badblockpos & 0xFE, page); | |
484 | bad = cpu_to_le16(chip->read_word(mtd)); | |
485 | if (chip->badblockpos & 0x1) | |
486 | bad >>= 8; | |
487 | else | |
488 | bad &= 0xFF; | |
489 | } else { | |
490 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, | |
491 | page); | |
492 | bad = chip->read_byte(mtd); | |
493 | } | |
ac7eb8a3 | 494 | |
dfe64e2c SL |
495 | if (likely(chip->badblockbits == 8)) |
496 | res = bad != 0xFF; | |
497 | else | |
498 | res = hweight8(bad) < chip->badblockbits; | |
499 | ofs += mtd->writesize; | |
500 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; | |
501 | i++; | |
502 | } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); | |
2a8e0fc8 | 503 | |
ff94bc40 HS |
504 | if (getchip) { |
505 | chip->select_chip(mtd, -1); | |
932394ac | 506 | nand_release_device(mtd); |
ff94bc40 | 507 | } |
ac7eb8a3 | 508 | |
932394ac WD |
509 | return res; |
510 | } | |
511 | ||
512 | /** | |
ff94bc40 | 513 | * nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker |
dfe64e2c SL |
514 | * @mtd: MTD device structure |
515 | * @ofs: offset from device start | |
932394ac | 516 | * |
dfe64e2c | 517 | * This is the default implementation, which can be overridden by a hardware |
ff94bc40 HS |
518 | * specific driver. It provides the details for writing a bad block marker to a |
519 | * block. | |
520 | */ | |
521 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |
522 | { | |
523 | struct nand_chip *chip = mtd->priv; | |
524 | struct mtd_oob_ops ops; | |
525 | uint8_t buf[2] = { 0, 0 }; | |
526 | int ret = 0, res, i = 0; | |
527 | ||
528 | ops.datbuf = NULL; | |
529 | ops.oobbuf = buf; | |
530 | ops.ooboffs = chip->badblockpos; | |
531 | if (chip->options & NAND_BUSWIDTH_16) { | |
532 | ops.ooboffs &= ~0x01; | |
533 | ops.len = ops.ooblen = 2; | |
534 | } else { | |
535 | ops.len = ops.ooblen = 1; | |
536 | } | |
537 | ops.mode = MTD_OPS_PLACE_OOB; | |
538 | ||
539 | /* Write to first/last page(s) if necessary */ | |
540 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) | |
541 | ofs += mtd->erasesize - mtd->writesize; | |
542 | do { | |
543 | res = nand_do_write_oob(mtd, ofs, &ops); | |
544 | if (!ret) | |
545 | ret = res; | |
546 | ||
547 | i++; | |
548 | ofs += mtd->writesize; | |
549 | } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2); | |
550 | ||
551 | return ret; | |
552 | } | |
553 | ||
554 | /** | |
555 | * nand_block_markbad_lowlevel - mark a block bad | |
556 | * @mtd: MTD device structure | |
557 | * @ofs: offset from device start | |
558 | * | |
559 | * This function performs the generic NAND bad block marking steps (i.e., bad | |
560 | * block table(s) and/or marker(s)). We only allow the hardware driver to | |
561 | * specify how to write bad block markers to OOB (chip->block_markbad). | |
562 | * | |
563 | * We try operations in the following order: | |
dfe64e2c | 564 | * (1) erase the affected block, to allow OOB marker to be written cleanly |
ff94bc40 HS |
565 | * (2) write bad block marker to OOB area of affected block (unless flag |
566 | * NAND_BBT_NO_OOB_BBM is present) | |
567 | * (3) update the BBT | |
568 | * Note that we retain the first error encountered in (2) or (3), finish the | |
dfe64e2c | 569 | * procedures, and dump the error in the end. |
932394ac | 570 | */ |
ff94bc40 | 571 | static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) |
932394ac | 572 | { |
cfa460ad | 573 | struct nand_chip *chip = mtd->priv; |
ff94bc40 | 574 | int res, ret = 0; |
2a8e0fc8 | 575 | |
ff94bc40 | 576 | if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { |
dfe64e2c SL |
577 | struct erase_info einfo; |
578 | ||
579 | /* Attempt erase before marking OOB */ | |
580 | memset(&einfo, 0, sizeof(einfo)); | |
581 | einfo.mtd = mtd; | |
582 | einfo.addr = ofs; | |
ff94bc40 | 583 | einfo.len = 1ULL << chip->phys_erase_shift; |
dfe64e2c | 584 | nand_erase_nand(mtd, &einfo, 0); |
2a8e0fc8 | 585 | |
ff94bc40 HS |
586 | /* Write bad block marker to OOB */ |
587 | nand_get_device(mtd, FL_WRITING); | |
588 | ret = chip->block_markbad(mtd, ofs); | |
c45912d8 | 589 | nand_release_device(mtd); |
cfa460ad | 590 | } |
dfe64e2c | 591 | |
ff94bc40 HS |
592 | /* Mark block bad in BBT */ |
593 | if (chip->bbt) { | |
594 | res = nand_markbad_bbt(mtd, ofs); | |
dfe64e2c SL |
595 | if (!ret) |
596 | ret = res; | |
597 | } | |
598 | ||
cfa460ad WJ |
599 | if (!ret) |
600 | mtd->ecc_stats.badblocks++; | |
c45912d8 | 601 | |
cfa460ad | 602 | return ret; |
932394ac WD |
603 | } |
604 | ||
ac7eb8a3 | 605 | /** |
932394ac | 606 | * nand_check_wp - [GENERIC] check if the chip is write protected |
dfe64e2c | 607 | * @mtd: MTD device structure |
932394ac | 608 | * |
dfe64e2c SL |
609 | * Check, if the device is write protected. The function expects, that the |
610 | * device is already selected. | |
932394ac | 611 | */ |
cfa460ad | 612 | static int nand_check_wp(struct mtd_info *mtd) |
932394ac | 613 | { |
cfa460ad | 614 | struct nand_chip *chip = mtd->priv; |
2a8e0fc8 | 615 | |
dfe64e2c | 616 | /* Broken xD cards report WP despite being writable */ |
2a8e0fc8 CH |
617 | if (chip->options & NAND_BROKEN_XD) |
618 | return 0; | |
619 | ||
932394ac | 620 | /* Check the WP bit */ |
cfa460ad WJ |
621 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
622 | return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; | |
932394ac | 623 | } |