Re: [U-Boot] [PATCH] Flex-OneNAND driver
On Thu, Nov 06, 2008 at 08:59:06AM +0530, Amit Kumar Sharma wrote: > We can provide two device registration for SLC and MLC are > but I don't know how useful it is because FlexOneNand > provides boundary settings and user can configure SLC and > MLC area and other point is still device registration is > separate how user will get any gain as it will be on same > die. The intent was to avoid having the command-line wrapper handle implementation details such as boundary calculations. I don't really care whether it's one device or two, but the front-end user of the flash shouldn't have to know such details. -Scott ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Hi We can provide two device registration for SLC and MLC are but I don't know how useful it is because FlexOneNand provides boundary settings and user can configure SLC and MLC area and other point is still device registration is separate how user will get any gain as it will be on same die. Regards Amit - Original Message - From: "Scott Wood" <[EMAIL PROTECTED]> To: "apgmoorthy" <[EMAIL PROTECTED]> Cc: Sent: Thursday, October 23, 2008 4:39 AM Subject: Re: [U-Boot] [PATCH] Flex-OneNAND driver > On Mon, Sep 22, 2008 at 11:58:51AM +0530, apgmoorthy > wrote: >> Hi All, >> This patch adds support for Samsung Flex-OneNAND devices. >> >> Flex-OneNAND combines SLC and MLC technologies into a >> single >> device. SLC area provides increased reliability and >> speed, suitable >> for storing code and data, such as bootloader, kernel >> and root file system. MLC area provides high density and >> is best used >> for storing user data. Users can configure the size of >> SLC and MLC >> regions through 'onenand setboundary' command. >> >> Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> > > Sorry for the late reply... > >> extern struct mtd_info onenand_mtd; >> extern struct onenand_chip onenand_chip; >> +loff_t flexonenand_get_addr(int block) > > Space before function declarations. > >> + for (block = start; block <= end; block++) { >> + if (FLEXONENAND(this)) >> + instr.addr = flexonenand_get_addr(block); >> + else >> + instr.addr = block << onenand_chip.erase_shift; >> + >> + if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) { >> + for (i = 0; i < mtd->numeraseregions && >> + mtd->eraseregions[i].offset <= instr.addr; >> i++) > > Patch is line-wrapped. > > Can some of this be abstracted through the driver > interface, rather than > putting a bunch of stuff into what should be a relatively > straightforward > command-line wrapper? > > Perhaps the two regions should be exposed as separate > devices. > > -Scott > ___ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Hi, Kyungmin Park wrote: >> Why? If it's dynamic changes to the boundary that concern you, you could >> tear down the device(s) and re-initialize. > > Okay consider that add reset or reprobe command to do this > We can expose Flex-OneNAND as a SLC device and a MLC device by having two mtd_info structures. The difference between the two devices is block size only. 1. This makes user aware of SLC and MLC areas. 2. We expose two devices where as there is a single physical device. Also, MTD provides erase regions capability for such devices ie which have many erase regions. Exposing as two devices reduces code by removing code for erase regions, but only little. Also other support for Flex-OneNAND is still needed ie - all 4KB dataram is used during read/write. - read/write oob-only commands are not present. - LSB recovery for MLC area read failure - 4 ecc registers >> Of course, I may simply be missing something about how this hardware works. >> >>> Also, comments from MTD mailing list have been included. >> If this is going to go into Linux, perhaps we should wait until it is merged >> there and then import the result? > > It's almost done and wait to merge into MTD tree. > As I mentioned. First merge MTD tree and then U-Boot tree. > >> At least, I'd like Kyungmin Park's ack for OneNAND stuff. > > Basically I acked this patch. I'll repost after MTD merge. Thanks, Rohit ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
On Tue, Oct 28, 2008 at 01:53:24PM +0900, Kyungmin Park wrote: > > Of course, I may simply be missing something about how this hardware works. > > > >> Also, comments from MTD mailing list have been included. > > > > If this is going to go into Linux, perhaps we should wait until it is merged > > there and then import the result? > > It's almost done and wait to merge into MTD tree. > As I mentioned. First merge MTD tree and then U-Boot tree. > > > > > At least, I'd like Kyungmin Park's ack for OneNAND stuff. > > Basically I acked this patch. OK, I missed it. I assume someone will resubmit once it's been merged in Linux? -Scott ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
> > Why? If it's dynamic changes to the boundary that concern you, you could > tear down the device(s) and re-initialize. Okay consider that add reset or reprobe command to do this > > Of course, I may simply be missing something about how this hardware works. > >> Also, comments from MTD mailing list have been included. > > If this is going to go into Linux, perhaps we should wait until it is merged > there and then import the result? It's almost done and wait to merge into MTD tree. As I mentioned. First merge MTD tree and then U-Boot tree. > > At least, I'd like Kyungmin Park's ack for OneNAND stuff. Basically I acked this patch. Thank you, Kyungmin Park ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
On Fri, Oct 24, 2008 at 07:20:12PM +0530, Rohit wrote: > On DDP Flex-OneNAND, regions can be 1, 2, 3 or 4 based on boundary setting. > Exposing as separate devices will be bit complex in these scenarios. Why? If it's dynamic changes to the boundary that concern you, you could tear down the device(s) and re-initialize. Of course, I may simply be missing something about how this hardware works. > Also, comments from MTD mailing list have been included. If this is going to go into Linux, perhaps we should wait until it is merged there and then import the result? At least, I'd like Kyungmin Park's ack for OneNAND stuff. -Scott ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Hi Scott, Thanks for the comments. Scott Wood wrote: > On Mon, Sep 22, 2008 at 11:58:51AM +0530, apgmoorthy wrote: >> Hi All, >> This patch adds support for Samsung Flex-OneNAND devices. >> >> Flex-OneNAND combines SLC and MLC technologies into a single >> device. SLC area provides increased reliability and speed, suitable >> for storing code and data, such as bootloader, kernel >> and root file system. MLC area provides high density and is best used >> for storing user data. Users can configure the size of SLC and MLC >> regions through 'onenand setboundary' command. >> >> Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> > > Sorry for the late reply... > >> extern struct mtd_info onenand_mtd; >> extern struct onenand_chip onenand_chip; >> +loff_t flexonenand_get_addr(int block) > > Space before function declarations. Ok. > >> +for (block = start; block <= end; block++) { >> +if (FLEXONENAND(this)) >> +instr.addr = flexonenand_get_addr(block); >> +else >> +instr.addr = block << onenand_chip.erase_shift; >> + >> +if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) { >> +for (i = 0; i < mtd->numeraseregions && >> +mtd->eraseregions[i].offset <= instr.addr; >> i++) > > Patch is line-wrapped. Sorry. Fixed it now. > > Can some of this be abstracted through the driver interface, rather than > putting a bunch of stuff into what should be a relatively straightforward > command-line wrapper? Ok. Now it is simplified. > Perhaps the two regions should be exposed as separate devices. On DDP Flex-OneNAND, regions can be 1, 2, 3 or 4 based on boundary setting. Exposing as separate devices will be bit complex in these scenarios. Also, comments from MTD mailing list have been included. Thanks, Rohit Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> --- diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 8d87b78..59f047a 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -21,8 +21,71 @@ extern struct mtd_info onenand_mtd; extern struct onenand_chip onenand_chip; +static loff_t flexonenand_get_addr(int block) +{ + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; + loff_t ofs; + int die = 0, boundary; + + ofs = 0; + if (this->dies == 2 && block >= this->density_mask) { + block -= this->density_mask; + die = 1; + ofs = this->diesize[0]; + } + boundary = this->boundary[die]; + ofs += block << (this->erase_shift - 1); + if (block > (boundary + 1)) + ofs += (block - boundary - 1) << (this->erase_shift - 1); + return ofs; +} + +static inline loff_t onenand_get_addr(int block) +{ + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; + + if (!FLEXONENAND(this)) + return block << onenand_chip.erase_shift; + return flexonenand_get_addr(block); +} + +static int do_erase(ulong start, ulong end) +{ + struct mtd_info *mtd = &onenand_mtd; + struct erase_info instr = { + .callback = NULL, + }; + int i, ret; + ulong block; + + printf("Erase block from %lu to %lu\n", start, end); + + for (block = start; block <= end; block++) { + instr.addr = onenand_get_addr(block); + if (mtd->numeraseregions > 1) { + i = flexonenand_region(mtd, instr.addr); + instr.len = mtd->eraseregions[i].erasesize; + } else + instr.len = mtd->erasesize; + + if (mtd->block_isbad(mtd, instr.addr)) { + printf("Skipping bad block %lu\n", block); + continue; + } + + ret = mtd->erase(&onenand_mtd, &instr); + if (ret) + printf("erase failed %lu\n", block); + } + return 0; +} + 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) { @@ -42,11 +105,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) default: /* At least 4 args */ if (strncmp(argv[1], "erase", 5) == 0) { - struct erase_info instr = { - .callback = NULL, - }; ulong start, end; - ulong block; char *endtail; if (strncmp(argv[2], "block", 5) == 0) { @@ -57,28 +116,18 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) start = simple_strtoul(argv[2], NULL, 10);
Re: [U-Boot] [PATCH] Flex-OneNAND driver
On Mon, Sep 22, 2008 at 11:58:51AM +0530, apgmoorthy wrote: > Hi All, > This patch adds support for Samsung Flex-OneNAND devices. > > Flex-OneNAND combines SLC and MLC technologies into a single > device. SLC area provides increased reliability and speed, suitable > for storing code and data, such as bootloader, kernel > and root file system. MLC area provides high density and is best used > for storing user data. Users can configure the size of SLC and MLC > regions through 'onenand setboundary' command. > > Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> Sorry for the late reply... > extern struct mtd_info onenand_mtd; > extern struct onenand_chip onenand_chip; > +loff_t flexonenand_get_addr(int block) Space before function declarations. > + for (block = start; block <= end; block++) { > + if (FLEXONENAND(this)) > + instr.addr = flexonenand_get_addr(block); > + else > + instr.addr = block << onenand_chip.erase_shift; > + > + if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) { > + for (i = 0; i < mtd->numeraseregions && > + mtd->eraseregions[i].offset <= instr.addr; > i++) Patch is line-wrapped. Can some of this be abstracted through the driver interface, rather than putting a bunch of stuff into what should be a relatively straightforward command-line wrapper? Perhaps the two regions should be exposed as separate devices. -Scott ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Hi Kyungmin, Thank you for the comments. Kyungmin Park wrote: >> diff --git a/common/env_onenand.c b/common/env_onenand.c >> --- a/common/env_onenand.c >> +++ b/common/env_onenand.c >> @@ -58,11 +58,14 @@ >> >> void env_relocate_spec(void) >> { >> + struct onenand_chip *this = &onenand_chip; >>unsigned long env_addr; >>int use_default = 0; >>size_t retlen; >> >>env_addr = CONFIG_ENV_ADDR; >> + if (FLEXONENAND(this)) >> + env_addr = CONFIG_ENV_ADDR_FLEX; >> > > Umm do you have more fancy method to determine the environment address > whatever it's OneNAND or not. > We can just double CONFIG_ENV_ADDR for Flex-OneNAND, so CONFIG_ENV_ADDR_FLEX is not needed. Otherwise, we can just set env_addr to 1 block size as bootloader is always limited to block 0. >> int saveenv(void) >> { >> + struct onenand_chip *this = &onenand_chip; >>unsigned long env_addr = CONFIG_ENV_ADDR; >>struct erase_info instr = { >>.callback = NULL, >> @@ -96,6 +100,12 @@ >>size_t retlen; >> >>instr.len = CONFIG_ENV_SIZE; >> + if (FLEXONENAND(this)) { >> + env_addr = CONFIG_ENV_ADDR_FLEX; >> + instr.len = CONFIG_ENV_SIZE_FLEX; >> + instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ? >> + 1 : 0; >> + } >> > > Ditto. > I don't get alternative than to use CONFIG_ENV_SIZE_FLEX to store size of environment variables partition. Can you please elaborate. Regards, Rohit ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
On Tue, Oct 14, 2008 at 01:30:03PM +0200, Wolfgang Denk wrote: > Dear Scott, > > In message <[EMAIL PROTECTED]> apgmoorthy wrote: > > > > This patch adds support for Samsung Flex-OneNAND devices. > > > > Flex-OneNAND combines SLC and MLC technologies into a single > > device. SLC area provides increased reliability and speed, suitable > > for storing code and data, such as bootloader, kernel > > and root file system. MLC area provides high density and is best used > > for storing user data. Users can configure the size of SLC and MLC > > regions through 'onenand setboundary' command. > > > > Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> > > Do you intend to apply this to the NAND repo? I'll take a look at it. -Scott ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Dear Scott, In message <[EMAIL PROTECTED]> apgmoorthy wrote: > > This patch adds support for Samsung Flex-OneNAND devices. > > Flex-OneNAND combines SLC and MLC technologies into a single > device. SLC area provides increased reliability and speed, suitable > for storing code and data, such as bootloader, kernel > and root file system. MLC area provides high density and is best used > for storing user data. Users can configure the size of SLC and MLC > regions through 'onenand setboundary' command. > > Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> Do you intend to apply this to the NAND repo? Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: [EMAIL PROTECTED] You may call me by my name, Wirth, or by my value, Worth. - Nicklaus Wirth ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Hi, In u-boot, I only comment the u-boot part only. others are same at mtd mailing list. generally looks good to me. except minor ones. Thank you, Kyungmin Park > --- a/common/cmd_onenand.c > +++ b/common/cmd_onenand.c > @@ -20,9 +20,64 @@ > > extern struct mtd_info onenand_mtd; > extern struct onenand_chip onenand_chip; > +loff_t flexonenand_get_addr(int block) Should be static. maybe you use this one for drviers/mtd/onenand. but it's not good idea. I want to separate onenand command and driver codes. > +{ > + struct mtd_info *mtd = &onenand_mtd; > + struct onenand_chip *this = mtd->priv; > + loff_t ofs; > + int die = 0, boundary; > + > + ofs = 0; > + if (this->dies == 2 && block >= this->density_mask) { > + block -= this->density_mask; > + die = 1; > + ofs = this->diesize[0]; > + } > + boundary = this->boundary[die]; > + ofs += block << (this->erase_shift - 1); > + if (block > (boundary + 1)) > + ofs += (block - boundary - 1) << (this->erase_shift - 1); > + return ofs; > +} > + > +static int do_erase(ulong start, ulong end) > +{ > + struct mtd_info *mtd = &onenand_mtd; > + struct onenand_chip *this = mtd->priv; > + struct erase_info instr = { > + .callback = NULL, > + }; > + int i, ret; > + ulong block; > + > + printf("Erase block from %lu to %lu\n", start, end); > + > + for (block = start; block <= end; block++) { > + if (FLEXONENAND(this)) > + instr.addr = flexonenand_get_addr(block); > + else > + instr.addr = block << onenand_chip.erase_shift; > + > + if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) { > + for (i = 0; i < mtd->numeraseregions && > + mtd->eraseregions[i].offset <= instr.addr; > i++) > + ; > + i--; > + 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); > + } > + return 0; > +} > > 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) { > @@ -42,11 +97,7 @@ >default: >/* At least 4 args */ >if (strncmp(argv[1], "erase", 5) == 0) { > - struct erase_info instr = { > - .callback = NULL, > - }; >ulong start, end; > - ulong block; >char *endtail; > >if (strncmp(argv[2], "block", 5) == 0) { > @@ -57,28 +108,18 @@ >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(&onenand_mtd, > + start, NULL); > + end = onenand_get_block(&onenand_mtd, > + end, NULL); >/* Don't include the end block */ > - end--; > + if (end > 0) > + end--; >} > >if (!end || end < 0) >end = start; > - > - 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; > - ret = onenand_erase(&onenand_mtd, &instr); > - if (ret) { > - printf("erase failed %lu\n", block); > - break; > - } > - } > - > - return 0; > + return do_erase(start, end); >} > >if (strncmp(argv[1], "read", 4) == 0) { > @@ -134,15 +175,18 @@ >ops.mode = MTD_OOB_PLACE; > > > - ofs = block << onenand_chip.erase_shift; > + if (FLEXONENAND(this)
Re: [U-Boot] [PATCH] Flex-OneNAND driver
Hi All, Kindly let us know the comments and feedback on this patch. With Regards Gangheyamoorthy.A.P -Original Message- From: apgmoorthy [mailto:[EMAIL PROTECTED] Sent: Monday, September 22, 2008 11:59 AM To: 'u-boot@lists.denx.de' Cc: '[EMAIL PROTECTED]' Subject: [U-Boot] [PATCH] Flex-OneNAND driver Hi All, This patch adds support for Samsung Flex-OneNAND devices. Flex-OneNAND combines SLC and MLC technologies into a single device. SLC area provides increased reliability and speed, suitable for storing code and data, such as bootloader, kernel and root file system. MLC area provides high density and is best used for storing user data. Users can configure the size of SLC and MLC regions through 'onenand setboundary' command. Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> --- diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 8d87b78..7260017 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -20,9 +20,64 @@ extern struct mtd_info onenand_mtd; extern struct onenand_chip onenand_chip; +loff_t flexonenand_get_addr(int block) +{ + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; + loff_t ofs; + int die = 0, boundary; + + ofs = 0; + if (this->dies == 2 && block >= this->density_mask) { + block -= this->density_mask; + die = 1; + ofs = this->diesize[0]; + } + boundary = this->boundary[die]; + ofs += block << (this->erase_shift - 1); + if (block > (boundary + 1)) + ofs += (block - boundary - 1) << (this->erase_shift - 1); + return ofs; +} + +static int do_erase(ulong start, ulong end) +{ + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; + struct erase_info instr = { + .callback = NULL, + }; + int i, ret; + ulong block; + + printf("Erase block from %lu to %lu\n", start, end); + + for (block = start; block <= end; block++) { + if (FLEXONENAND(this)) + instr.addr = flexonenand_get_addr(block); + else + instr.addr = block << onenand_chip.erase_shift; + + if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) { + for (i = 0; i < mtd->numeraseregions && + mtd->eraseregions[i].offset <= instr.addr; i++) + ; + i--; + 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); + } + return 0; +} 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) { @@ -42,11 +97,7 @@ default: /* At least 4 args */ if (strncmp(argv[1], "erase", 5) == 0) { - struct erase_info instr = { - .callback = NULL, - }; ulong start, end; - ulong block; char *endtail; if (strncmp(argv[2], "block", 5) == 0) { @@ -57,28 +108,18 @@ 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(&onenand_mtd, + start, NULL); + end = onenand_get_block(&onenand_mtd, + end, NULL); /* Don't include the end block */ - end--; + if (end > 0) + end--; } if (!end || end < 0) end = start; - - 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_c
[U-Boot] [PATCH] Flex-OneNAND driver
Hi All, This patch adds support for Samsung Flex-OneNAND devices. Flex-OneNAND combines SLC and MLC technologies into a single device. SLC area provides increased reliability and speed, suitable for storing code and data, such as bootloader, kernel and root file system. MLC area provides high density and is best used for storing user data. Users can configure the size of SLC and MLC regions through 'onenand setboundary' command. Signed-off-by: Rohit Hagargundgi <[EMAIL PROTECTED]> --- diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 8d87b78..7260017 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -20,9 +20,64 @@ extern struct mtd_info onenand_mtd; extern struct onenand_chip onenand_chip; +loff_t flexonenand_get_addr(int block) +{ + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; + loff_t ofs; + int die = 0, boundary; + + ofs = 0; + if (this->dies == 2 && block >= this->density_mask) { + block -= this->density_mask; + die = 1; + ofs = this->diesize[0]; + } + boundary = this->boundary[die]; + ofs += block << (this->erase_shift - 1); + if (block > (boundary + 1)) + ofs += (block - boundary - 1) << (this->erase_shift - 1); + return ofs; +} + +static int do_erase(ulong start, ulong end) +{ + struct mtd_info *mtd = &onenand_mtd; + struct onenand_chip *this = mtd->priv; + struct erase_info instr = { + .callback = NULL, + }; + int i, ret; + ulong block; + + printf("Erase block from %lu to %lu\n", start, end); + + for (block = start; block <= end; block++) { + if (FLEXONENAND(this)) + instr.addr = flexonenand_get_addr(block); + else + instr.addr = block << onenand_chip.erase_shift; + + if (FLEXONENAND(this) && (mtd->numeraseregions > 1)) { + for (i = 0; i < mtd->numeraseregions && + mtd->eraseregions[i].offset <= instr.addr; i++) + ; + i--; + 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); + } + return 0; +} 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) { @@ -42,11 +97,7 @@ default: /* At least 4 args */ if (strncmp(argv[1], "erase", 5) == 0) { - struct erase_info instr = { - .callback = NULL, - }; ulong start, end; - ulong block; char *endtail; if (strncmp(argv[2], "block", 5) == 0) { @@ -57,28 +108,18 @@ 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(&onenand_mtd, + start, NULL); + end = onenand_get_block(&onenand_mtd, + end, NULL); /* Don't include the end block */ - end--; + if (end > 0) + end--; } if (!end || end < 0) end = start; - - 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; - ret = onenand_erase(&onenand_mtd, &instr); - if (ret) { - printf("erase failed %lu\n", block); - break; - } - } - - return 0; + return do_erase(start, end); } if (strncmp(argv[1], "read", 4) == 0) { @@ -134,15 +175,18 @@ ops.mode = MTD_OOB_PLACE; - ofs = block << onenand_chip.