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 amul.saha at samsung.com
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 h.rohit at samsung.com
 Signed-off-by: Gangheyamoorthy   moorthy.apg at samsung.com
---
 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 += 

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-06 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 h.ro...@samsung.com
 Signed-off-by: Gangheyamoorthy   moorthy@samsung.com
---
 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 linux/mtd/onenand_regs.h
 
-#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 (; 

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   moorthy@samsung.com
 Signed-off-by: Rohit Hagargundgi h.ro...@samsung.com

 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   moorthy@samsung.com
Signed-off-by: Rohit Hagargundgi h.ro...@samsung.com
---
 
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 *buf)
 {
-   int page, 

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

2008-09-22 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.erase_shift;
+   if (FLEXONENAND(this))
+