[U-Boot] [PATCH 3/3] [OneNAND] Flex-OneNAND boundary settings

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 Signed-off-by: Amul Kumar Saha amul.saha@samsung.com --- common/cmd_onenand.c | 90 +++++++++++++++++++++++++++++++++------------- include/configs/apollon.h | 2 - 2 files changed, 66 insertions(+), 26 deletions(-)
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 9090940..a34befe 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -69,36 +69,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); @@ -120,8 +133,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; @@ -135,11 +147,16 @@ 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; } @@ -169,13 +186,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; }
@@ -186,7 +205,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; } } @@ -223,25 +242,28 @@ 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 at 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; }
@@ -345,7 +367,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];
@@ -363,9 +384,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; @@ -474,6 +497,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) strict_strtoul(argv[2], NULL, 0); + bdry = (int) strict_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; }
@@ -493,9 +531,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(s) at offset (UNSAFE)" + "onenand setboundary DIE BOUNDARY [LOCK] - \n" + "Change SLC boundary of Flex-OneNAND\n" ); diff --git a/include/configs/apollon.h b/include/configs/apollon.h index ddac5fb..5a97743 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

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 Signed-off-by: Amul Kumar Saha amul.saha@samsung.com --- common/cmd_onenand.c | 90 +++++++++++++++++++++++++++++++++------------- include/configs/apollon.h | 2 - 2 files changed, 66 insertions(+), 26 deletions(-)
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 9090940..a34befe 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -69,36 +69,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); @@ -120,8 +133,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; @@ -135,11 +147,16 @@ 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; } @@ -169,13 +186,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; }
@@ -186,7 +205,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; } } @@ -223,25 +242,28 @@ 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 at 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; }
@@ -345,7 +367,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];
@@ -363,9 +384,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; @@ -474,6 +497,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; }
@@ -493,9 +531,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(s) at offset (UNSAFE)" + "onenand setboundary DIE BOUNDARY [LOCK] - \n" + "Change SLC boundary of Flex-OneNAND\n" ); diff --git a/include/configs/apollon.h b/include/configs/apollon.h index ddac5fb..5a97743 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

On Wed, Nov 04, 2009 at 10:39:41AM +0530, Amul Kumar Saha wrote:
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);
This isn't new, but %d doesn't match u32 (though I guess GCC doesn't complain about signedness) -- and we shouldn't be chopping off the upper bits of ofs.
- blocks = (int) onenand_block(this, ofs + len)
- onenand_block(this, ofs);
Unnecessary cast.
@@ -493,9 +531,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(s) at offset (UNSAFE)"
- "onenand setboundary DIE BOUNDARY [LOCK] - \n"
- "Change SLC boundary of Flex-OneNAND\n"
Description should be indented if you're going to put it on a new line.
-Scott

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);
This isn't new, but %d doesn't match u32 (though I guess GCC doesn't complain about signedness) -- and we shouldn't be chopping off the upper bits of ofs.
Accepted and Corrected
- blocks = (int) onenand_block(this, ofs + len)
- onenand_block(this, ofs);
Unnecessary cast.
Yes, got that.
@@ -493,9 +531,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(s) at offset (UNSAFE)"
- "onenand setboundary DIE BOUNDARY [LOCK] - \n"
- "Change SLC boundary of Flex-OneNAND\n"
Description should be indented if you're going to put it on a new line.
I've put '\t' instead now.
Regards, Amul

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 Signed-off-by: Amul Kumar Saha amul.saha@samsung.com --- common/cmd_onenand.c | 98 ++++++++++++++++++++++++++++++++-------------- include/configs/apollon.h | 2 2 files changed, 70 insertions(+), 30 deletions(-)
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 9090940..1d0778e 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -69,36 +69,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); + printk("Bad blocks %lu at 0x%x\n", + (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); @@ -120,8 +133,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; @@ -135,11 +147,16 @@ 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; } @@ -169,13 +186,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; }
@@ -186,7 +205,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; } } @@ -223,25 +242,28 @@ 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 at 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; }
@@ -345,7 +367,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];
@@ -363,9 +384,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; @@ -474,6 +497,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; }
@@ -491,11 +529,13 @@ U_BOOT_CMD( "onenand bad - show bad blocks\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" + "\tread/write 'size' bytes starting at offset 'off'\n" + "\tto/from memory address 'addr', skipping bad blocks.\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" + "\toffset 'off' (entire device if not specified)\n" "onenand dump[.oob] off - dump page\n" "onenand markbad off [...] - mark bad block(s) at offset (UNSAFE)" + "onenand setboundary DIE BOUNDARY [LOCK] - \n" + "\tChange SLC boundary of Flex-OneNAND\n" ); diff --git a/include/configs/apollon.h b/include/configs/apollon.h index ddac5fb..5a97743 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

On Fri, Nov 06, 2009 at 05:17:44PM +0530, Amul Kumar Saha wrote:
printk("Bad blocks %d at 0x%x\n",
(u32)(ofs >> this->erase_shift), (u32)ofs);
printk("Bad blocks %lu at 0x%x\n",
(u32)onenand_block(this, ofs), (u32)ofs);
cmd_onenand.c: In function ‘onenand_block_read’: cmd_onenand.c:103: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 2 has type ‘unsigned int’
If you must pass a u32 to printf, use "%u" or "%x" -- but it makes little sense to explicitly cast from int to something that doesn't have a standard printf format string.
How about this?
+ printk("Bad block %d at 0x%llx\n", + onenand_block(this, ofs), ofs);
Likewise throughout the rest of the file.
-Scott

Hi Scott,
On Fri, Nov 06, 2009 at 05:17:44PM +0530, Amul Kumar Saha wrote:
- printk("Bad blocks %d at 0x%x\n",
(u32)(ofs >> this->erase_shift), (u32)ofs);
- printk("Bad blocks %lu at 0x%x\n",
(u32)onenand_block(this, ofs), (u32)ofs);
cmd_onenand.c: In function 'onenand_block_read': cmd_onenand.c:103: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'unsigned int'
My bad.
If you must pass a u32 to printf, use "%u" or "%x" -- but it makes little sense to explicitly cast from int to something that doesn't have a standard printf format string.
How about this?
- printk("Bad block %d at 0x%llx\n",
onenand_block(this, ofs), ofs);
Accepted and Corrected.
Likewise throughout the rest of the file.
Yes, there are areas that need sanity clean-ups. I'll send a patch for the same, shortly.
Regards, Amul Kumar Saha

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 Signed-off-by: Amul Kumar Saha amul.saha@samsung.com --- common/cmd_onenand.c | 106 +++++++++++++++++++++++++++++++--------------- include/configs/apollon.h | 2 2 files changed, 74 insertions(+), 34 deletions(-)
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 9090940..d6aff90 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -69,36 +69,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); + printk("Bad blocks %u at 0x%llx\n", + onenand_block(this, ofs), 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); @@ -120,8 +133,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; @@ -135,11 +147,16 @@ 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); + printk("Bad blocks %u at 0x%llx\n", + onenand_block(this, ofs), ofs); skip_ofs += blocksize; goto next; } @@ -169,13 +186,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); + printf("Skip erase bad block %u at 0x%llx\n", + onenand_block(this, ofs), ofs); continue; }
@@ -185,8 +204,8 @@ static int onenand_block_erase(u32 start, u32 size, int force) instr.mtd = mtd; ret = mtd->erase(mtd, &instr); if (ret) { - printf("erase failed block %d at 0x%x\n", - (u32)(ofs >> this->erase_shift), (u32)ofs); + printf("erase failed block %u at 0x%llx\n", + onenand_block(this, ofs), ofs); continue; } } @@ -223,25 +242,28 @@ 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 at 0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs); + printf("\rTesting block %u at 0x%llx", + onenand_block(this, ofs), 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); + printf("Skip erase bad block %u at 0x%llx\n", + onenand_block(this, ofs), ofs); goto next; }
@@ -345,7 +367,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];
@@ -363,9 +384,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; @@ -474,6 +497,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; }
@@ -491,11 +529,13 @@ U_BOOT_CMD( "onenand bad - show bad blocks\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" + "\tread/write 'size' bytes starting at offset 'off'\n" + "\tto/from memory address 'addr', skipping bad blocks.\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" + "\toffset 'off' (entire device if not specified)\n" "onenand dump[.oob] off - dump page\n" "onenand markbad off [...] - mark bad block(s) at offset (UNSAFE)" + "onenand setboundary DIE BOUNDARY [LOCK] - \n" + "\tChange SLC boundary of Flex-OneNAND\n" ); diff --git a/include/configs/apollon.h b/include/configs/apollon.h index ddac5fb..5a97743 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

Dear Amul Kumar Saha,
In message 0870C11EAE73409E8727CAC3891E4DED@sisodomain.com you 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 Signed-off-by: Amul Kumar Saha amul.saha@samsung.com
common/cmd_onenand.c | 106 +++++++++++++++++++++++++++++++--------------- include/configs/apollon.h | 2 2 files changed, 74 insertions(+), 34 deletions(-)
How many versions of these patches did you post so far?
You are supposed to use "[PATCH 3/3 v5]" or similar in the Subject: line to mark the Nth re-submission of the patch.
And what was changed between versions of this patch?
You are supposed to put a change log below the "---" line that explains which changes were made to the previous version of the patch.
Best regards,
Wolfgang Denk

Hi Wolfgang Denk,
Sorry for the late reply.
How many versions of these patches did you post so far?
You are supposed to use "[PATCH 3/3 v5]" or similar in the Subject: line to mark the Nth re-submission of the patch.
I'll make sure that versions are properly displayed with each patch, from next post onwards.
And what was changed between versions of this patch?
You are supposed to put a change log below the "---" line that explains which changes were made to the previous version of the patch.
Accepted.
Should I send the patch again with version updated?
Regards, Amul Kumar Saha
participants (3)
-
Amul Kumar Saha
-
Scott Wood
-
Wolfgang Denk