Re: [U-Boot] Breakage on arm/next

2009-12-21 Thread apgmoorthy
Hi Scott,

> >>>
> >>> Hunk 2:
> >>> +   if (FLEXONENAND(this)) {
> >>> +   env_addr <<= 1;
> >>> +   instr.len <<=
> >> onenand_mtd.eraseregions[0].numblocks == 1 ?
> >>> +   2 : 1;
> >>> +   }
> >>>
> >>> This should not break any other Board with OneNAND support. 
> >> Please comment.
> >>> (Somehow I still feel Macros can be Cleaner way.)
> >> Why is the address automatically doubled on flex?  I think this 
> >> really needs to be something board-specified.
> >>
> > Please excuse me for the Delay.
> > 
> > Flex-OneNAND device's erasesize itself is double considered 
> to OneNAND.
> 
> That doesn't mean that all data you're storing is double the 
> size.  A board may want to keep the byte offset the same, and 
> let the block number change.
> 
> > Like , In SLC region of Flex-OneNAND size is 256K and in 
> MLC region it 
> > is 512K. In case of OneNAND erasesize is 128K and it is just SLC.
> 
> Suppose I have a 256K U-Boot.  I want CONFIG_ENV_ADDR to be 
> 256K regardless, which would be block 1 for flex SLC or block 
> 2 for regular OneNAND.
> 
> If I have a 512K U-Boot, then the byte offset would be the 
> same for MLC as well.

You are right , Sorry , I missed it. This is one of the scenarios which 
compelled us 
to use seperate Flex-OneNAND Env Macros different from OneNANDs , when 
suggesting a alternative somehow missed it.

Going back to the suggestion you have given couple of mails back in the same 
chain.
That there should be a macro which should return the ENV size for Flex.
In that case i just saw something like below should do.

Hunk 1:
env_addr += CONFIG_ENV_ADDR & (onenand_mtd.eraseregions[0].erasesize-1);

Hunk 2:
env_addr += CONFIG_ENV_ADDR & (onenand_mtd.eraseregions[0].erasesize-1);
instr.len = onenand_mtd.eraseregions[0].erasesize;
instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ? 1 : 0;

Please comment.

With Regards
 Moorthy







___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] Breakage on arm/next

2009-12-18 Thread apgmoorthy
Hi Sanjeev,

> 
> Is there any update on the fix/proposal?
> 
> I am trying to build for omap3_evm; but see the same problem.
> My repo is currently at:
>   bb3bcfa : Merge branch 'next' of ../next
>   a200a7c : Update CHANGELOG; prepare Prepare v2009.11
> 

As Scott pointed out rightly, my previous suggestion missed 
to see certain scenario.I will send the fix shortly. 
Sorry for the Delay.

With Regards
  Moorthy

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] Breakage on arm/next

2009-12-09 Thread apgmoorthy
Hi Scott, 

> > 
> > Hunk 1:
> >env_addr = CONFIG_ENV_ADDR;
> >+   if (FLEXONENAND(this))
> >+   env_addr <<= 1;
> > 
> > Hunk 2:
> > +   if (FLEXONENAND(this)) {
> > +   env_addr <<= 1;
> > +   instr.len <<= 
> onenand_mtd.eraseregions[0].numblocks == 1 ?
> > +   2 : 1;
> > +   }
> > 
> > This should not break any other Board with OneNAND support. 
> Please comment.
> > (Somehow I still feel Macros can be Cleaner way.)
> 
> Why is the address automatically doubled on flex?  I think 
> this really needs to be something board-specified.
> 
Please excuse me for the Delay.

Flex-OneNAND device's erasesize itself is double considered to OneNAND.
Like , In SLC region of Flex-OneNAND size is 256K and 
in MLC region it is 512K. In case of OneNAND erasesize is 128K and 
it is just SLC.

That's the reason size doubles for the Env in SLC and 
for MLC increased by one more fold.

In reply to Alessandro's mail , I have given the same details.

With Regards
 Moorthy 

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] Breakage on arm/next

2009-12-07 Thread apgmoorthy
Hi Scott, 
 
> Are they going to be the same on all boards?  We let the 
> board determine the environment location for other types of storage.
> 
OK

> How about just using CONFIG_ENV_ADDR/CONFIG_ENV_SIZE?  On 
> boards that must dynamically support multiple possibilities, 
> define it as an expression that returns the right thing.
> 

If the macros are not favoured to get consensus , let the code
use CONFIG_ENV_ADDR/CONFIG_ENV_SIZE and incase of Flex-OneNAND
increase it by one more fold.

something Like

Hunk 1:
   env_addr = CONFIG_ENV_ADDR;
   +   if (FLEXONENAND(this))
   +   env_addr <<= 1;

Hunk 2:
+   if (FLEXONENAND(this)) {
+   env_addr <<= 1;
+   instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ?
+   2 : 1;
+   }

This should not break any other Board with OneNAND support. Please comment.
(Somehow I still feel Macros can be Cleaner way.)

With Regards
  Moorthy

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] Breakage on arm/next

2009-12-02 Thread apgmoorthy
 
Hi,

> -Original Message-
> From: rub...@gnudd.com [mailto:rub...@gnudd.com] On Behalf Of 
> Alessandro Rubini
> Sent: Tuesday, December 01, 2009 9:36 PM
> To: tom@windriver.com
> Cc: moorthy@samsung.com; scottw...@freescale.com; 
> u-boot@lists.denx.de; kyungmin.p...@samsung.com
> Subject: Re: [U-Boot] Breakage on arm/next
> 
> > Could the macros defined in apollo.h also be defined in the other 
> > target board's config file ?
> 
> I don't think so (my board is one of the affected ones).
> 
> The macros are CONFIG_ENV_ADDR_FLEX and CONFIG_ENV_SIZE_FLEX 
> . I just don't have the flex device.
   
I get u.
   
> 
> In the commit that introduced the problem, I see  code like this:
> 
> 
>env_addr = CONFIG_ENV_ADDR;
>+   if (FLEXONENAND(this))
>+   env_addr = CONFIG_ENV_ADDR_FLEX;
> 
> So why should CONFIG_ENV_ADDR_FLEX have a different name from 
> CONFIG_ENV_ADDR ?
> Same applies to CONFIG_ENV_SIZE_FLEX.
> 
Erasesizes differ in Flex-OneNAND from OneNAND.
So Default Macros cannot be used.

> I think c758e947aa7d39a2be607ecdedd818ad300807b2 should be 
> reverted and done differently. If I got my reasoning right, 
> the first hunk should go and the next one:
> 
> 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;
> +   }
> 
> 
> Shoul just become
> 
> +   if (FLEXONENAND(this))
> +   instr.len <<= 
> onenand_mtd.eraseregions[0].numblocks == 1 
> + ? 1 : 0;
> 
> This has no adverse effect on other boards and handles the 
> flex specifics, withouth adding two unneeded macros.
> 

The Erase Sizes of Flex-OneNAND are 256K for SLC and 512K for MLC regions.
And always 0th Block belongs to SLC region whereas, 1st Block can be of SLC or
MLC region in a Die.
So without these Macros Flex-OneNAND specifics cannot be handled.

I felt moving these macros "include/linux/mtd/onenand.h" will be ideal in this
scenario.

With Regards
 Moorthy

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] Breakage on arm/next

2009-12-01 Thread apgmoorthy

Hi Tom,

Amul is out-of-office for sometime.
Excuse us for the delay.

>>In rebasing arm/next against u-boot/next.
>>There is a general error with targets that use onenand.
>>This includes the targets
>>nk8815_onenand
>>omap3_evm
>>smdkc100

>>I believe the error is from

>>commit c758e947aa7d39a2be607ecdedd818ad300807b2
>>Author: Amul Kumar Saha 
>>Date:   Wed Nov 4 10:38:46 2009 +0530

>> ENV Variable support for Flex-OneNAND

>> Define and use CONFIG_ENV_ADDR_FLEX and CONFIG_ENV_SIZE_FLEX
>> for storing environment variables.

The error comes since the Macros are defined in "configs/apollon.h".
And it works fine for Apollon.

I have tried with "make smdkc100_config" and did 'make all' and confirmed the 
error reported.

>>Please send a patch for this problem as soon as possible.

Moving these Macro definitions to "include/linux/mtd/onenand.h" looks more 
viable.
I can send across the patch. Please comment.

With Regards
  Moorthy




___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH] Bad Block Capable environment for OneNAND

2009-04-13 Thread apgmoorthy
Hi,
   With OneNAND ipl reading CONFIG_SYS_MONITOR_LEN , Environment Area 
should start after CONFIG_SYS_MONITOR_LEN.
Environment is made Bad Block cpapable too. These are done in the patch.
And fix 'onenand test' command to skip Bootloader and Environment Blocks.

With Regards
  Moorthy

Makes Environment to start after CONFIG_SYS_MONITOR_LEN
Environment is made to be Bad Block aware/capable.
Fix 'onenand test' command to skip Bootloader and Environment Blocks.

 Signed-off-by: Rohit Hagargundgi 
 Signed-off-by: Gangheyamoorthy   
---
 common/cmd_onenand.c  |   12 --
 common/env_onenand.c  |   96 +
 include/configs/apollon.h |2 +-
 include/onenand_uboot.h   |4 ++
 4 files changed, 84 insertions(+), 30 deletions(-)

diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 5832ff8..c366935 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -206,6 +206,7 @@ static int onenand_block_test(u32 start, u32 size)
u_char *buf;
u_char *verify_buf;
int ret;
+   int badblocklen = 0;
 
buf = malloc(blocksize);
if (!buf) {
@@ -219,13 +220,16 @@ static int onenand_block_test(u32 start, u32 size)
return -1;
}
 
+   /* Protect boot-loader and environment variables from badblock testing 
*/
+   while (start < CONFIG_SYS_MONITOR_LEN + CONFIG_ENV_SIZE + badblocklen) {
+   if (mtd->block_isbad(&onenand_mtd, start))
+   badblocklen += blocksize;
+   start += blocksize;
+   }
+
start_block = start >> this->erase_shift;
end_block = (start + size) >> this->erase_shift;
 
-   /* 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;
 
diff --git a/common/env_onenand.c b/common/env_onenand.c
index dbccc79..76e3aa8 100644
--- a/common/env_onenand.c
+++ b/common/env_onenand.c
@@ -39,6 +39,16 @@ extern uchar default_environment[];
 
 #define ONENAND_ENV_SIZE(mtd)  (mtd.writesize - ENV_HEADER_SIZE)
 
+/*
+ * User can give many blocks to environment variable partition
+ * through CONFIG_ENV_SIZE macro.
+ * The variables are written to first block in the partition. If this block
+ * goes bad, the successive block is used to store environment variables.
+ *
+ */
+
+#define ONENAND_ENV_END   (CONFIG_SYS_MONITOR_LEN + CONFIG_ENV_SIZE)
+
 char *env_name_spec = "OneNAND";
 
 #ifdef ENV_IS_EMBEDDED
@@ -58,23 +68,31 @@ uchar env_get_char_spec(int index)
 
 void env_relocate_spec(void)
 {
-   unsigned long env_addr;
-   int use_default = 0;
+   unsigned long env_addr = CONFIG_SYS_MONITOR_LEN;
+   int use_default = 1;
size_t retlen;
+   int blocksize = onenand_mtd.erasesize;
 
-   env_addr = CONFIG_ENV_ADDR;
+   /* Find environment block. */
+   while (onenand_mtd.writesize && (env_addr < ONENAND_ENV_END)) {
+   if (onenand_block_isbad(&onenand_mtd, env_addr)) {
+   printf("Skip bad block at 0x%x\n", (u32)env_addr);
+   env_addr += blocksize;
+   continue;
+   }
 
-   /* Check OneNAND exist */
-   if (onenand_mtd.writesize)
/* Ignore read fail */
onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,
 &retlen, (u_char *) env_ptr);
-   else
-   onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;
 
-   if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
-   env_ptr->crc)
-   use_default = 1;
+   if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) ==
+   env_ptr->crc) {
+   printf("OneNAND: Read environment from 0x%x\n", 
(u32)env_addr);
+   use_default = 0;
+   break;
+   }
+   env_addr += blocksize;
+   }
 
if (use_default) {
memcpy(env_ptr->data, default_environment,
@@ -89,31 +107,59 @@ void env_relocate_spec(void)
 
 int saveenv(void)
 {
-   unsigned long env_addr = CONFIG_ENV_ADDR;
+   unsigned long env_addr = 0, badblocklen = 0;
struct erase_info instr = {
-   .callback   = NULL,
+.callback  = NULL,
};
size_t retlen;
+   int blocksize = onenand_mtd.erasesize;
 
-   instr.len = CONFIG_ENV_SIZE;
-   instr.addr = env_addr;
-   instr.mtd = &onenand_mtd;
-   if (onenand_erase(&onenand_mtd, &instr)) {
-   printf("OneNAND: erase failed at 0x%08lx\n", env_addr);
+   /* Skip bootloader area. */
+   while (env_addr < CONFIG_SYS_MONITOR_LEN + badblocklen) {
+   if (onenand_block_isbad(&onenand_mtd, env_addr))
+   badblocklen += blocksize;
+ 

Re: [U-Boot] [PATCH 1/2] Fix OneNAND ipl to read CONFIG_SYS_MONITOR_LEN

2009-04-12 Thread apgmoorthy

Hi Scott, 

On Tuesday, March 31, 2009 4:04 AM Scott Wood Wrote :

>>Note that there are a couple of board files (apollon and nmdk8815) that use 
>>the OneNAND loader 
>>that do not define CONFIG_SYS_MONITOR_LEN.  I've added the maintainers to the 
>>Cc: list.

CONFIG_SYS_MONITOR_LEN is not defined in include/configs/apollon.h as of now.

This is done by the Post : [U-Boot] [PATCH 2/2] Fix OneNAND ipl to read 
CONFIG_SYS_MONITOR_LEN

What do you feel about getting this one inside u-boot-nand-flash ?

With Regards
  Moorthy

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] OneNand support broken for apollon

2009-04-05 Thread apgmoorthy

On Apr 05, 2009 01:40 Jean-Christophe Wrote :

>   Your patch Fix OneNAND ipl to read CONFIG_SYS_MONITOR_LEN
>   brake the appolon
>   Could you take a look?

   - Can you please do let me know , where exactly do you see a problem ?

With Regards
  Moorthy

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 1/2] Fix OneNAND ipl to read CONFIG_SYS_MONITOR_LEN

2009-03-27 Thread apgmoorthy
Currently OneNAND initial program loader (ipl) reads only block 0 ie 128KB.
However, u-boot image for apollon board is 195KB making the board
unbootable with OneNAND.

Fix ipl to read CONFIG_SYS_MONITOR_LEN.
CONFIG_SYS_MONITOR_LEN macro holds the U-Boot image size.

 Signed-off-by: Rohit Hagargundgi 
 Signed-off-by: Gangheyamoorthy   
---
 onenand_boot.c |2 -
 onenand_ipl.h  |8 ++-
 onenand_read.c |   58 +++--
 3 files changed, 44 insertions(+), 24 deletions(-) 
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c
index 86428cc..63995ce 100644
--- a/onenand_ipl/onenand_boot.c
+++ b/onenand_ipl/onenand_boot.c
@@ -36,7 +36,7 @@ void start_oneboot(void)
 
buf = (uchar *) CONFIG_SYS_LOAD_ADDR;
 
-   onenand_read_block0(buf);
+   onenand_read_block(buf);
 
((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)();
 
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h
index 57e54f5..412572a 100644
--- a/onenand_ipl/onenand_ipl.h
+++ b/onenand_ipl/onenand_ipl.h
@@ -23,15 +23,13 @@
 
 #include 
 
-#define onenand_readw(a)readw(a)
-#define onenand_writew(v, a)writew(v, a)
+#define onenand_readw(a)readw(THIS_ONENAND(a))
+#define onenand_writew(v, a)writew(v, THIS_ONENAND(a))
 
 #define THIS_ONENAND(a) (CONFIG_SYS_ONENAND_BASE + (a))
 
 #define READ_INTERRUPT()\
onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT))
 
-#define ONENAND_PAGE_SIZE   2048
-
-extern int onenand_read_block0(unsigned char *buf);
+extern int onenand_read_block(unsigned char *buf);
 #endif
diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c
index 6d04943..7886358 100644
--- a/onenand_ipl/onenand_read.c
+++ b/onenand_ipl/onenand_read.c
@@ -49,20 +49,20 @@ static inline int onenand_read_page(ulong block, ulong page,
 #endif
 
onenand_writew(onenand_block_address(block),
-   THIS_ONENAND(ONENAND_REG_START_ADDRESS1));
+   ONENAND_REG_START_ADDRESS1);
 
onenand_writew(onenand_bufferram_address(block),
-   THIS_ONENAND(ONENAND_REG_START_ADDRESS2));
+   ONENAND_REG_START_ADDRESS2);
 
onenand_writew(onenand_sector_address(page),
-   THIS_ONENAND(ONENAND_REG_START_ADDRESS8));
+   ONENAND_REG_START_ADDRESS8);
 
onenand_writew(onenand_buffer_address(),
-   THIS_ONENAND(ONENAND_REG_START_BUFFER));
+   ONENAND_REG_START_BUFFER);
 
-   onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT));
+   onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT);
 
-   onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND));
+   onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);
 
 #ifndef __HAVE_ARCH_MEMCPY32
p = (unsigned long *) buf;
@@ -72,6 +72,10 @@ static inline int onenand_read_page(ulong block, ulong page,
while (!(READ_INTERRUPT() & ONENAND_INT_READ))
continue;
 
+   /* Check for invalid block mark */
+   if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0x))
+   return 1;
+
 #ifdef __HAVE_ARCH_MEMCPY32
/* 32 bytes boundary memory copy */
memcpy32(buf, base, pagesize);
@@ -89,25 +93,43 @@ static inline int onenand_read_page(ulong block, ulong page,
 #define ONENAND_PAGES_PER_BLOCK64
 
 /**
- * onenand_read_block - Read a block data to buf
+ * onenand_read_block - Read CONFIG_SYS_MONITOR_LEN from begining
+ *  of OneNAND, skipping bad blocks
  * @return 0 on success
  */
-int onenand_read_block0(unsigned char *buf)
+int onenand_read_block(unsigned char *buf)
 {
-   int page, offset = 0;
-   int pagesize = ONENAND_PAGE_SIZE;
+   int block;
+   int page = ONENAND_START_PAGE, offset = 0;
+   int pagesize = 0, erase_shift = 0;
+   int erasesize = 0, nblocks = 0;
+
+   if (onenand_readw(ONENAND_REG_TECHNOLOGY)) {
+   pagesize = 4096; /* MLC OneNAND has 4KiB pagesize */
+   erase_shift = 18;
+   } else {
+   pagesize = 2048;
+   erase_shift = 17;
+   }
 
-   /* MLC OneNAND has 4KiB page size */
-   if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY)))
-   pagesize <<= 1;
+   erasesize = ONENAND_PAGES_PER_BLOCK * pagesize;
+   nblocks = (CONFIG_SYS_MONITOR_LEN + erasesize - 1) >> erase_shift;
 
/* NOTE: you must read page from page 1 of block 0 */
/* read the block page by page*/
-   for (page = ONENAND_START_PAGE;
-   page < ONENAND_PAGES_PER_BLOCK; page++) {
-
-   onenand_read_page(0, page, buf + offset, pagesize);
-   offset += pagesize;
+   for (block = 0; block < nblocks; block++) {
+   for (; page < ONENAND_PAGES_PER_BLOCK; page++) {
+ 

Re: [U-Boot] [PATCH 1/2] Fix OneNAND ipl to read CONFIG_SYS_MONITOR_LEN

2009-03-25 Thread apgmoorthy
Hi Scott,

On Tuesday, March 24, 2009 2:55 AM , Scott Wood wrote

>> Please do find the updated patch below.

>It's easier if updated patches are sent separately from the reply (both to 
>avoid getting lost, 
>and to avoid having to manually strip discussion from the changelog).

>> Signed-off-by: Gangheyamoorthy   
>> Signed-off-by: Rohit Hagargundgi 

> The signed-off-by lines should go in chronological order of handling;
> thus, yours should be at the bottom (as the most recent one to touch or 
> forward the patch).

- Thanks, Will take care.

>> +/* Check for invalid block mark */
>> +if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0x))
>> +return 1;

>Unnecessary parens.

- I think , parens make it more readable.

>> - * onenand_read_block - Read a block data to buf
>> + * onenand_read_block - Read First 'n' consecutive Good blocks holding 
>> + *  data to buf

> "Read SYS_MONITOR_LEN from beginning of OneNAND, skipping bad blocks"

- Changed it in Function Header.

>> +int block = 0, page = ONENAND_START_PAGE, offset = 0;
>> +int pagesize = 0, erase_shift =0;
>> +int erasesize = 0, nblocks = 0;

>s/=0/= 0/

>> +if(onenand_readw(ONENAND_REG_TECHNOLOGY)) {

> Space after "if".

   - Corrected them.

>> +} else {
>> +pagesize = 2048;
>> +erase_shift = 17;
>> +}
>> +erasesize = ONENAND_PAGES_PER_BLOCK * pagesize;
>> +nblocks = (CONFIG_SYS_MONITOR_LEN + erasesize -1) >> erase_shift;

>Blank line after the closing brace at the end of a block (except with a 
>hanging else, or similar).

>s/-1/- 1/

- Changed them.

>> +for (; block < nblocks; block++) {
>> +for (; page < ONENAND_PAGES_PER_BLOCK; page++) {

> Why not do block = 0 and page = 0 here, rather than at the beginning 
> of the function and (in the case of page) at the end of the loop?

- Initialized block in the for. With 'page' we need to start with page 1 in 
Block 0.
   

>> +if (onenand_read_page(block, page, buf + offset, 
>> pagesize)) {
>> +/* This block is bad. Skip it and read next 
>> block */

>Line length.

   - Resolved.

With Regards
  Moorthy

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH 1/2] Fix OneNAND ipl to read CONFIG_SYS_MONITOR_LEN

2009-03-23 Thread apgmoorthy
Hi Scott, 

>> +if (page < 2 && (onenand_readw(THIS_ONENAND(ONENAND_SPARERAM)) != 
>> 0x))

 >Line length.

 - Corrected.
  
>>  int pagesize = ONENAND_PAGE_SIZE;
>> +int nblocks = CONFIG_SYS_MONITOR_LEN / ONENAND_BLOCK_SIZE;

 >Shouldn't nblocks be rounded up?

>>  pagesize <<= 1;
>> +nblocks = (nblocks + 1) >> 1;
>> +}

 >Hmm, might be clearer to just do this:

>if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY))) {
>   pagesize = 4096;
>   pageshift = 12;
>} else {
>   pagesize = 2048;
>   pageshift = 11;
>}

>nblocks = (CONFIG_SYS_MONITOR_LEN + pagesize - 1) >> pageshift;

   - Right , But the above line dosent give the nblocks ,
 used erasesize and erase_shift.


>ONENAND_PAGE_SIZE as a constant should go away since it's not always
>true.

- Removed it.

>> +for (; block < nblocks; block++) {
>> +for (; page < ONENAND_PAGES_PER_BLOCK; page++) {
>> +if (onenand_read_page(block, page, buf + offset, 
>> pagesize)) {
>> +/* This block is bad. Skip it and read next 
>> block */
>> +nblocks++;
>> +break;
>> +}
>> +offset += pagesize;

>If you find a bad block marker in the second page of a block, shouldn't
>you rewind offset to the beginning of the block?

   - Correct , have reverted back.

>BTW, if we're going to have "onenand_readw" and "onenand_writew"
>wrappers, can we make them useful by combining them with THIS_ONENAND?

   - Corrected , Now onenand_readw/onenand_writew conatins THIS_ONENAND.

Please do find the updated patch below.

With Regards
  Moorthy


Currently OneNAND initial program loader (ipl) reads only block 0 ie 128KB.
However, u-boot image for apollon board is 195KB making the board
unbootable with OneNAND.

Fix ipl to read CONFIG_SYS_MONITOR_LEN.
CONFIG_SYS_MONITOR_LEN macro holds the U-Boot image size.

Signed-off-by: Gangheyamoorthy   
Signed-off-by: Rohit Hagargundgi 
---
 
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c
index 86428cc..63995ce 100644
--- a/onenand_ipl/onenand_boot.c
+++ b/onenand_ipl/onenand_boot.c
@@ -36,7 +36,7 @@ void start_oneboot(void)
 
buf = (uchar *) CONFIG_SYS_LOAD_ADDR;
 
-   onenand_read_block0(buf);
+   onenand_read_block(buf);
 
((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)();
 
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h
index c5a722d..412572a 100644
--- a/onenand_ipl/onenand_ipl.h
+++ b/onenand_ipl/onenand_ipl.h
@@ -31,5 +31,5 @@
 #define READ_INTERRUPT()\
onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT))
 
-extern int onenand_read_block0(unsigned char *buf);
+extern int onenand_read_block(unsigned char *buf);
 #endif
diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c
index 6d04943..7415c7f 100644
--- a/onenand_ipl/onenand_read.c
+++ b/onenand_ipl/onenand_read.c
@@ -49,20 +49,20 @@ static inline int onenand_read_page(ulong block, ulong page,
 #endif
 
onenand_writew(onenand_block_address(block),
-   THIS_ONENAND(ONENAND_REG_START_ADDRESS1));
+   ONENAND_REG_START_ADDRESS1);
 
onenand_writew(onenand_bufferram_address(block),
-   THIS_ONENAND(ONENAND_REG_START_ADDRESS2));
+   ONENAND_REG_START_ADDRESS2);
 
onenand_writew(onenand_sector_address(page),
-   THIS_ONENAND(ONENAND_REG_START_ADDRESS8));
+   ONENAND_REG_START_ADDRESS8);
 
onenand_writew(onenand_buffer_address(),
-   THIS_ONENAND(ONENAND_REG_START_BUFFER));
+   ONENAND_REG_START_BUFFER);
 
-   onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT));
+   onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT);
 
-   onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND));
+   onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);
 
 #ifndef __HAVE_ARCH_MEMCPY32
p = (unsigned long *) buf;
@@ -72,6 +72,10 @@ static inline int onenand_read_page(ulong block, ulong page,
while (!(READ_INTERRUPT() & ONENAND_INT_READ))
continue;
 
+   /* Check for invalid block mark */
+   if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0x))
+   return 1;
+
 #ifdef __HAVE_ARCH_MEMCPY32
/* 32 bytes boundary memory copy */
memcpy32(buf, base, pagesize);
@@ -89,25 +93,39 @@ static inline int onenand_read_page(ulong block, ulong page,
 #define ONENAND_PAGES_PER_BLOCK64
 
 /**
- * onenand_read_block - Read a block data to buf
+ * onenand_read_block - Read First 'n' consecutive Good blocks holding 
+ *  data to buf
  * @return 0 on success
  */
-int onenand_read_block0(unsigned char *buf)
+int onenand_read_block(unsigned char *b

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.