summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/cmd_nand.c9
-rw-r--r--drivers/dfu/dfu_nand.c18
-rw-r--r--drivers/mtd/nand/docg4.c26
-rw-r--r--drivers/mtd/nand/docg4_spl.c15
-rw-r--r--drivers/mtd/nand/jz4740_nand.c2
-rw-r--r--drivers/mtd/nand/nand_util.c4
-rw-r--r--drivers/mtd/nand/s3c2410_nand.c4
-rw-r--r--include/nand.h2
8 files changed, 46 insertions, 34 deletions
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 8b1e01a..886212a 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -426,7 +426,7 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
}
/* Adjust a chip/partition size down for bad blocks so we don't
- * read/write/erase past the end of a chip/partition by accident.
+ * read/write past the end of a chip/partition by accident.
*/
static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)
{
@@ -546,7 +546,6 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int scrub = !strncmp(cmd, "scrub", 5);
int spread = 0;
int args = 2;
- int adjust_size = 0;
const char *scrub_warn =
"Warning: "
"scrub option will erase all factory set bad blocks!\n"
@@ -563,10 +562,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
spread = 1;
} else if (!strcmp(&cmd[5], ".part")) {
args = 1;
- adjust_size = 1;
} else if (!strcmp(&cmd[5], ".chip")) {
args = 0;
- adjust_size = 1;
} else {
goto usage;
}
@@ -586,10 +583,6 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
&maxsize) != 0)
return 1;
- /* size is unspecified */
- if (adjust_size && !scrub)
- adjust_size_for_badblocks(&size, off, dev);
-
nand = &nand_info[dev];
memset(&opts, 0, sizeof(opts));
diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c
index 7dc89b2..07dee89 100644
--- a/drivers/dfu/dfu_nand.c
+++ b/drivers/dfu/dfu_nand.c
@@ -63,12 +63,26 @@ static int nand_block_op(enum dfu_nand_op op, struct dfu_entity *dfu,
nand = &nand_info[nand_curr_device];
- if (op == DFU_OP_READ)
+ if (op == DFU_OP_READ) {
ret = nand_read_skip_bad(nand, start, &count, &actual,
lim, buf);
- else
+ } else {
+ nand_erase_options_t opts;
+
+ memset(&opts, 0, sizeof(opts));
+ opts.offset = start;
+ opts.length = count;
+ opts.spread = 1;
+ opts.quiet = 1;
+ opts.lim = lim;
+ /* first erase */
+ ret = nand_erase_opts(nand, &opts);
+ if (ret)
+ return ret;
+ /* then write */
ret = nand_write_skip_bad(nand, start, &count, &actual,
lim, buf, 0);
+ }
if (ret != 0) {
printf("%s: nand_%s_skip_bad call failed at %llx!\n",
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index 7dd9953..09f01c8 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -487,7 +487,7 @@ static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
}
static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
- int page, int sndcmd)
+ int page)
{
struct docg4_priv *doc = nand->priv;
void __iomem *docptr = CONFIG_SYS_NAND_BASE;
@@ -577,7 +577,7 @@ static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
writew(p[i], nand->IO_ADDR_W);
}
-static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
const uint8_t *buf, int use_ecc)
{
void __iomem *docptr = CONFIG_SYS_NAND_BASE;
@@ -626,16 +626,18 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
write_nop(docptr);
writew(0, docptr + DOC_DATAEND);
write_nop(docptr);
+
+ return 0;
}
-static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
- const uint8_t *buf)
+static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+ const uint8_t *buf, int oob_required)
{
return write_page(mtd, nand, buf, 0);
}
-static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
- const uint8_t *buf)
+static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+ const uint8_t *buf, int oob_required)
{
return write_page(mtd, nand, buf, 1);
}
@@ -706,13 +708,13 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
return read_page(mtd, nand, buf, page, 0);
}
static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
return read_page(mtd, nand, buf, page, 1);
}
@@ -779,7 +781,7 @@ static int read_factory_bbt(struct mtd_info *mtd)
return -ENOMEM;
read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
- status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE);
+ status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
if (status)
goto exit;
@@ -858,7 +860,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
/* write first page of block */
write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
- docg4_write_page(mtd, nand, buf);
+ docg4_write_page(mtd, nand, buf, 1);
ret = pageprog(mtd);
if (!ret)
mtd->ecc_stats.badblocks++;
@@ -959,8 +961,8 @@ int docg4_nand_init(struct mtd_info *mtd, struct nand_chip *nand, int devnum)
nand->ecc.size = DOCG4_PAGE_SIZE;
nand->ecc.prepad = 8;
nand->ecc.bytes = 8;
- nand->options =
- NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
+ nand->ecc.strength = DOCG4_T;
+ nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE;
nand->controller = &nand->hwcontrol;
/* methods */
diff --git a/drivers/mtd/nand/docg4_spl.c b/drivers/mtd/nand/docg4_spl.c
index 95e856c..734cbeb 100644
--- a/drivers/mtd/nand/docg4_spl.c
+++ b/drivers/mtd/nand/docg4_spl.c
@@ -113,7 +113,6 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
int g4_index = 0;
uint16_t flash_status;
uint16_t *buf;
- uint16_t discard, magic_high, magic_low;
/* flash_offset must be aligned to the start of a block */
if (flash_offset & 0x3ffff)
@@ -154,9 +153,9 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
* The IPL on the palmtreo680 requires that this contain a 32 bit magic
* number, or the load aborts. We'll ignore it.
*/
- discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
- magic_low = readw(docptr + 0x103c);
- magic_high = readw(docptr + DOCG4_MYSTERY_REG);
+ readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
+ readw(docptr + 0x103c); /* lower 16 bits of magic number */
+ readw(docptr + DOCG4_MYSTERY_REG); /* upper 16 bits of magic number */
writew(0, docptr + DOC_DATAEND);
write_nop(docptr);
write_nop(docptr);
@@ -183,15 +182,15 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
write_nop(docptr);
/* read the 512 bytes of page data, 2 bytes at a time */
- discard = readw(docptr + 0x103c);
+ readw(docptr + 0x103c); /* hw quirk */
for (i = 0; i < 256; i++)
*buf++ = readw(docptr + 0x103c);
/* read oob, but discard it */
for (i = 0; i < 7; i++)
- discard = readw(docptr + 0x103c);
- discard = readw(docptr + DOCG4_OOB_6_7);
- discard = readw(docptr + DOCG4_OOB_6_7);
+ readw(docptr + 0x103c);
+ readw(docptr + DOCG4_OOB_6_7);
+ readw(docptr + DOCG4_OOB_6_7);
writew(0, docptr + DOC_DATAEND);
write_nop(docptr);
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index a691fbc..9421e56 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -256,7 +256,7 @@ int board_nand_init(struct nand_chip *nand)
nand->ecc.strength = 4;
nand->ecc.layout = &qi_lb60_ecclayout_2gb;
nand->chip_delay = 50;
- nand->options = NAND_USE_FLASH_BBT;
+ nand->bbt_options |= NAND_BBT_USE_FLASH;
return 0;
}
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index d81972c..1d22b52 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -120,6 +120,10 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
WATCHDOG_RESET();
+ if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) {
+ puts("Size of erase exceeds limit\n");
+ return -EFBIG;
+ }
if (!opts->scrub && bbtest) {
int ret = mtd_block_isbad(meminfo, erase.addr);
if (ret > 0) {
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c
index 43d8213..1187b9f 100644
--- a/drivers/mtd/nand/s3c2410_nand.c
+++ b/drivers/mtd/nand/s3c2410_nand.c
@@ -179,9 +179,7 @@ int board_nand_init(struct nand_chip *nand)
#endif
#ifdef CONFIG_S3C2410_NAND_BBT
- nand->options = NAND_USE_FLASH_BBT;
-#else
- nand->options = 0;
+ nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif
debug("end of nand_init\n");
diff --git a/include/nand.h b/include/nand.h
index 26190e4..228d871 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -125,6 +125,8 @@ struct nand_erase_options {
/* Don't include skipped bad blocks in size to be erased */
int spread;
+ /* maximum size that actual may be in order to not exceed the buf */
+ loff_t lim;
};
typedef struct nand_erase_options nand_erase_options_t;