Flex-OneNAND boundary setting command
PATCH v2 4/4 Flex-OneNAND boundary setting command
Add command for changing Flex-OneNAND SLC / MLC boundary.
--- common/cmd_onenand.c | 65 +++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 56 insertions(+), 9 deletions(-)
common/cmd_onenand.c +56 -9
@@ -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" );
Signature · 1 line
1.5.4.3
PATCH v2 4/4 Flex-OneNAND boundary setting command
Quoted 2 lines · 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.
--- common/cmd_onenand.c | 88 ++++++++++++++++++++++++++++++++-------------- include/configs/apollon.h | 2 - 2 files changed, 64 insertions(+), 26 deletions(-)
include/configs/apollon.h +1 -1
@@ -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
common/cmd_onenand.c +63 -25
194 lines not on this page · raw message
PATCH v2 4/4 Flex-OneNAND boundary setting command
common/cmd_onenand.c static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size) · line 77
Quoted 10 lines · Rohit Hagargundgi
common/cmd_onenand.c +10
-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;
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?
Quoted 4 lines
common/cmd_onenand.c +4
-0+if (strncmp (cmd,"setboundary" ,11 ) ==0 ) { +int die, bdry, lock =0 ; + +if (argc <4 )
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 496
Quoted 10 lines
common/cmd_onenand.c +10
-0+ 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?
common/cmd_onenand.c U_BOOT_CMD( · line 517
Quoted 10 lines
common/cmd_onenand.c +2
-1+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
PATCH v2 4/4 Flex-OneNAND boundary setting command
Hi Scott,
Quoted 6 lines
Quoted 6 lines
(quoted diff) +6
-0+static inline int onenand_blocksize(loff_t ofs) +{ + struct onenand_chip *this = mtd->priv; + int i; + + if (!FLEXONENAND(this))
Quoted 9 lines
Quoted 4 lines
+ 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.
Quoted 9 lines
Quoted 9 lines
+ if (
strncmp(cmd, "setboundary", 11)== 0) {
+ int die, bdry, lock = 0;(quoted diff) +7
-0+ + if (argc < 4) + goto usage; + + die = (int) simple_strtoul(argv[2], NULL, 0); + bdry = (int) simple_strtoul(argv[3], NULL, 0); +
Quoted 9 lines
Quoted 5 lines
+ if (argc == 5 &&
strncmp(argv[4], "LOCK", 4)== 0)
+ lock = 1;
+
+ returnflexonenand_set_boundary(mtd, die, bdry, lock);
+ }What happens if the user runs the setboundary command on non-flex onenand? Does it fail gracefully?
Resolved.
Quoted 4 lines
Quoted 4 lines
+
break;
}
Quoted 9 lines
Review U_BOOT_CMD( · line 517
Quoted 6 lines
(quoted diff) +1
-1@@ -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
--- common/cmd_onenand.c | 103 ++++++++++++++++++++++++++++++++-------------- include/configs/apollon.h | 2 2 files changed, 74 insertions(+), 31 deletions(-)
common/cmd_onenand.c +73 -30
@@ -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" );
include/configs/apollon.h +1 -1
@@ -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
PATCH v2 4/4 Flex-OneNAND boundary setting command
common/cmd_onenand.c static int arg_off_size(int argc, char *argv[], ulong · line 72
Quoted 13 lines · Amul Kumar Saha
common/cmd_onenand.c +4
-0@@ -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).
common/cmd_onenand.c static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size) · line 85
Quoted 2 lines
common/cmd_onenand.c +2
-0+int blocks = (int )onenand_block (this, from + len) + -onenand_block (this, from);
Why the (int) cast? onenand_block() already returns int.
common/cmd_onenand.c static int onenand_block_test(u32 start, u32 size) · line 248
Quoted 4 lines
common/cmd_onenand.c +2
-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);
This should probably be:
if (end_block >= onenand_block(this, mtd->size - 1))
...to avoid asking for a block that doesn't exist.
common/cmd_onenand.c static int arg_off_size(int argc, char *argv[], ulong · line 82
Quoted 7 lines
common/cmd_onenand.c +1
-1blocks = 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.
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, · line 387
Quoted 12 lines
common/cmd_onenand.c +3
-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); }
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.
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 494
Quoted 2 lines
common/cmd_onenand.c +2
-0+ die = (int )simple_strtoul (argv[2 ],NULL ,0 ); + bdry = (int )simple_strtoul (argv[3 ],NULL ,0 );
Casts should not be necessary.
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 497
Quoted 2 lines
common/cmd_onenand.c +2
-0+if (argc ==5 &&strncmp (argv[4 ],"LOCK" ,4 ) ==0 ) + lock =1 ;
Please have commands be lower-case, just like all the other ones.
-Scott
PATCH v2 4/4 Flex-OneNAND boundary setting command
In reply to Scott WoodHi Scott,
Quoted 6 lines
Quoted 3 lines
+ int blocks = (int)
onenand_block(this, from + len)
+ -onenand_block(this, from);Why the (int) cast?
onenand_block()already returns int.
Resolved
Quoted 11 lines
common/cmd_onenand.c static int onenand_block_test(u32 start, u32 size) · line 248
Quoted 4 lines
- if (
end_block> (mtd->size>>this->erase_shift))common/cmd_onenand.c +2
-1- 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.
Quoted 10 lines
Quoted 7 lines
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.
Quoted 11 lines
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 386
Quoted 6 lines
common/cmd_onenand.c +3
-0+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);
}
Quoted 5 lines
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 490
Quoted 2 lines
common/cmd_onenand.c +2
-0+ 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.
Quoted 5 lines
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 493
Quoted 2 lines
common/cmd_onenand.c +2
-0+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
PATCH v2 4/4 Flex-OneNAND boundary setting command
Quoted 8 lines · Amul Kumar Saha
Quoted 5 lines
common/cmd_onenand.c int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) · line 490
Quoted 2 lines
common/cmd_onenand.c +2
-0+ 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
PATCH v2 4/4 Flex-OneNAND boundary setting command
Hi Scott,
Quoted 5 lines
Quoted 2 lines
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.
PATCH v2 4/4 Flex-OneNAND boundary setting command
In reply to Scott WoodOneNAND commands now work for Flex-OneNAND.
Add command for changing Flex-OneNAND SLC / MLC boundary.
---common/cmd_onenand.c | 103 ++++++++++++++++++++++++++++++++--------------include/configs/apollon.h | 2
2 files changed, 73 insertions(+), 32 deletions(-)
common/cmd_onenand.c +72 -31
@@ -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" );
include/configs/apollon.h +1 -1
@@ -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