mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-31 03:21:32 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
This commit is contained in:
commit
5a34d9bf31
8 changed files with 46 additions and 34 deletions
|
@ -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
|
/* 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)
|
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 scrub = !strncmp(cmd, "scrub", 5);
|
||||||
int spread = 0;
|
int spread = 0;
|
||||||
int args = 2;
|
int args = 2;
|
||||||
int adjust_size = 0;
|
|
||||||
const char *scrub_warn =
|
const char *scrub_warn =
|
||||||
"Warning: "
|
"Warning: "
|
||||||
"scrub option will erase all factory set bad blocks!\n"
|
"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;
|
spread = 1;
|
||||||
} else if (!strcmp(&cmd[5], ".part")) {
|
} else if (!strcmp(&cmd[5], ".part")) {
|
||||||
args = 1;
|
args = 1;
|
||||||
adjust_size = 1;
|
|
||||||
} else if (!strcmp(&cmd[5], ".chip")) {
|
} else if (!strcmp(&cmd[5], ".chip")) {
|
||||||
args = 0;
|
args = 0;
|
||||||
adjust_size = 1;
|
|
||||||
} else {
|
} else {
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
|
@ -586,10 +583,6 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
&maxsize) != 0)
|
&maxsize) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* size is unspecified */
|
|
||||||
if (adjust_size && !scrub)
|
|
||||||
adjust_size_for_badblocks(&size, off, dev);
|
|
||||||
|
|
||||||
nand = &nand_info[dev];
|
nand = &nand_info[dev];
|
||||||
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
|
|
@ -63,12 +63,26 @@ static int nand_block_op(enum dfu_nand_op op, struct dfu_entity *dfu,
|
||||||
|
|
||||||
nand = &nand_info[nand_curr_device];
|
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,
|
ret = nand_read_skip_bad(nand, start, &count, &actual,
|
||||||
lim, buf);
|
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,
|
ret = nand_write_skip_bad(nand, start, &count, &actual,
|
||||||
lim, buf, 0);
|
lim, buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("%s: nand_%s_skip_bad call failed at %llx!\n",
|
printf("%s: nand_%s_skip_bad call failed at %llx!\n",
|
||||||
|
|
|
@ -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,
|
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;
|
struct docg4_priv *doc = nand->priv;
|
||||||
void __iomem *docptr = CONFIG_SYS_NAND_BASE;
|
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);
|
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)
|
const uint8_t *buf, int use_ecc)
|
||||||
{
|
{
|
||||||
void __iomem *docptr = CONFIG_SYS_NAND_BASE;
|
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);
|
write_nop(docptr);
|
||||||
writew(0, docptr + DOC_DATAEND);
|
writew(0, docptr + DOC_DATAEND);
|
||||||
write_nop(docptr);
|
write_nop(docptr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
|
static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
|
||||||
const uint8_t *buf)
|
const uint8_t *buf, int oob_required)
|
||||||
{
|
{
|
||||||
return write_page(mtd, nand, buf, 0);
|
return write_page(mtd, nand, buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
|
static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
|
||||||
const uint8_t *buf)
|
const uint8_t *buf, int oob_required)
|
||||||
{
|
{
|
||||||
return write_page(mtd, nand, buf, 1);
|
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,
|
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);
|
return read_page(mtd, nand, buf, page, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
|
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);
|
return read_page(mtd, nand, buf, page, 1);
|
||||||
}
|
}
|
||||||
|
@ -779,7 +781,7 @@ static int read_factory_bbt(struct mtd_info *mtd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
|
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)
|
if (status)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -858,7 +860,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||||
|
|
||||||
/* write first page of block */
|
/* write first page of block */
|
||||||
write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
|
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);
|
ret = pageprog(mtd);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
mtd->ecc_stats.badblocks++;
|
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.size = DOCG4_PAGE_SIZE;
|
||||||
nand->ecc.prepad = 8;
|
nand->ecc.prepad = 8;
|
||||||
nand->ecc.bytes = 8;
|
nand->ecc.bytes = 8;
|
||||||
nand->options =
|
nand->ecc.strength = DOCG4_T;
|
||||||
NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
|
nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE;
|
||||||
nand->controller = &nand->hwcontrol;
|
nand->controller = &nand->hwcontrol;
|
||||||
|
|
||||||
/* methods */
|
/* methods */
|
||||||
|
|
|
@ -113,7 +113,6 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
|
||||||
int g4_index = 0;
|
int g4_index = 0;
|
||||||
uint16_t flash_status;
|
uint16_t flash_status;
|
||||||
uint16_t *buf;
|
uint16_t *buf;
|
||||||
uint16_t discard, magic_high, magic_low;
|
|
||||||
|
|
||||||
/* flash_offset must be aligned to the start of a block */
|
/* flash_offset must be aligned to the start of a block */
|
||||||
if (flash_offset & 0x3ffff)
|
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
|
* The IPL on the palmtreo680 requires that this contain a 32 bit magic
|
||||||
* number, or the load aborts. We'll ignore it.
|
* number, or the load aborts. We'll ignore it.
|
||||||
*/
|
*/
|
||||||
discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
|
readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
|
||||||
magic_low = readw(docptr + 0x103c);
|
readw(docptr + 0x103c); /* lower 16 bits of magic number */
|
||||||
magic_high = readw(docptr + DOCG4_MYSTERY_REG);
|
readw(docptr + DOCG4_MYSTERY_REG); /* upper 16 bits of magic number */
|
||||||
writew(0, docptr + DOC_DATAEND);
|
writew(0, docptr + DOC_DATAEND);
|
||||||
write_nop(docptr);
|
write_nop(docptr);
|
||||||
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);
|
write_nop(docptr);
|
||||||
|
|
||||||
/* read the 512 bytes of page data, 2 bytes at a time */
|
/* 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++)
|
for (i = 0; i < 256; i++)
|
||||||
*buf++ = readw(docptr + 0x103c);
|
*buf++ = readw(docptr + 0x103c);
|
||||||
|
|
||||||
/* read oob, but discard it */
|
/* read oob, but discard it */
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 7; i++)
|
||||||
discard = readw(docptr + 0x103c);
|
readw(docptr + 0x103c);
|
||||||
discard = readw(docptr + DOCG4_OOB_6_7);
|
readw(docptr + DOCG4_OOB_6_7);
|
||||||
discard = readw(docptr + DOCG4_OOB_6_7);
|
readw(docptr + DOCG4_OOB_6_7);
|
||||||
|
|
||||||
writew(0, docptr + DOC_DATAEND);
|
writew(0, docptr + DOC_DATAEND);
|
||||||
write_nop(docptr);
|
write_nop(docptr);
|
||||||
|
|
|
@ -256,7 +256,7 @@ int board_nand_init(struct nand_chip *nand)
|
||||||
nand->ecc.strength = 4;
|
nand->ecc.strength = 4;
|
||||||
nand->ecc.layout = &qi_lb60_ecclayout_2gb;
|
nand->ecc.layout = &qi_lb60_ecclayout_2gb;
|
||||||
nand->chip_delay = 50;
|
nand->chip_delay = 50;
|
||||||
nand->options = NAND_USE_FLASH_BBT;
|
nand->bbt_options |= NAND_BBT_USE_FLASH;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,10 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
|
||||||
|
|
||||||
WATCHDOG_RESET();
|
WATCHDOG_RESET();
|
||||||
|
|
||||||
|
if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) {
|
||||||
|
puts("Size of erase exceeds limit\n");
|
||||||
|
return -EFBIG;
|
||||||
|
}
|
||||||
if (!opts->scrub && bbtest) {
|
if (!opts->scrub && bbtest) {
|
||||||
int ret = mtd_block_isbad(meminfo, erase.addr);
|
int ret = mtd_block_isbad(meminfo, erase.addr);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
|
|
|
@ -179,9 +179,7 @@ int board_nand_init(struct nand_chip *nand)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_S3C2410_NAND_BBT
|
#ifdef CONFIG_S3C2410_NAND_BBT
|
||||||
nand->options = NAND_USE_FLASH_BBT;
|
nand->bbt_options |= NAND_BBT_USE_FLASH;
|
||||||
#else
|
|
||||||
nand->options = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug("end of nand_init\n");
|
debug("end of nand_init\n");
|
||||||
|
|
|
@ -125,6 +125,8 @@ struct nand_erase_options {
|
||||||
|
|
||||||
/* Don't include skipped bad blocks in size to be erased */
|
/* Don't include skipped bad blocks in size to be erased */
|
||||||
int spread;
|
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;
|
typedef struct nand_erase_options nand_erase_options_t;
|
||||||
|
|
Loading…
Add table
Reference in a new issue