* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command @ 2008-12-11 14:27 Rohit Hagargundgi 2009-03-08 6:47 ` Rohit Hagargundgi 0 siblings, 1 reply; 9+ messages in thread From: Rohit Hagargundgi @ 2008-12-11 14:27 UTC (permalink / raw) To: u-boot Add command for changing Flex-OneNAND SLC / MLC boundary. Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> --- common/cmd_onenand.c | 65 +++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 56 insertions(+), 9 deletions(-) diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 8d87b78..2caae45 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -21,8 +21,35 @@ extern struct mtd_info onenand_mtd; extern struct onenand_chip onenand_chip; +/** + * do_set_boundary - [Flex-OneNAND] Set boundary of Flex-OneNAND + * @param mtd mtd information structure + * @param die die of device for which boundary will be set + * @param bdry new boundary value ie last SLC block of die + * + * Set boundary of Flex-OneNAND + */ +int do_set_boundary(struct mtd_info *mtd, unsigned die, unsigned bdry, int lock) +{ + struct onenand_chip *this = mtd->priv; + + if (!FLEXONENAND(this)) { + printf("Flex-OneNAND not found.\n"); + return -1; + } + + if (die >= this->dies) { + printf("Invalid die index\n"); + return -1; + } + + return flexonenand_set_boundary(mtd, die, bdry, lock); +} + int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; int ret = 0; switch (argc) { @@ -57,10 +84,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) start = simple_strtoul(argv[2], NULL, 10); end = simple_strtoul(argv[3], NULL, 10); - start >>= onenand_chip.erase_shift; - end >>= onenand_chip.erase_shift; + start = onenand_get_block(this, start, NULL); + end = onenand_get_block(this, end, NULL); /* Don't include the end block */ - end--; + if (end > 0) + end--; } if (!end || end < 0) @@ -69,8 +97,13 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("Erase block from %lu to %lu\n", start, end); for (block = start; block <= end; block++) { - instr.addr = block << onenand_chip.erase_shift; - instr.len = 1 << onenand_chip.erase_shift; + instr.addr = onenand_get_addr(this, block); + if (mtd->numeraseregions > 1) { + int i = flexonenand_region(mtd, instr.addr); + instr.len = mtd->eraseregions[i].erasesize; + } else + instr.len = mtd->erasesize; + ret = onenand_erase(&onenand_mtd, &instr); if (ret) { printf("erase failed %lu\n", block); @@ -134,15 +167,15 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ops.mode = MTD_OOB_PLACE; - ofs = block << onenand_chip.erase_shift; + ofs = onenand_get_addr(this, block); if (page) ofs += page << onenand_chip.page_shift; if (!len) { if (oob) - ops.ooblen = 64; + ops.ooblen = FLEXONENAND(this) ? 128 : 64; else - ops.len = 512; + ops.len = FLEXONENAND(this) ? 4096 : 512; } if (oob) { @@ -158,6 +191,18 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 0; } + if (strncmp(argv[1], "setboundary", 11) == 0) { + unsigned die = simple_strtoul(argv[2], NULL, 0); + unsigned bdry = simple_strtoul(argv[3], NULL, 0); + int lock = 0; + + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) + lock = 1; + + do_set_boundary(mtd, die, bdry, lock); + return 0; + } + break; } @@ -172,5 +217,7 @@ U_BOOT_CMD( "onenand write addr ofs len - write data@ofs with len from addr\n" "onenand erase saddr eaddr - erase block start addr to end addr\n" "onenand block[.oob] addr block [page] [len] - " - "read data with (block [, page]) to addr" + "read data with (block [, page]) to addr\n" + "onenand setboundary DIE BOUNDARY [LOCK] - " + "Change SLC boundary of Flex-OneNAND\n" ); -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2008-12-11 14:27 [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command Rohit Hagargundgi @ 2009-03-08 6:47 ` Rohit Hagargundgi 2009-03-09 21:38 ` Scott Wood 0 siblings, 1 reply; 9+ messages in thread From: Rohit Hagargundgi @ 2009-03-08 6:47 UTC (permalink / raw) To: u-boot On Thursday 11 December 2008 19:57:53 Rohit Hagargundgi wrote: > Add command for changing Flex-OneNAND SLC / MLC boundary. > Also onenand commands work for Flex-OneNAND. Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> --- common/cmd_onenand.c | 88 ++++++++++++++++++++++++++++++++-------------- include/configs/apollon.h | 2 - 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/include/configs/apollon.h b/include/configs/apollon.h index dff47fc..6e3e34a 100644 --- a/include/configs/apollon.h +++ b/include/configs/apollon.h @@ -76,7 +76,7 @@ */ #define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE_FLEX SZ_256K -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_2M) /* bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_SIZE 128 diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 6a2c924..7779b44 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size) return 0; } +static inline int onenand_blocksize(loff_t ofs) +{ + struct onenand_chip *this = mtd->priv; + int i; + + if (!FLEXONENAND(this)) + return mtd->erasesize; + + i = flexonenand_region(mtd, ofs); + return mtd->eraseregions[i].erasesize; +} + static int onenand_block_read(loff_t from, size_t len, size_t *retlen, u_char *buf, int oob) { struct onenand_chip *this = mtd->priv; - int blocks = (int) len >> this->erase_shift; - int blocksize = (1 << this->erase_shift); + int blocks = (int) onenand_block(this, from + len) + - onenand_block(this, from); + int blocksize; loff_t ofs = from; struct mtd_oob_ops ops = { .retlen = 0, }; int ret; - if (oob) - ops.ooblen = blocksize; - else - ops.len = blocksize; - while (blocks) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret) { printk("Bad blocks %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); ofs += blocksize; continue; } - if (oob) + if (oob) { ops.oobbuf = buf; - else + ops.ooblen = blocksize; + } else { ops.datbuf = buf; + ops.len = blocksize; + } ops.retlen = 0; ret = mtd->read_oob(mtd, ofs, &ops); @@ -116,8 +129,7 @@ static int onenand_block_write(loff_t to, size_t len, size_t *retlen, const u_char * buf) { struct onenand_chip *this = mtd->priv; - int blocks = len >> this->erase_shift; - int blocksize = (1 << this->erase_shift); + int blocks, blocksize; loff_t ofs; size_t _retlen = 0; int ret; @@ -131,11 +143,15 @@ static int onenand_block_write(loff_t to, size_t len, } ofs = to; + blocks = (int) onenand_block(this, ofs + len) - onenand_block(this, ofs); + while (blocks) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret) { printk("Bad blocks %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); skip_ofs += blocksize; goto next; } @@ -165,13 +181,15 @@ static int onenand_block_erase(u32 start, u32 size, int force) }; loff_t ofs; int ret; - int blocksize = 1 << this->erase_shift; + int blocksize; for (ofs = start; ofs < (start + size); ofs += blocksize) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret && !force) { printf("Skip erase bad block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); continue; } @@ -182,7 +200,7 @@ static int onenand_block_erase(u32 start, u32 size, int force) ret = mtd->erase(mtd, &instr); if (ret) { printf("erase failed block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); continue; } } @@ -219,25 +237,27 @@ static int onenand_block_test(u32 start, u32 size) return -1; } - start_block = start >> this->erase_shift; - end_block = (start + size) >> this->erase_shift; + start_block = onenand_block(this, start); + end_block = onenand_block(this, start + size); /* Protect boot-loader from badblock testing */ if (start_block < 2) start_block = 2; - if (end_block > (mtd->size >> this->erase_shift)) - end_block = mtd->size >> this->erase_shift; + if (end_block > onenand_block(this, mtd->size)) + end_block = onenand_block(this, mtd->size); blocks = start_block; ofs = start; while (blocks < end_block) { - printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs); + printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), (u32)ofs); + + blocksize = onenand_blocksize(ofs); ret = mtd->block_isbad(mtd, ofs); if (ret) { printf("Skip erase bad block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); goto next; } @@ -341,7 +361,6 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) mtd = &onenand_mtd; this = mtd->priv; - blocksize = (1 << this->erase_shift); cmd = argv[1]; @@ -359,9 +378,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strcmp(cmd, "bad") == 0) { /* Currently only one OneNAND device is supported */ printf("\nDevice %d bad blocks:\n", 0); - for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { + for (ofs = 0; ofs < mtd->size; ofs += blocksize) { if (mtd->block_isbad(mtd, ofs)) printf(" %08x\n", (u32)ofs); + + blocksize = onenand_blocksize(ofs); } return 0; @@ -459,6 +480,21 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return ret == 0 ? 1 : 0; } + if (strncmp(cmd, "setboundary", 11) == 0) { + int die, bdry, lock = 0; + + if (argc < 4) + goto usage; + + die = (int) simple_strtoul(argv[2], NULL, 0); + bdry = (int) simple_strtoul(argv[3], NULL, 0); + + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) + lock = 1; + + return flexonenand_set_boundary(mtd, die, bdry, lock); + } + break; } @@ -478,9 +514,11 @@ U_BOOT_CMD( "onenand write[.oob] addr off size\n" " read/write 'size' bytes starting at offset 'off'\n" " to/from memory address 'addr', skipping bad blocks.\n" - "onenand erase [force] [off size] - erase 'size' bytes from\n" + "onenand erase [force] [off size] - erase 'size' bytes from off\n" "onenand test [off size] - test 'size' bytes from\n" " offset 'off' (entire device if not specified)\n" "onenand dump[.oob] off - dump page\n" "onenand markbad off - mark bad block@offset (UNSAFE)\n" + "onenand setboundary DIE BOUNDARY [LOCK] - " + "Change SLC boundary of Flex-OneNAND\n" ); ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-08 6:47 ` Rohit Hagargundgi @ 2009-03-09 21:38 ` Scott Wood 2009-03-23 7:06 ` Amul Kumar Saha 2009-03-25 15:14 ` Amul Kumar Saha 0 siblings, 2 replies; 9+ messages in thread From: Scott Wood @ 2009-03-09 21:38 UTC (permalink / raw) To: u-boot On Sun, Mar 08, 2009 at 12:17:36PM +0530, Rohit Hagargundgi wrote: > +static inline int onenand_blocksize(loff_t ofs) > +{ > + struct onenand_chip *this = mtd->priv; > + int i; > + > + if (!FLEXONENAND(this)) > + return mtd->erasesize; > + > + i = flexonenand_region(mtd, ofs); > + return mtd->eraseregions[i].erasesize; Can we define the interface to the onenand code such that the caller doesn't need to care what type of onenand it is, and non-flex will simply appear to have one region? > + if (strncmp(cmd, "setboundary", 11) == 0) { > + int die, bdry, lock = 0; > + > + if (argc < 4) > + goto usage; > + > + die = (int) simple_strtoul(argv[2], NULL, 0); > + bdry = (int) simple_strtoul(argv[3], NULL, 0); > + > + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) > + lock = 1; > + > + return flexonenand_set_boundary(mtd, die, bdry, lock); > + } What happens if the user runs the setboundary command on non-flex onenand? Does it fail gracefully? > + > break; > } > > @@ -478,9 +514,11 @@ U_BOOT_CMD( > "onenand write[.oob] addr off size\n" > " read/write 'size' bytes starting at offset 'off'\n" > " to/from memory address 'addr', skipping bad blocks.\n" > - "onenand erase [force] [off size] - erase 'size' bytes from\n" > + "onenand erase [force] [off size] - erase 'size' bytes from off\n" Quotes around 'off', as is done elsewhere in the help text. -Scott ^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-09 21:38 ` Scott Wood @ 2009-03-23 7:06 ` Amul Kumar Saha 2009-03-23 20:17 ` Scott Wood 2009-03-25 15:14 ` Amul Kumar Saha 1 sibling, 1 reply; 9+ messages in thread From: Amul Kumar Saha @ 2009-03-23 7:06 UTC (permalink / raw) To: u-boot Hi Scott, >> +static inline int onenand_blocksize(loff_t ofs) >> +{ >> + struct onenand_chip *this = mtd->priv; >> + int i; >> + >> + if (!FLEXONENAND(this)) >> + return mtd->erasesize; >> + >> + i = flexonenand_region(mtd, ofs); >> + return mtd->eraseregions[i].erasesize; > > Can we define the interface to the onenand code such that the caller > doesn't need to care what type of onenand it is, and non-flex will simply > appear to have one region? > Right. We shall take this on moving ahead. Guess this is fine for now. >> + if (strncmp(cmd, "setboundary", 11) == 0) { >> + int die, bdry, lock = 0; >> + >> + if (argc < 4) >> + goto usage; >> + >> + die = (int) simple_strtoul(argv[2], NULL, 0); >> + bdry = (int) simple_strtoul(argv[3], NULL, 0); >> + >> + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) >> + lock = 1; >> + >> + return flexonenand_set_boundary(mtd, die, bdry, lock); >> + } > > What happens if the user runs the setboundary command on non-flex > onenand? Does it fail gracefully? > Resolved. >> + >> break; >> } >> >> @@ -478,9 +514,11 @@ U_BOOT_CMD( >> "onenand write[.oob] addr off size\n" >> " read/write 'size' bytes starting at offset 'off'\n" >> " to/from memory address 'addr', skipping bad blocks.\n" >> - "onenand erase [force] [off size] - erase 'size' bytes from\n" >> + "onenand erase [force] [off size] - erase 'size' bytes from off\n" > > Quotes around 'off', as is done elsewhere in the help text. > Resolved OneNAND commands now work for Flex-OneNAND. Add command for changing Flex-OneNAND SLC / MLC boundary. Thank You, Amul Kumar Saha Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> Signed-off-by: Amul Kumar Saha <amul.saha@samsung.com> --- common/cmd_onenand.c | 103 ++++++++++++++++++++++++++++++++-------------- include/configs/apollon.h | 2 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 5832ff8..ed6681a 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size) return 0; } +static inline int onenand_blocksize(loff_t ofs) +{ + struct onenand_chip *this = mtd->priv; + int i; + + if (!FLEXONENAND(this)) + return mtd->erasesize; + + i = flexonenand_region(mtd, ofs); + return mtd->eraseregions[i].erasesize; +} + static int onenand_block_read(loff_t from, size_t len, size_t *retlen, u_char *buf, int oob) { struct onenand_chip *this = mtd->priv; - int blocks = (int) len >> this->erase_shift; - int blocksize = (1 << this->erase_shift); + int blocks = (int) onenand_block(this, from + len) + - onenand_block(this, from); + int blocksize; loff_t ofs = from; struct mtd_oob_ops ops = { .retlen = 0, }; int ret; - if (oob) - ops.ooblen = blocksize; - else - ops.len = blocksize; - while (blocks) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret) { printk("Bad blocks %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); ofs += blocksize; continue; } - if (oob) + if (oob) { ops.oobbuf = buf; - else + ops.ooblen = blocksize; + } else { ops.datbuf = buf; + ops.len = blocksize; + } ops.retlen = 0; ret = mtd->read_oob(mtd, ofs, &ops); @@ -116,8 +129,7 @@ static int onenand_block_write(loff_t to, size_t len, size_t *retlen, const u_char * buf) { struct onenand_chip *this = mtd->priv; - int blocks = len >> this->erase_shift; - int blocksize = (1 << this->erase_shift); + int blocks, blocksize; loff_t ofs; size_t _retlen = 0; int ret; @@ -131,11 +143,15 @@ static int onenand_block_write(loff_t to, size_t len, } ofs = to; + blocks = (int) onenand_block(this, ofs + len) - onenand_block(this, ofs); + while (blocks) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret) { printk("Bad blocks %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); skip_ofs += blocksize; goto next; } @@ -165,13 +181,15 @@ static int onenand_block_erase(u32 start, u32 size, int force) }; loff_t ofs; int ret; - int blocksize = 1 << this->erase_shift; + int blocksize; for (ofs = start; ofs < (start + size); ofs += blocksize) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret && !force) { printf("Skip erase bad block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); continue; } @@ -182,7 +200,7 @@ static int onenand_block_erase(u32 start, u32 size, int force) ret = mtd->erase(mtd, &instr); if (ret) { printf("erase failed block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); continue; } } @@ -219,25 +237,27 @@ static int onenand_block_test(u32 start, u32 size) return -1; } - start_block = start >> this->erase_shift; - end_block = (start + size) >> this->erase_shift; + start_block = onenand_block(this, start); + end_block = onenand_block(this, start + size); /* Protect boot-loader from badblock testing */ if (start_block < 2) start_block = 2; - if (end_block > (mtd->size >> this->erase_shift)) - end_block = mtd->size >> this->erase_shift; + if (end_block > onenand_block(this, mtd->size)) + end_block = onenand_block(this, mtd->size); blocks = start_block; ofs = start; while (blocks < end_block) { - printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs); + printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), (u32)ofs); + + blocksize = onenand_blocksize(ofs); ret = mtd->block_isbad(mtd, ofs); if (ret) { printf("Skip erase bad block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + (u32)onenand_block(this, ofs), (u32)ofs); goto next; } @@ -341,7 +361,6 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) mtd = &onenand_mtd; this = mtd->priv; - blocksize = (1 << this->erase_shift); cmd = argv[1]; @@ -359,9 +378,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strcmp(cmd, "bad") == 0) { /* Currently only one OneNAND device is supported */ printf("\nDevice %d bad blocks:\n", 0); - for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { + for (ofs = 0; ofs < mtd->size; ofs += blocksize) { if (mtd->block_isbad(mtd, ofs)) printf(" %08x\n", (u32)ofs); + + blocksize = onenand_blocksize(ofs); } return 0; @@ -459,6 +480,26 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return ret == 0 ? 1 : 0; } + /* + * The following cmd holds true only for a Flex-OneNAND + */ + if (FLEXONENAND(this)) { + if (strncmp(cmd, "setboundary", 11) == 0) { + int die, bdry, lock = 0; + + if (argc < 4) + goto usage; + + die = (int) simple_strtoul(argv[2], NULL, 0); + bdry = (int) simple_strtoul(argv[3], NULL, 0); + + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) + lock = 1; + + return flexonenand_set_boundary(mtd, die, bdry, lock); + } + } + break; } @@ -474,13 +515,15 @@ U_BOOT_CMD( "OneNAND sub-system", "info - show available OneNAND devices\n" "onenand bad - show bad blocks\n" - "onenand read[.oob] addr off size\n" - "onenand write[.oob] addr off size\n" + "onenand read[.oob] addr 'off' size\n" + "onenand write[.oob] addr 'off' size\n" " read/write 'size' bytes starting at offset 'off'\n" " to/from memory address 'addr', skipping bad blocks.\n" - "onenand erase [force] [off size] - erase 'size' bytes from\n" - "onenand test [off size] - test 'size' bytes from\n" + "onenand erase [force] ['off' size] - erase 'size' bytes from 'off'\n" + "onenand test ['off' size] - test 'size' bytes from\n" " offset 'off' (entire device if not specified)\n" - "onenand dump[.oob] off - dump page\n" - "onenand markbad off - mark bad block at offset (UNSAFE)\n" + "onenand dump[.oob] 'off' - dump page\n" + "onenand markbad 'off' - mark bad block@offset (UNSAFE)\n" + "onenand setboundary DIE BOUNDARY [LOCK] - " + "Change SLC boundary of Flex-OneNAND\n" ); diff --git a/include/configs/apollon.h b/include/configs/apollon.h index 0fcb22b..3a096c8 100644 --- a/include/configs/apollon.h +++ b/include/configs/apollon.h @@ -77,7 +77,7 @@ */ #define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE_FLEX SZ_256K -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_2M) /* bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_SIZE 128 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-23 7:06 ` Amul Kumar Saha @ 2009-03-23 20:17 ` Scott Wood 0 siblings, 0 replies; 9+ messages in thread From: Scott Wood @ 2009-03-23 20:17 UTC (permalink / raw) To: u-boot On Mon, Mar 23, 2009 at 12:36:32PM +0530, Amul Kumar Saha wrote: > diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c > index 5832ff8..ed6681a 100644 > --- a/common/cmd_onenand.c > +++ b/common/cmd_onenand.c > @@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong > *off, size_t *size) > return 0; > } > > +static inline int onenand_blocksize(loff_t ofs) > +{ > + struct onenand_chip *this = mtd->priv; > + int i; Patch is whitespace-damaged. Please send the patch separately (not as a reply; it's easy to miss patches at the end of a reply, and I have to manually strip the discussion from the changelog) using something that will preserve the patch text intact (not Outlook Express). > + int blocks = (int) onenand_block(this, from + len) > + - onenand_block(this, from); Why the (int) cast? onenand_block() already returns int. > - if (end_block > (mtd->size >> this->erase_shift)) > - end_block = mtd->size >> this->erase_shift; > + if (end_block > onenand_block(this, mtd->size)) > + end_block = onenand_block(this, mtd->size); This should probably be: if (end_block >= onenand_block(this, mtd->size - 1)) ...to avoid asking for a block that doesn't exist. > blocks = start_block; > ofs = start; > while (blocks < end_block) { > - printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), > (u32)ofs); > + printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), > (u32)ofs); No (u32) cast on return from onenand_block(). Likewise elsewhere. > @@ -359,9 +378,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, > char *argv[]) > if (strcmp(cmd, "bad") == 0) { > /* Currently only one OneNAND device is supported */ > printf("\nDevice %d bad blocks:\n", 0); > - for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { > + for (ofs = 0; ofs < mtd->size; ofs += blocksize) { > if (mtd->block_isbad(mtd, ofs)) > printf(" %08x\n", (u32)ofs); > + > + blocksize = onenand_blocksize(ofs); > } Hmm, not sure I like blocksize being used in the for loop when it's first initialized in the body of the loop. It's valid code, but it might be more readable as a while loop. > + die = (int) simple_strtoul(argv[2], NULL, 0); > + bdry = (int) simple_strtoul(argv[3], NULL, 0); Casts should not be necessary. > + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) > + lock = 1; Please have commands be lower-case, just like all the other ones. -Scott ^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-09 21:38 ` Scott Wood 2009-03-23 7:06 ` Amul Kumar Saha @ 2009-03-25 15:14 ` Amul Kumar Saha 2009-03-25 17:23 ` Scott Wood 1 sibling, 1 reply; 9+ messages in thread From: Amul Kumar Saha @ 2009-03-25 15:14 UTC (permalink / raw) To: u-boot Hi Scott, > >> + int blocks = (int) onenand_block(this, from + len) >> + - onenand_block(this, from); > > Why the (int) cast? onenand_block() already returns int. > Resolved >> - if (end_block > (mtd->size >> this->erase_shift)) >> - end_block = mtd->size >> this->erase_shift; >> + if (end_block > onenand_block(this, mtd->size)) >> + end_block = onenand_block(this, mtd->size); > > This should probably be: > > if (end_block >= onenand_block(this, mtd->size - 1)) > > ...to avoid asking for a block that doesn't exist. > Changed from mtd->size to (mtd->size) - 1, In the OP, end_block was understood to accomodate (last_block_no + 1). But, as you have pointed it may be more conventional to have the exact last_block_no made necessary changes in some other places as well. >> blocks = start_block; >> ofs = start; >> while (blocks < end_block) { >> - printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), >> (u32)ofs); >> + printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), >> (u32)ofs); > > No (u32) cast on return from onenand_block(). Likewise elsewhere. > Accepted and changed. >> + for (ofs = 0; ofs < mtd->size; ofs += blocksize) { >> if (mtd->block_isbad(mtd, ofs)) >> printf(" %08x\n", (u32)ofs); >> + >> + blocksize = onenand_blocksize(ofs); >> } > > Hmm, not sure I like blocksize being used in the for loop when it's first > initialized in the body of the loop. It's valid code, but it might be > more readable as a while loop. > Modified it to a while loop. Thanks :) ofs = 0; while (ofs < mtd->size) { if (mtd->block_isbad(mtd, ofs)) printf(" %08x\n", (u32)ofs); ofs += onenand_blocksize(ofs); } >> + die = (int) simple_strtoul(argv[2], NULL, 0); >> + bdry = (int) simple_strtoul(argv[3], NULL, 0); > > Casts should not be necessary. > I believe that typecasting a UL to an int, is OK. Do let me know. >> + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0) >> + lock = 1; > > Please have commands be lower-case, just like all the other ones. > Changed Do let me know, your feedback on the changes made. I'll send the updated patch, in the next post. With regards, Amul ^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-25 15:14 ` Amul Kumar Saha @ 2009-03-25 17:23 ` Scott Wood 2009-03-26 12:21 ` Amul Kumar Saha 2009-03-26 12:35 ` Amul Kumar Saha 0 siblings, 2 replies; 9+ messages in thread From: Scott Wood @ 2009-03-25 17:23 UTC (permalink / raw) To: u-boot On Wed, Mar 25, 2009 at 08:44:37PM +0530, Amul Kumar Saha wrote: > >> + die = (int) simple_strtoul(argv[2], NULL, 0); > >> + bdry = (int) simple_strtoul(argv[3], NULL, 0); > > > > Casts should not be necessary. > > > > I believe that typecasting a UL to an int, is OK. > Do let me know. The compiler will implicitly cast unsigned long to int. The explicit cast is unnecessary clutter which makes it harder to find casts that aren't OK. -Scott ^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-25 17:23 ` Scott Wood @ 2009-03-26 12:21 ` Amul Kumar Saha 2009-03-26 12:35 ` Amul Kumar Saha 1 sibling, 0 replies; 9+ messages in thread From: Amul Kumar Saha @ 2009-03-26 12:21 UTC (permalink / raw) To: u-boot Hi Scott, >> I believe that typecasting a UL to an int, is OK. >> Do let me know. > > The compiler will implicitly cast unsigned long to int. The explicit cast > is unnecessary clutter which makes it harder to find casts that aren't OK. Accepted and changed. Thank You Amul. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command 2009-03-25 17:23 ` Scott Wood 2009-03-26 12:21 ` Amul Kumar Saha @ 2009-03-26 12:35 ` Amul Kumar Saha 1 sibling, 0 replies; 9+ messages in thread From: Amul Kumar Saha @ 2009-03-26 12:35 UTC (permalink / raw) To: u-boot OneNAND commands now work for Flex-OneNAND. Add command for changing Flex-OneNAND SLC / MLC boundary. Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> Signed-off-by: Amul Kumar Saha <amul.saha@samsung.com> --- common/cmd_onenand.c | 103 ++++++++++++++++++++++++++++++++-------------- include/configs/apollon.h | 2 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 5832ff8..8d25238 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size) return 0; } +static inline int onenand_blocksize(loff_t ofs) +{ + struct onenand_chip *this = mtd->priv; + int i; + + if (!FLEXONENAND(this)) + return mtd->erasesize; + + i = flexonenand_region(mtd, ofs); + return mtd->eraseregions[i].erasesize; +} + static int onenand_block_read(loff_t from, size_t len, size_t *retlen, u_char *buf, int oob) { struct onenand_chip *this = mtd->priv; - int blocks = (int) len >> this->erase_shift; - int blocksize = (1 << this->erase_shift); + int blocks = onenand_block(this, from + len) + - onenand_block(this, from); + int blocksize; loff_t ofs = from; struct mtd_oob_ops ops = { .retlen = 0, }; int ret; - if (oob) - ops.ooblen = blocksize; - else - ops.len = blocksize; - while (blocks) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret) { printk("Bad blocks %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + onenand_block(this, ofs), (u32)ofs); ofs += blocksize; continue; } - if (oob) + if (oob) { ops.oobbuf = buf; - else + ops.ooblen = blocksize; + } else { ops.datbuf = buf; + ops.len = blocksize; + } ops.retlen = 0; ret = mtd->read_oob(mtd, ofs, &ops); @@ -116,8 +129,7 @@ static int onenand_block_write(loff_t to, size_t len, size_t *retlen, const u_char * buf) { struct onenand_chip *this = mtd->priv; - int blocks = len >> this->erase_shift; - int blocksize = (1 << this->erase_shift); + int blocks, blocksize; loff_t ofs; size_t _retlen = 0; int ret; @@ -131,11 +143,15 @@ static int onenand_block_write(loff_t to, size_t len, } ofs = to; + blocks = onenand_block(this, ofs + len) - onenand_block(this, ofs); + while (blocks) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret) { printk("Bad blocks %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + onenand_block(this, ofs), (u32)ofs); skip_ofs += blocksize; goto next; } @@ -165,13 +181,15 @@ static int onenand_block_erase(u32 start, u32 size, int force) }; loff_t ofs; int ret; - int blocksize = 1 << this->erase_shift; + int blocksize; for (ofs = start; ofs < (start + size); ofs += blocksize) { + blocksize = onenand_blocksize(ofs); + ret = mtd->block_isbad(mtd, ofs); if (ret && !force) { printf("Skip erase bad block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + onenand_block(this, ofs), (u32)ofs); continue; } @@ -182,7 +200,7 @@ static int onenand_block_erase(u32 start, u32 size, int force) ret = mtd->erase(mtd, &instr); if (ret) { printf("erase failed block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + onenand_block(this, ofs), (u32)ofs); continue; } } @@ -219,25 +237,27 @@ static int onenand_block_test(u32 start, u32 size) return -1; } - start_block = start >> this->erase_shift; - end_block = (start + size) >> this->erase_shift; + start_block = onenand_block(this, start); + end_block = onenand_block(this, start + size - 1); /* Protect boot-loader from badblock testing */ if (start_block < 2) start_block = 2; - if (end_block > (mtd->size >> this->erase_shift)) - end_block = mtd->size >> this->erase_shift; + if (end_block > onenand_block(this, mtd->size - 1)) + end_block = onenand_block(this, mtd->size - 1); blocks = start_block; ofs = start; - while (blocks < end_block) { - printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs); + while (blocks <= end_block) { + printf("\rTesting block %d@0x%x", onenand_block(this, ofs), (u32)ofs); + + blocksize = onenand_blocksize(ofs); ret = mtd->block_isbad(mtd, ofs); if (ret) { printf("Skip erase bad block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + onenand_block(this, ofs), (u32)ofs); goto next; } @@ -341,7 +361,6 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) mtd = &onenand_mtd; this = mtd->priv; - blocksize = (1 << this->erase_shift); cmd = argv[1]; @@ -359,9 +378,12 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strcmp(cmd, "bad") == 0) { /* Currently only one OneNAND device is supported */ printf("\nDevice %d bad blocks:\n", 0); - for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { + ofs = 0; + while (ofs < mtd->size) { if (mtd->block_isbad(mtd, ofs)) printf(" %08x\n", (u32)ofs); + + ofs += onenand_blocksize(ofs); } return 0; @@ -459,6 +481,23 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return ret == 0 ? 1 : 0; } + if (FLEXONENAND(this)) { + if (strncmp(cmd, "setboundary", 11) == 0) { + int die, bdry, lock = 0; + + if (argc < 4) + goto usage; + + die = (int) simple_strtoul(argv[2], NULL, 0); + bdry = (int) simple_strtoul(argv[3], NULL, 0); + + if (argc == 5 && strncmp(argv[4], "lock", 4) == 0) + lock = 1; + + return flexonenand_set_boundary(mtd, die, bdry, lock); + } + } + break; } @@ -474,13 +513,15 @@ U_BOOT_CMD( "OneNAND sub-system", "info - show available OneNAND devices\n" "onenand bad - show bad blocks\n" - "onenand read[.oob] addr off size\n" - "onenand write[.oob] addr off size\n" + "onenand read[.oob] addr 'off' size\n" + "onenand write[.oob] addr 'off' size\n" " read/write 'size' bytes starting at offset 'off'\n" " to/from memory address 'addr', skipping bad blocks.\n" - "onenand erase [force] [off size] - erase 'size' bytes from\n" - "onenand test [off size] - test 'size' bytes from\n" + "onenand erase [force] ['off' size] - erase 'size' bytes from 'off'\n" + "onenand test ['off' size] - test 'size' bytes from\n" " offset 'off' (entire device if not specified)\n" - "onenand dump[.oob] off - dump page\n" - "onenand markbad off - mark bad block at offset (UNSAFE)\n" + "onenand dump[.oob] 'off' - dump page\n" + "onenand markbad 'off' - mark bad block@offset (UNSAFE)\n" + "onenand setboundary DIE BOUNDARY [LOCK] - " + "Change SLC boundary of Flex-OneNAND\n" ); diff --git a/include/configs/apollon.h b/include/configs/apollon.h index 0fcb22b..3a096c8 100644 --- a/include/configs/apollon.h +++ b/include/configs/apollon.h @@ -77,7 +77,7 @@ */ #define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE_FLEX SZ_256K -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_2M) /* bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_SIZE 128 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-03-26 12:35 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-12-11 14:27 [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command Rohit Hagargundgi 2009-03-08 6:47 ` Rohit Hagargundgi 2009-03-09 21:38 ` Scott Wood 2009-03-23 7:06 ` Amul Kumar Saha 2009-03-23 20:17 ` Scott Wood 2009-03-25 15:14 ` Amul Kumar Saha 2009-03-25 17:23 ` Scott Wood 2009-03-26 12:21 ` Amul Kumar Saha 2009-03-26 12:35 ` Amul Kumar Saha
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox