nand: Add support for unlock.invert
Subsystems (2)
PATCH 1/3 nand: Add support for unlock.invert
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
--- common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 9 ++++++--- include/nand.h | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-)
common/cmd_nand.c +10 -3
@@ -749,11 +749,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])return 0 ; } -if (strcmp (cmd,"unlock" ) ==0 ) { +if (strncmp (cmd,"unlock" ,5 ) ==0 ) { +int invert =0 ; + + s =strchr (cmd,'.' ); + +if (s && !strcmp (s,".invert" )) + invert =1 ; +if (arg_off_size (argc -2 , argv +2 , &dev, &off, &size) <0 )return 1 ; -if (!nand_unlock (&nand_info[dev], off, size)) { +if (!nand_unlock (&nand_info[dev], off, size, invert)) {puts ("NAND flash successfully unlocked\n" ); }else { puts("Error unlocking NAND flash, "
@@ -807,7 +814,7 @@ U_BOOT_CMD("\n" "nand lock [tight] [status]\n" " bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section" + "nand unlock[.invert] [offset] [size] - unlock section"#endif #ifdef CONFIG_ENV_OFFSET_OOB "\n"
drivers/mtd/nand/nand_util.c +6 -3
@@ -317,18 +317,19 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)* @param start start byte address * @param length number of bytes to unlock (must be a multiple of * page size nand->writesize) +* @param invert if set, unlock everything not selected * * @return 0 on success, -1 in case of error */ -int nand_unlock (struct mtd_info *mtd,ulong start,ulong length) +int nand_unlock (struct mtd_info *mtd,ulong start,ulong length,int invert) {int ret =0 ;int chipnr;int status;int page;struct nand_chip *chip = mtd->priv; -printf ("nand_unlock: start: %08x, length: %d!\n" , - (int )start, (int )length); +printf ("nand_unlock%s: start: %08x, length: %d!\n" , + invert ?" (invert)" :"" , (int )start, (int )length);/* select the NAND device */ chipnr = (int )(start >> chip->chip_shift);
@@ -368,6 +369,8 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); +if (invert) + page |=1 ; chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);/* call wait ready function */
include/nand.h +2 -2
@@ -144,8 +144,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);#define NAND_LOCK_STATUS_LOCK 0x02#define NAND_LOCK_STATUS_UNLOCK 0x04 -int nand_lock (nand_info_t *meminfo,int tight ); -int nand_unlock (nand_info_t *meminfo,ulong start,ulong length ); +int nand_lock (nand_info_t *meminfo,int tight); +int nand_unlock (nand_info_t *meminfo,ulong start,ulong length,int invert);int nand_get_lock_status (nand_info_t *meminfo,loff_t offset);int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst);
Signature · 1 line
1.7.11.5
PATCH 2/3 nand: consolidate duplicated constants
NAND_CMD_ constants for lock/unlock should be in the header
--- drivers/mtd/nand/nand_util.c | 6 ------ include/linux/mtd/nand.h | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-)
drivers/mtd/nand/nand_util.c +0 -6
@@ -207,12 +207,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)* Support for locking / unlocking operations of some NAND devices *****************************************************************************/ -#define NAND_CMD_LOCK 0x2a -#define NAND_CMD_LOCK_TIGHT 0x2c -#define NAND_CMD_UNLOCK1 0x23 -#define NAND_CMD_UNLOCK2 0x24 -#define NAND_CMD_LOCK_STATUS 0x7a -/** * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT * state
include/linux/mtd/nand.h +2 -0
@@ -85,8 +85,10 @@ extern void nand_wait_ready(struct mtd_info *mtd);#define NAND_CMD_RESET 0xff#define NAND_CMD_LOCK 0x2a +#define NAND_CMD_LOCK_TIGHT 0x2c#define NAND_CMD_UNLOCK1 0x23#define NAND_CMD_UNLOCK2 0x24 +#define NAND_CMD_LOCK_STATUS 0x7a/* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30
Signature · 1 line
1.7.11.5
PATCH 3/3 nand: Make NAND lock status compatible with Micron
In reply to Joe HershbergerMicron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is not the same as others. Instead of bit 1 being lock, it is #lock_tight. To make the driver support either format, ignore bit 1 and use only bit 0 and bit 2.
--- common/cmd_nand.c | 2 +- drivers/mtd/nand/nand_util.c | 2 -- include/nand.h | 1 - 3 files changed, 1 insertion(+), 4 deletions(-)
common/cmd_nand.c +1 -1
@@ -236,7 +236,7 @@ static void print_status(ulong start, ulong end, ulong erasesize, int status) end -1 , (end - start) / erasesize, ((status &NAND_LOCK_STATUS_TIGHT ) ?"TIGHT " :"" ), - ((status &NAND_LOCK_STATUS_LOCK ) ?"LOCK " :"" ), + (!(status &NAND_LOCK_STATUS_UNLOCK ) ?"LOCK " :"" ), ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); }
drivers/mtd/nand/nand_util.c +0 -2
@@ -265,7 +265,6 @@ int nand_lock(struct mtd_info *mtd, int tight)* >0 lock status: * bitfield with the following combinations: * NAND_LOCK_STATUS_TIGHT: page in tight state -* NAND_LOCK_STATUS_LOCK: page locked * NAND_LOCK_STATUS_UNLOCK: page unlocked * */
@@ -294,7 +293,6 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) chip->cmdfunc (mtd,NAND_CMD_LOCK_STATUS ,-1 , page & chip->pagemask); ret = chip->read_byte (mtd) & (NAND_LOCK_STATUS_TIGHT - |NAND_LOCK_STATUS_LOCK |NAND_LOCK_STATUS_UNLOCK ); out:
include/nand.h +0 -1
@@ -141,7 +141,6 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,int nand_erase_opts (nand_info_t *meminfo,const nand_erase_options_t *opts);#define NAND_LOCK_STATUS_TIGHT 0x01 -#define NAND_LOCK_STATUS_LOCK 0x02#define NAND_LOCK_STATUS_UNLOCK 0x04int nand_lock (nand_info_t *meminfo,int tight);
Signature · 1 line
1.7.11.5
PATCH 3/3 nand: Make NAND lock status compatible with Micron
Quoted 4 lines · Joe Hershberger
Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is not the same as others. Instead of bit 1 being lock, it is #lock_tight. To make the driver support either format, ignore bit 1 and use only bit 0 and bit 2.
Please put a comment in the code as to why we're doing this.
-Scott
PATCH 1/3 nand: Add support for unlock.invert
In reply to Joe HershbergerQuoted 17 lines · Joe Hershberger
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
Signed-off-by Joe Hershberger <[email protected]>--- common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 9 ++++++--- include/nand.h | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-)common/cmd_nand.c +0
-0@@ -749,11 +749,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])return 0 ; }
common/cmd_nand.c int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) · line 759
Quoted 10 lines
common/cmd_nand.c +8
-1-if (strcmp (cmd,"unlock" ) ==0 ) { +if (strncmp (cmd,"unlock" ,5 ) ==0 ) { +int invert =0 ; + + s =strchr (cmd,'.' ); + +if (s && !strcmp (s,".invert" )) + invert =1 ; +
How about something like ".allexcept"? "Invert" is less clear about what's being inverted.
Quoted 22 lines
common/cmd_nand.c +2
-2if (arg_off_size (argc -2 , argv +2 , &dev, &off, &size) <0 )return 1 ; -if (!nand_unlock (&nand_info[dev], off, size)) { +if (!nand_unlock (&nand_info[dev], off, size, invert)) {puts ("NAND flash successfully unlocked\n" ); }else { puts("Error unlocking NAND flash, "@@ -807,7 +814,7 @@ U_BOOT_CMD("\n" "nand lock [tight] [status]\n" " bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section" + "nand unlock[.invert] [offset] [size] - unlock section"#endif #ifdef CONFIG_ENV_OFFSET_OOB "\n" drivers/mtd/nand/nand_util.c +0
-0
drivers/mtd/nand/nand_util.c int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) · line 324
Quoted 9 lines
drivers/mtd/nand/nand_util.c +2
-1@@ -317,18 +317,19 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)* @param start start byte address * @param length number of bytes to unlock (must be a multiple of * page size nand->writesize) +* @param invert if set, unlock everything not selected * * @return 0 on success, -1 in case of error */ -int nand_unlock (struct mtd_info *mtd,ulong start,ulong length) +int nand_unlock (struct mtd_info *mtd,ulong start,ulong length,int invert)
Hmm, seems this got missed in the loff_t conversion.
drivers/mtd/nand/nand_util.c int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) · line 332
Quoted 10 lines
drivers/mtd/nand/nand_util.c +2
-2{int ret =0 ;int chipnr;int status;int page;struct nand_chip *chip = mtd->priv; -printf ("nand_unlock: start: %08x, length: %d!\n" , - (int )start, (int )length); +printf ("nand_unlock%s: start: %08x, length: %d!\n" , + invert ?" (invert)" :"" , (int )start, (int )length);
This looks like it should be a debug message rather than a normal printf (and the (int) casts should go).
drivers/mtd/nand/nand_util.c int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) · line 374
Quoted 9 lines
drivers/mtd/nand/nand_util.c +2
-0/* select the NAND device */ chipnr = (int )(start >> chip->chip_shift);@@ -368,6 +369,8 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); +if (invert) + page |=1 ; chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);
Why |= 1? Is this some magic that the chip recognizes to implement "invert"? Do all chips that support lock/unlock support this (none of the NAND chip manuals I have document lock/unlock at all as far as I could find)? What if you want to unlock a non-inverted range that ends in a page with the low bit set?
-Scott
PATCH 1/3 nand: Add support for unlock.invert
Hi Scott,
Quoted 13 lines · Scott Wood
Quoted 12 lines · Joe Hershberger
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
Signed-off-by Joe Hershberger <[email protected]>--- common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 9 ++++++--- include/nand.h | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-)(quoted diff) +0
-0@@ -368,6 +369,8 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)
Quoted 11 lines
drivers/mtd/nand/nand_util.c int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) · line 374
Quoted 5 lines
drivers/mtd/nand/nand_util.c +2
-0/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); +if (invert) + page |=1 ; chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);Why |= 1? Is this some magic that the chip recognizes to implement "invert"? Do all chips that support lock/unlock support this (none of the NAND chip manuals I have document lock/unlock at all as far as I could find)? What if you want to unlock a non-inverted range that ends in a page with the low bit set?
According to the data sheet for the part I'm working with (MT29F4G08ABADAH4) the unlock command has 2 commands... 0x23 and 0x24.
The invert bit only exists for 0x24 (NAND_CMD_UNLOCK2). The format
of the unlock commands specifys that block addresses are used, therefore the LSb would never be set. This bit-0 is defined to be "invert area" for 0x24 and always LOW for 0x23.
-Joe
PATCH 1/3 nand: Add support for unlock.invert
Quoted 28 lines · Joe Hershberger
Hi Scott,
Quoted 13 lines · Scott Wood
Quoted 12 lines · Joe Hershberger
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
Signed-off-by Joe Hershberger <[email protected]>--- common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 9 ++++++--- include/nand.h | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-)(quoted diff) +0
-0@@ -368,6 +369,8 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)Quoted 11 lines
drivers/mtd/nand/nand_util.c int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) · line 374
Quoted 5 lines
drivers/mtd/nand/nand_util.c +2
-0/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); +if (invert) + page |=1 ; chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);Why |= 1? Is this some magic that the chip recognizes to implement "invert"? Do all chips that support lock/unlock support this (none of the NAND chip manuals I have document lock/unlock at all as far as I could find)? What if you want to unlock a non-inverted range that ends in a page with the low bit set?
Quoted 6 lines
According to the data sheet for the part I'm working with (MT29F4G08ABADAH4) the unlock command has 2 commands...
0x23and0x24.
The invert bit only exists for0x24(NAND_CMD_UNLOCK2). The format
of the unlock commands specifys that block addresses are used, therefore the LSb would never be set. This bit-0 is defined to be "invert area" for0x24and always LOW for0x23.
Please add a code comment to this effect.
-Scott
PATCH 1/3 nand: Add support for unlock.invert
Hi Scott,
Quoted 29 lines · Scott Wood
Quoted 28 lines · Joe Hershberger
Hi Scott,
Quoted 24 lines · Scott Wood
Quoted 11 lines · Joe Hershberger
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
Signed-off-by Joe Hershberger <[email protected]>--- common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 9 ++++++--- include/nand.h | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-)drivers/mtd/nand/nand_util.c int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) · line 374
Quoted 6 lines
drivers/mtd/nand/nand_util.c +2
-0@@ -368,6 +369,8 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); +if (invert) + page |=1 ; chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);Why |= 1? Is this some magic that the chip recognizes to implement "invert"? Do all chips that support lock/unlock support this (none of the NAND chip manuals I have document lock/unlock at all as far as I could find)? What if you want to unlock a non-inverted range that ends in a page with the low bit set?
Quoted 8 lines
Quoted 6 lines
According to the data sheet for the part I'm working with (MT29F4G08ABADAH4) the unlock command has 2 commands...
0x23and0x24.
The invert bit only exists for0x24(NAND_CMD_UNLOCK2). The format
of the unlock commands specifys that block addresses are used, therefore the LSb would never be set. This bit-0 is defined to be "invert area" for0x24and always LOW for0x23.Please add a code comment to this effect.
This is what the code does... Can you recommend a comment that you would like?
Thanks,
-Joe
PATCH v2 1/4 nand: Add support for unlock.invert
In reply to Joe HershbergerNAND unlock command allows an invert bit to be set to unlock all but the selected page range.
---
Changes in v2:
- Changed invert to allexcept
- Changed unlock printf to debug print
- Dropped cast in unlock debug print
common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 10 +++++++--- include/nand.h | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-)
common/cmd_nand.c +10 -3
@@ -749,11 +749,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])return 0 ; } -if (strcmp (cmd,"unlock" ) ==0 ) { +if (strncmp (cmd,"unlock" ,5 ) ==0 ) { +int allexcept =0 ; + + s =strchr (cmd,'.' ); + +if (s && !strcmp (s,".allexcept" )) + allexcept =1 ; +if (arg_off_size (argc -2 , argv +2 , &dev, &off, &size) <0 )return 1 ; -if (!nand_unlock (&nand_info[dev], off, size)) { +if (!nand_unlock (&nand_info[dev], off, size, allexcept)) {puts ("NAND flash successfully unlocked\n" ); }else { puts("Error unlocking NAND flash, "
@@ -807,7 +814,7 @@ U_BOOT_CMD("\n" "nand lock [tight] [status]\n" " bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section" + "nand unlock[.allexcept] [offset] [size] - unlock section"#endif #ifdef CONFIG_ENV_OFFSET_OOB "\n"
drivers/mtd/nand/nand_util.c +7 -3
@@ -317,18 +317,20 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)* @param start start byte address * @param length number of bytes to unlock (must be a multiple of * page size nand->writesize) +* @param allexcept if set, unlock everything not selected * * @return 0 on success, -1 in case of error */ -int nand_unlock (struct mtd_info *mtd,ulong start,ulong length) +int nand_unlock (struct mtd_info *mtd,ulong start,ulong length,int allexcept) {int ret =0 ;int chipnr;int status;int page;struct nand_chip *chip = mtd->priv; -printf ("nand_unlock: start: %08x, length: %d!\n" , - (int )start, (int )length); + +debug ("nand_unlock%s: start: %08x, length: %d!\n" , + allexcept ?" (allexcept)" :"" , start, length);/* select the NAND device */ chipnr = (int )(start >> chip->chip_shift);
@@ -368,6 +370,8 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); +if (allexcept) + page |=1 ; chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);/* call wait ready function */
include/nand.h +2 -2
@@ -144,8 +144,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);#define NAND_LOCK_STATUS_LOCK 0x02#define NAND_LOCK_STATUS_UNLOCK 0x04 -int nand_lock (nand_info_t *meminfo,int tight ); -int nand_unlock (nand_info_t *meminfo,ulong start,ulong length ); +int nand_lock (nand_info_t *meminfo,int tight); +int nand_unlock (nand_info_t *meminfo,ulong start,ulong length,int allexcept);int nand_get_lock_status (nand_info_t *meminfo,loff_t offset);int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst);
Signature · 1 line
1.7.11.5
PATCH v2 2/4 nand: Change ulong to loff_t and size_t
Missed in previous cleanup.
---
Changes in v2:
- Added loff_t cleanup to series
drivers/mtd/nand/nand_util.c | 5 +++-- include/nand.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-)
drivers/mtd/nand/nand_util.c +3 -2
@@ -321,7 +321,8 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)* * @return 0 on success, -1 in case of error */ -int nand_unlock (struct mtd_info *mtd,ulong start,ulong length,int allexcept) +int nand_unlock (struct mtd_info *mtd,loff_t start,size_t length, +int allexcept) {int ret =0 ;int chipnr;
@@ -329,7 +330,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept)int page;struct nand_chip *chip = mtd->priv; -debug ("nand_unlock%s: start: %08x, length: %d!\n" , +debug ("nand_unlock%s: start: %08llx, length: %d!\n" , allexcept ?" (allexcept)" :"" , start, length);/* select the NAND device */
include/nand.h +2 -1
@@ -145,7 +145,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);#define NAND_LOCK_STATUS_UNLOCK 0x04int nand_lock (nand_info_t *meminfo,int tight); -int nand_unlock (nand_info_t *meminfo,ulong start,ulong length,int allexcept); +int nand_unlock (nand_info_t *meminfo,loff_t start,size_t length, +int allexcept);int nand_get_lock_status (nand_info_t *meminfo,loff_t offset);int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst);
Signature · 1 line
1.7.11.5
PATCH v2 2/4 nand: Change ulong to loff_t and size_t
Quoted 10 lines · Joe Hershberger
Missed in previous cleanup.
Signed-off-by Joe Hershberger <[email protected]>---
Changes in v2:
- Addedloff_tcleanup to seriesdrivers/mtd/nand/nand_util.c | 5 +++-- include/nand.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-)
Applied to u-boot-nand-flash.
-Scott
PATCH v2 3/4 nand: consolidate duplicated constants
In reply to Joe HershbergerNAND_CMD_ constants for lock/unlock should be in the header
---
drivers/mtd/nand/nand_util.c | 6 ------ include/linux/mtd/nand.h | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-)
drivers/mtd/nand/nand_util.c +0 -6
@@ -207,12 +207,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)* Support for locking / unlocking operations of some NAND devices *****************************************************************************/ -#define NAND_CMD_LOCK 0x2a -#define NAND_CMD_LOCK_TIGHT 0x2c -#define NAND_CMD_UNLOCK1 0x23 -#define NAND_CMD_UNLOCK2 0x24 -#define NAND_CMD_LOCK_STATUS 0x7a -/** * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT * state
include/linux/mtd/nand.h +2 -0
@@ -85,8 +85,10 @@ extern void nand_wait_ready(struct mtd_info *mtd);#define NAND_CMD_RESET 0xff#define NAND_CMD_LOCK 0x2a +#define NAND_CMD_LOCK_TIGHT 0x2c#define NAND_CMD_UNLOCK1 0x23#define NAND_CMD_UNLOCK2 0x24 +#define NAND_CMD_LOCK_STATUS 0x7a/* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30
Signature · 1 line
1.7.11.5
PATCH v2 3/4 nand: consolidate duplicated constants
Quoted 8 lines · Joe Hershberger
NAND_CMD_constants for lock/unlock should be in the headerSigned-off-by Joe Hershberger <[email protected]>---
drivers/mtd/nand/nand_util.c | 6 ------ include/linux/mtd/nand.h | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-)
Applied to u-boot-nand-flash.
-Scott
PATCH v2 4/4 nand: Make NAND lock status compatible with Micron
In reply to Joe HershbergerMicron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is not the same as others. Instead of bit 1 being lock, it is #lock_tight. To make the driver support either format, ignore bit 1 and use only bit 0 and bit 2.
---
Changes in v2:
- Added comment about NAND status work-around
common/cmd_nand.c | 8 +++++++- drivers/mtd/nand/nand_util.c | 2 -- include/nand.h | 1 - 3 files changed, 7 insertions(+), 4 deletions(-)
common/cmd_nand.c +7 -1
@@ -231,12 +231,18 @@ print:#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status (ulong start,ulong end,ulong erasesize,int status) { +/* +* Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is +* not the same as others. Instead of bit 1 being lock, it is +* #lock_tight. To make the driver support either format, ignore bit 1 +* and use only bit 0 and bit 2. +*/ printf ("%08lx - %08lx: %08lx blocks %s%s%s\n" , start, end -1 , (end - start) / erasesize, ((status &NAND_LOCK_STATUS_TIGHT ) ?"TIGHT " :"" ), - ((status &NAND_LOCK_STATUS_LOCK ) ?"LOCK " :"" ), + (!(status &NAND_LOCK_STATUS_UNLOCK ) ?"LOCK " :"" ), ((status &NAND_LOCK_STATUS_UNLOCK ) ?"UNLOCK " :"" )); }
drivers/mtd/nand/nand_util.c +0 -2
@@ -265,7 +265,6 @@ int nand_lock(struct mtd_info *mtd, int tight)* >0 lock status: * bitfield with the following combinations: * NAND_LOCK_STATUS_TIGHT: page in tight state -* NAND_LOCK_STATUS_LOCK: page locked * NAND_LOCK_STATUS_UNLOCK: page unlocked * */
@@ -294,7 +293,6 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) chip->cmdfunc (mtd,NAND_CMD_LOCK_STATUS ,-1 , page & chip->pagemask); ret = chip->read_byte (mtd) & (NAND_LOCK_STATUS_TIGHT - |NAND_LOCK_STATUS_LOCK |NAND_LOCK_STATUS_UNLOCK ); out:
include/nand.h +0 -1
@@ -141,7 +141,6 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,int nand_erase_opts (nand_info_t *meminfo,const nand_erase_options_t *opts);#define NAND_LOCK_STATUS_TIGHT 0x01 -#define NAND_LOCK_STATUS_LOCK 0x02#define NAND_LOCK_STATUS_UNLOCK 0x04int nand_lock (nand_info_t *meminfo,int tight);
Signature · 1 line
1.7.11.5
PATCH v2 4/4 nand: Make NAND lock status compatible with Micron
Quoted 6 lines · Joe Hershberger
Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is not the same as others. Instead of bit 1 being lock, it is #lock_tight. To make the driver support either format, ignore bit 1 and use only bit 0 and bit 2.
Signed-off-by Joe Hershberger <[email protected]>
Quoted 8 lines
---
Changes in v2:
- Added comment about NAND status work-aroundcommon/cmd_nand.c | 8 +++++++- drivers/mtd/nand/nand_util.c | 2 -- include/nand.h | 1 - 3 files changed, 7 insertions(+), 4 deletions(-)
Applied to u-boot-nand-flash.
-Scott
PATCH v2 1/4 nand: Add support for unlock.invert
In reply to Joe HershbergerQuoted 10 lines · Joe Hershberger
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
Signed-off-by Joe Hershberger <[email protected]>---
Changes in v2:
- Changed invert to allexcept
- Changed unlock printf to debug print
- Dropped cast in unlock debug print
Quoted 4 lines
common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 10 +++++++--- include/nand.h | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-)
Applied to u-boot-nand-flash with the diff below. Do you know if all chips that support locking support the invert bit? If not, we should at least update the documentation to mention this (though runtime detection would be good if practical).
doc/README.nand +2 -0
@@ -228,6 +228,8 @@ NAND locking command (for chips with active LOCKPRE pin) "nand unlock [offset] [size]" unlock consecutive area (can be called multiple times for different areas) + "nand unlock.allexcept [offset] [size]" + unlock all except specified consecutive area I have tested the code with board containing 128MiB NAND large page chips and 32MiB small page chips.
drivers/mtd/nand/nand_util.c +7 -0
@@ -370,8 +370,15 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept)/* submit ADDRESS of LAST page to unlock */ page += (int )(length >> chip->page_shift); + +/* +* Page addresses for unlocking are supposed to be block-aligned. +* At least some NAND chips use the low bit to indicate that the +* page range should be inverted. +*/ if (allexcept) page |=1 ; + chip->cmdfunc (mtd,NAND_CMD_UNLOCK2 ,-1 , page & chip->pagemask);/* call wait ready function */
-Scott
PATCH v2 1/4 nand: Add support for unlock.invert
Hi Scott,
Quoted 16 lines · Scott Wood
Quoted 10 lines · Joe Hershberger
NAND unlock command allows an invert bit to be set to unlock all but the selected page range.
Signed-off-by Joe Hershberger <[email protected]>---
Changes in v2:
- Changed invert to allexcept
- Changed unlock printf to debug print
- Dropped cast in unlock debug printQuoted 4 lines
common/cmd_nand.c | 13 ++++++++++--- drivers/mtd/nand/nand_util.c | 10 +++++++--- include/nand.h | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-)
Quoted 4 lines
Applied to u-boot-nand-flash with the diff below. Do you know if all chips that support locking support the invert bit? If not, we should at least update the documentation to mention this (though runtime detection would be good if practical).
I'm not aware of a part that supports lock and not the invert functionality. I'm also not aware of a way to detect at runtime if it is supported.
Thanks,
-Joe