2 * drivers/mtd/nand/nand_util.c
4 * Copyright (C) 2006 by Weiss-Electronic GmbH.
7 * @author: Guido Classen <clagix@gmail.com>
8 * @descr: NAND Flash support
9 * @references: borrowed heavily from Linux mtd-utils code:
10 * flash_eraseall.c by Arcom Control System Ltd
11 * nandwrite.c by Steven J. Hill (sjhill@realitydiluted.com)
12 * and Thomas Gleixner (tglx@linutronix.de)
14 * See file CREDITS for list of people who contributed to this
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License version
19 * 2 as published by the Free Software Foundation.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 * Copyright 2010 Freescale Semiconductor
32 * The portions of this file whose copyright is held by Freescale and which
33 * are not considered a derived work of GPL v2-only code may be distributed
34 * and/or modified under the terms of the GNU General Public License as
35 * published by the Free Software Foundation; either version 2 of the
36 * License, or (at your option) any later version.
45 #include <asm/errno.h>
46 #include <linux/mtd/mtd.h>
48 #include <jffs2/jffs2.h>
50 typedef struct erase_info erase_info_t
;
51 typedef struct mtd_info mtd_info_t
;
53 /* support only for native endian JFFS2 */
54 #define cpu_to_je16(x) (x)
55 #define cpu_to_je32(x) (x)
57 /*****************************************************************************/
58 static int nand_block_bad_scrub(struct mtd_info
*mtd
, loff_t ofs
, int getchip
)
64 * nand_erase_opts: - erase NAND flash with support for various options
67 * @param meminfo NAND device to erase
68 * @param opts options, @see struct nand_erase_options
69 * @return 0 in case of success
71 * This code is ported from flash_eraseall.c from Linux mtd utils by
72 * Arcom Control System Ltd.
74 int nand_erase_opts(nand_info_t
*meminfo
, const nand_erase_options_t
*opts
)
76 struct jffs2_unknown_node cleanmarker
;
78 unsigned long erase_length
, erased_length
; /* in blocks */
81 int percent_complete
= -1;
82 int (*nand_block_bad_old
)(struct mtd_info
*, loff_t
, int) = NULL
;
83 const char *mtd_device
= meminfo
->name
;
84 struct mtd_oob_ops oob_opts
;
85 struct nand_chip
*chip
= meminfo
->priv
;
87 if ((opts
->offset
& (meminfo
->writesize
- 1)) != 0) {
88 printf("Attempt to erase non page aligned data\n");
92 memset(&erase
, 0, sizeof(erase
));
93 memset(&oob_opts
, 0, sizeof(oob_opts
));
96 erase
.len
= meminfo
->erasesize
;
97 erase
.addr
= opts
->offset
;
98 erase_length
= lldiv(opts
->length
+ meminfo
->erasesize
- 1,
101 cleanmarker
.magic
= cpu_to_je16 (JFFS2_MAGIC_BITMASK
);
102 cleanmarker
.nodetype
= cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER
);
103 cleanmarker
.totlen
= cpu_to_je32(8);
105 /* scrub option allows to erase badblock. To prevent internal
106 * check from erase() method, set block check method to dummy
107 * and disable bad block table while erasing.
110 struct nand_chip
*priv_nand
= meminfo
->priv
;
112 nand_block_bad_old
= priv_nand
->block_bad
;
113 priv_nand
->block_bad
= nand_block_bad_scrub
;
114 /* we don't need the bad block table anymore...
115 * after scrub, there are no bad blocks left!
117 if (priv_nand
->bbt
) {
118 kfree(priv_nand
->bbt
);
120 priv_nand
->bbt
= NULL
;
123 for (erased_length
= 0;
124 erased_length
< erase_length
;
125 erase
.addr
+= meminfo
->erasesize
) {
129 if (!opts
->scrub
&& bbtest
) {
130 int ret
= meminfo
->block_isbad(meminfo
, erase
.addr
);
133 printf("\rSkipping bad block at "
143 } else if (ret
< 0) {
144 printf("\n%s: MTD get bad block failed: %d\n",
153 result
= meminfo
->erase(meminfo
, &erase
);
155 printf("\n%s: MTD Erase failure: %d\n",
160 /* format for JFFS2 ? */
161 if (opts
->jffs2
&& chip
->ecc
.layout
->oobavail
>= 8) {
162 chip
->ops
.ooblen
= 8;
163 chip
->ops
.datbuf
= NULL
;
164 chip
->ops
.oobbuf
= (uint8_t *)&cleanmarker
;
165 chip
->ops
.ooboffs
= 0;
166 chip
->ops
.mode
= MTD_OOB_AUTO
;
168 result
= meminfo
->write_oob(meminfo
,
172 printf("\n%s: MTD writeoob failure: %d\n",
179 unsigned long long n
= erased_length
* 100ULL;
182 do_div(n
, erase_length
);
185 /* output progress message only at whole percent
186 * steps to reduce the number of messages printed
187 * on (slow) serial consoles
189 if (percent
!= percent_complete
) {
190 percent_complete
= percent
;
192 printf("\rErasing at 0x%llx -- %3d%% complete.",
193 erase
.addr
, percent
);
195 if (opts
->jffs2
&& result
== 0)
196 printf(" Cleanmarker written at 0x%llx.",
204 if (nand_block_bad_old
) {
205 struct nand_chip
*priv_nand
= meminfo
->priv
;
207 priv_nand
->block_bad
= nand_block_bad_old
;
208 priv_nand
->scan_bbt(meminfo
);
214 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
216 /******************************************************************************
217 * Support for locking / unlocking operations of some NAND devices
218 *****************************************************************************/
220 #define NAND_CMD_LOCK 0x2a
221 #define NAND_CMD_LOCK_TIGHT 0x2c
222 #define NAND_CMD_UNLOCK1 0x23
223 #define NAND_CMD_UNLOCK2 0x24
224 #define NAND_CMD_LOCK_STATUS 0x7a
227 * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT
230 * @param mtd nand mtd instance
231 * @param tight bring device in lock tight mode
233 * @return 0 on success, -1 in case of error
235 * The lock / lock-tight command only applies to the whole chip. To get some
236 * parts of the chip lock and others unlocked use the following sequence:
238 * - Lock all pages of the chip using nand_lock(mtd, 0) (or the lockpre pin)
239 * - Call nand_unlock() once for each consecutive area to be unlocked
240 * - If desired: Bring the chip to the lock-tight state using nand_lock(mtd, 1)
242 * If the device is in lock-tight state software can't change the
243 * current active lock/unlock state of all pages. nand_lock() / nand_unlock()
244 * calls will fail. It is only posible to leave lock-tight state by
245 * an hardware signal (low pulse on _WP pin) or by power down.
247 int nand_lock(struct mtd_info
*mtd
, int tight
)
251 struct nand_chip
*chip
= mtd
->priv
;
253 /* select the NAND device */
254 chip
->select_chip(mtd
, 0);
257 (tight
? NAND_CMD_LOCK_TIGHT
: NAND_CMD_LOCK
),
260 /* call wait ready function */
261 status
= chip
->waitfunc(mtd
, chip
);
263 /* see if device thinks it succeeded */
268 /* de-select the NAND device */
269 chip
->select_chip(mtd
, -1);
274 * nand_get_lock_status: - query current lock state from one page of NAND
277 * @param mtd nand mtd instance
278 * @param offset page address to query (muss be page aligned!)
280 * @return -1 in case of error
282 * bitfield with the following combinations:
283 * NAND_LOCK_STATUS_TIGHT: page in tight state
284 * NAND_LOCK_STATUS_LOCK: page locked
285 * NAND_LOCK_STATUS_UNLOCK: page unlocked
288 int nand_get_lock_status(struct mtd_info
*mtd
, loff_t offset
)
293 struct nand_chip
*chip
= mtd
->priv
;
295 /* select the NAND device */
296 chipnr
= (int)(offset
>> chip
->chip_shift
);
297 chip
->select_chip(mtd
, chipnr
);
300 if ((offset
& (mtd
->writesize
- 1)) != 0) {
301 printf ("nand_get_lock_status: "
302 "Start address must be beginning of "
308 /* check the Lock Status */
309 page
= (int)(offset
>> chip
->page_shift
);
310 chip
->cmdfunc(mtd
, NAND_CMD_LOCK_STATUS
, -1, page
& chip
->pagemask
);
312 ret
= chip
->read_byte(mtd
) & (NAND_LOCK_STATUS_TIGHT
313 | NAND_LOCK_STATUS_LOCK
314 | NAND_LOCK_STATUS_UNLOCK
);
317 /* de-select the NAND device */
318 chip
->select_chip(mtd
, -1);
323 * nand_unlock: - Unlock area of NAND pages
324 * only one consecutive area can be unlocked at one time!
326 * @param mtd nand mtd instance
327 * @param start start byte address
328 * @param length number of bytes to unlock (must be a multiple of
329 * page size nand->writesize)
331 * @return 0 on success, -1 in case of error
333 int nand_unlock(struct mtd_info
*mtd
, ulong start
, ulong length
)
339 struct nand_chip
*chip
= mtd
->priv
;
340 printf ("nand_unlock: start: %08x, length: %d!\n",
341 (int)start
, (int)length
);
343 /* select the NAND device */
344 chipnr
= (int)(start
>> chip
->chip_shift
);
345 chip
->select_chip(mtd
, chipnr
);
347 /* check the WP bit */
348 chip
->cmdfunc(mtd
, NAND_CMD_STATUS
, -1, -1);
349 if (!(chip
->read_byte(mtd
) & NAND_STATUS_WP
)) {
350 printf ("nand_unlock: Device is write protected!\n");
355 if ((start
& (mtd
->erasesize
- 1)) != 0) {
356 printf ("nand_unlock: Start address must be beginning of "
362 if (length
== 0 || (length
& (mtd
->erasesize
- 1)) != 0) {
363 printf ("nand_unlock: Length must be a multiple of nand block "
364 "size %08x!\n", mtd
->erasesize
);
370 * Set length so that the last address is set to the
371 * starting address of the last block
373 length
-= mtd
->erasesize
;
375 /* submit address of first page to unlock */
376 page
= (int)(start
>> chip
->page_shift
);
377 chip
->cmdfunc(mtd
, NAND_CMD_UNLOCK1
, -1, page
& chip
->pagemask
);
379 /* submit ADDRESS of LAST page to unlock */
380 page
+= (int)(length
>> chip
->page_shift
);
381 chip
->cmdfunc(mtd
, NAND_CMD_UNLOCK2
, -1, page
& chip
->pagemask
);
383 /* call wait ready function */
384 status
= chip
->waitfunc(mtd
, chip
);
385 /* see if device thinks it succeeded */
387 /* there was an error */
393 /* de-select the NAND device */
394 chip
->select_chip(mtd
, -1);
402 * Check if there are any bad blocks, and whether length including bad
403 * blocks fits into device
405 * @param nand NAND device
406 * @param offset offset in flash
407 * @param length image length
408 * @return 0 if the image fits and there are no bad blocks
409 * 1 if the image fits, but there are bad blocks
410 * -1 if the image does not fit
412 static int check_skip_len(nand_info_t
*nand
, loff_t offset
, size_t length
)
414 size_t len_excl_bad
= 0;
417 while (len_excl_bad
< length
) {
418 size_t block_len
, block_off
;
421 if (offset
>= nand
->size
)
424 block_start
= offset
& ~(loff_t
)(nand
->erasesize
- 1);
425 block_off
= offset
& (nand
->erasesize
- 1);
426 block_len
= nand
->erasesize
- block_off
;
428 if (!nand_block_isbad(nand
, block_start
))
429 len_excl_bad
+= block_len
;
440 * nand_write_skip_bad:
442 * Write image to NAND flash.
443 * Blocks that are marked bad are skipped and the is written to the next
444 * block instead as long as the image is short enough to fit even after
445 * skipping the bad blocks.
447 * @param nand NAND device
448 * @param offset offset in flash
449 * @param length buffer length
450 * @param buffer buffer to read from
451 * @param withoob whether write with yaffs format
452 * @return 0 in case of success
454 int nand_write_skip_bad(nand_info_t
*nand
, loff_t offset
, size_t *length
,
455 u_char
*buffer
, int withoob
)
457 int rval
= 0, blocksize
;
458 size_t left_to_write
= *length
;
459 u_char
*p_buffer
= buffer
;
462 #ifdef CONFIG_CMD_NAND_YAFFS
465 pages
= nand
->erasesize
/ nand
->writesize
;
466 blocksize
= (pages
* nand
->oobsize
) + nand
->erasesize
;
467 if (*length
% (nand
->writesize
+ nand
->oobsize
)) {
468 printf ("Attempt to write incomplete page"
475 blocksize
= nand
->erasesize
;
479 * nand_write() handles unaligned, partial page writes.
481 * We allow length to be unaligned, for convenience in
482 * using the $filesize variable.
484 * However, starting at an unaligned offset makes the
485 * semantics of bad block skipping ambiguous (really,
486 * you should only start a block skipping access at a
487 * partition boundary). So don't try to handle that.
489 if ((offset
& (nand
->writesize
- 1)) != 0) {
490 printf ("Attempt to write non page aligned data\n");
495 need_skip
= check_skip_len(nand
, offset
, *length
);
497 printf ("Attempt to write outside the flash area\n");
503 rval
= nand_write (nand
, offset
, length
, buffer
);
508 printf ("NAND write to offset %llx failed %d\n",
513 while (left_to_write
> 0) {
514 size_t block_offset
= offset
& (nand
->erasesize
- 1);
519 if (nand_block_isbad (nand
, offset
& ~(nand
->erasesize
- 1))) {
520 printf ("Skip bad block 0x%08llx\n",
521 offset
& ~(nand
->erasesize
- 1));
522 offset
+= nand
->erasesize
- block_offset
;
526 if (left_to_write
< (blocksize
- block_offset
))
527 write_size
= left_to_write
;
529 write_size
= blocksize
- block_offset
;
531 #ifdef CONFIG_CMD_NAND_YAFFS
534 size_t pagesize
= nand
->writesize
;
535 size_t pagesize_oob
= pagesize
+ nand
->oobsize
;
536 struct mtd_oob_ops ops
;
539 ops
.ooblen
= nand
->oobsize
;
540 ops
.mode
= MTD_OOB_AUTO
;
543 pages
= write_size
/ pagesize_oob
;
544 for (page
= 0; page
< pages
; page
++) {
547 ops
.datbuf
= p_buffer
;
548 ops
.oobbuf
= ops
.datbuf
+ pagesize
;
550 rval
= nand
->write_oob(nand
, offset
, &ops
);
555 p_buffer
+= pagesize_oob
;
561 rval
= nand_write (nand
, offset
, &write_size
, p_buffer
);
562 offset
+= write_size
;
563 p_buffer
+= write_size
;
567 printf ("NAND write to offset %llx failed %d\n",
569 *length
-= left_to_write
;
573 left_to_write
-= write_size
;
580 * nand_read_skip_bad:
582 * Read image from NAND flash.
583 * Blocks that are marked bad are skipped and the next block is readen
584 * instead as long as the image is short enough to fit even after skipping the
587 * @param nand NAND device
588 * @param offset offset in flash
589 * @param length buffer length, on return holds remaining bytes to read
590 * @param buffer buffer to write to
591 * @return 0 in case of success
593 int nand_read_skip_bad(nand_info_t
*nand
, loff_t offset
, size_t *length
,
597 size_t left_to_read
= *length
;
598 u_char
*p_buffer
= buffer
;
601 if ((offset
& (nand
->writesize
- 1)) != 0) {
602 printf ("Attempt to read non page aligned data\n");
607 need_skip
= check_skip_len(nand
, offset
, *length
);
609 printf ("Attempt to read outside the flash area\n");
615 rval
= nand_read (nand
, offset
, length
, buffer
);
616 if (!rval
|| rval
== -EUCLEAN
)
620 printf ("NAND read from offset %llx failed %d\n",
625 while (left_to_read
> 0) {
626 size_t block_offset
= offset
& (nand
->erasesize
- 1);
631 if (nand_block_isbad (nand
, offset
& ~(nand
->erasesize
- 1))) {
632 printf ("Skipping bad block 0x%08llx\n",
633 offset
& ~(nand
->erasesize
- 1));
634 offset
+= nand
->erasesize
- block_offset
;
638 if (left_to_read
< (nand
->erasesize
- block_offset
))
639 read_length
= left_to_read
;
641 read_length
= nand
->erasesize
- block_offset
;
643 rval
= nand_read (nand
, offset
, &read_length
, p_buffer
);
644 if (rval
&& rval
!= -EUCLEAN
) {
645 printf ("NAND read from offset %llx failed %d\n",
647 *length
-= left_to_read
;
651 left_to_read
-= read_length
;
652 offset
+= read_length
;
653 p_buffer
+= read_length
;