Re: [U-Boot] [PATCH] Flex-OneNAND driver

2008-11-06 Thread Scott Wood
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

2008-11-05 Thread Amit Kumar Sharma
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

2008-11-02 Thread Rohit
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

2008-10-28 Thread Scott Wood
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

2008-10-27 Thread Kyungmin Park
>
> 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

2008-10-27 Thread Scott Wood
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

2008-10-24 Thread Rohit
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

2008-10-22 Thread Scott Wood
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

2008-10-16 Thread Rohit
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

2008-10-14 Thread Scott Wood
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

2008-10-14 Thread Wolfgang Denk
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

2008-09-25 Thread Kyungmin Park
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

2008-09-25 Thread apgmoorthy
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

2008-09-21 Thread apgmoorthy
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.