public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot]  [PATCH v2 4/4] Flex-OneNAND boundary setting command
@ 2008-12-11 14:27 Rohit Hagargundgi
  2009-03-08  6:47 ` Rohit Hagargundgi
  0 siblings, 1 reply; 9+ messages in thread
From: Rohit Hagargundgi @ 2008-12-11 14:27 UTC (permalink / raw)
  To: u-boot

Add command for changing Flex-OneNAND SLC / MLC boundary.

Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com>
---
 common/cmd_onenand.c |   65 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 8d87b78..2caae45 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -21,8 +21,35 @@
 extern struct mtd_info onenand_mtd;
 extern struct onenand_chip onenand_chip;
 
+/**
+ * do_set_boundary - [Flex-OneNAND] Set boundary of Flex-OneNAND
+ * @param mtd		mtd information structure
+ * @param die		die of device for which boundary will be set
+ * @param bdry		new boundary value ie last SLC block of die
+ *
+ * Set boundary of Flex-OneNAND
+ */
+int do_set_boundary(struct mtd_info *mtd, unsigned die, unsigned bdry, int lock)
+{
+	struct onenand_chip *this = mtd->priv;
+
+	if (!FLEXONENAND(this)) {
+		printf("Flex-OneNAND not found.\n");
+		return -1;
+	}
+
+	if (die >= this->dies) {
+		printf("Invalid die index\n");
+		return -1;
+	}
+
+	return flexonenand_set_boundary(mtd, die, bdry, lock);
+}
+
 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) {
@@ -57,10 +84,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 				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(this,	start, NULL);
+				end = onenand_get_block(this, end, NULL);
 				/* Don't include the end block */
-				end--;
+				if (end > 0)
+					end--;
 			}
 
 			if (!end || end < 0)
@@ -69,8 +97,13 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 			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;
+				instr.addr = onenand_get_addr(this, block);
+				if (mtd->numeraseregions > 1) {
+					int i = flexonenand_region(mtd, instr.addr);
+					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);
@@ -134,15 +167,15 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 			ops.mode = MTD_OOB_PLACE;
 
 
-			ofs = block << onenand_chip.erase_shift;
+			ofs = onenand_get_addr(this, block);
 			if (page)
 				ofs += page << onenand_chip.page_shift;
 
 			if (!len) {
 				if (oob)
-					ops.ooblen = 64;
+					ops.ooblen = FLEXONENAND(this) ? 128 : 64;
 				else
-					ops.len = 512;
+					ops.len = FLEXONENAND(this) ? 4096 : 512;
 			}
 
 			if (oob) {
@@ -158,6 +191,18 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 			return 0;
 		}
 
+		if (strncmp(argv[1], "setboundary", 11) == 0) {
+			unsigned die = simple_strtoul(argv[2], NULL, 0);
+			unsigned bdry = simple_strtoul(argv[3], NULL, 0);
+			int lock = 0;
+
+			if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
+				lock = 1;
+
+			do_set_boundary(mtd, die, bdry, lock);
+			return 0;
+		}
+
 		break;
 	}
 
@@ -172,5 +217,7 @@ U_BOOT_CMD(
 	"onenand write addr ofs len - write data@ofs with len from addr\n"
 	"onenand erase saddr eaddr - erase block start addr to end addr\n"
 	"onenand block[.oob] addr block [page] [len] - "
-		"read data with (block [, page]) to addr"
+		"read data with (block [, page]) to addr\n"
+	"onenand setboundary DIE BOUNDARY [LOCK] - "
+	"Change SLC boundary of Flex-OneNAND\n"
 );
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2008-12-11 14:27 [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command Rohit Hagargundgi
@ 2009-03-08  6:47 ` Rohit Hagargundgi
  2009-03-09 21:38   ` Scott Wood
  0 siblings, 1 reply; 9+ messages in thread
From: Rohit Hagargundgi @ 2009-03-08  6:47 UTC (permalink / raw)
  To: u-boot

On Thursday 11 December 2008 19:57:53 Rohit Hagargundgi wrote:
> Add command for changing Flex-OneNAND SLC / MLC boundary.
> 

Also onenand commands work for Flex-OneNAND.

Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com>
---
 common/cmd_onenand.c      |   88 ++++++++++++++++++++++++++++++++--------------
 include/configs/apollon.h |    2 -
 2 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/include/configs/apollon.h b/include/configs/apollon.h
index dff47fc..6e3e34a 100644
--- a/include/configs/apollon.h
+++ b/include/configs/apollon.h
@@ -76,7 +76,7 @@
  */
 #define	CONFIG_ENV_SIZE SZ_128K	/* Total Size of Environment Sector */
 #define CONFIG_ENV_SIZE_FLEX SZ_256K
-#define	CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + SZ_1M)
+#define	CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + SZ_2M)
 /* bytes reserved for initial data */
 #define	CONFIG_SYS_GBL_DATA_SIZE	128
 
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 6a2c924..7779b44 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size)
 	return 0;
 }
 
+static inline int onenand_blocksize(loff_t ofs)
+{
+	struct onenand_chip *this = mtd->priv;
+	int i;
+
+	if (!FLEXONENAND(this))
+		return mtd->erasesize;
+
+	i = flexonenand_region(mtd, ofs);
+	return mtd->eraseregions[i].erasesize;
+}
+
 static int onenand_block_read(loff_t from, size_t len,
 			      size_t *retlen, u_char *buf, int oob)
 {
 	struct onenand_chip *this = mtd->priv;
-	int blocks = (int) len >> this->erase_shift;
-	int blocksize = (1 << this->erase_shift);
+	int blocks = (int) onenand_block(this, from + len)
+			 - onenand_block(this, from);
+	int blocksize;
 	loff_t ofs = from;
 	struct mtd_oob_ops ops = {
 		.retlen		= 0,
 	};
 	int ret;
 
-	if (oob)
-		ops.ooblen = blocksize;
-	else
-		ops.len = blocksize;
-
 	while (blocks) {
+		blocksize = onenand_blocksize(ofs);
+
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret) {
 			printk("Bad blocks %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       (u32)onenand_block(this, ofs), (u32)ofs);
 			ofs += blocksize;
 			continue;
 		}
 
-		if (oob)
+		if (oob) {
 			ops.oobbuf = buf;
-		else
+			ops.ooblen = blocksize;
+		} else {
 			ops.datbuf = buf;
+			ops.len = blocksize;
+		}
 
 		ops.retlen = 0;
 		ret = mtd->read_oob(mtd, ofs, &ops);
@@ -116,8 +129,7 @@ static int onenand_block_write(loff_t to, size_t len,
 			       size_t *retlen, const u_char * buf)
 {
 	struct onenand_chip *this = mtd->priv;
-	int blocks = len >> this->erase_shift;
-	int blocksize = (1 << this->erase_shift);
+	int blocks, blocksize;
 	loff_t ofs;
 	size_t _retlen = 0;
 	int ret;
@@ -131,11 +143,15 @@ static int onenand_block_write(loff_t to, size_t len,
 	}
 	ofs = to;
 
+	blocks = (int) onenand_block(this, ofs + len) - onenand_block(this, ofs);
+
 	while (blocks) {
+		blocksize = onenand_blocksize(ofs);
+
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret) {
 			printk("Bad blocks %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       (u32)onenand_block(this, ofs), (u32)ofs);
 			skip_ofs += blocksize;
 			goto next;
 		}
@@ -165,13 +181,15 @@ static int onenand_block_erase(u32 start, u32 size, int force)
 	};
 	loff_t ofs;
 	int ret;
-	int blocksize = 1 << this->erase_shift;
+	int blocksize;
 
 	for (ofs = start; ofs < (start + size); ofs += blocksize) {
+		blocksize = onenand_blocksize(ofs);
+
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret && !force) {
 			printf("Skip erase bad block %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       (u32)onenand_block(this, ofs), (u32)ofs);
 			continue;
 		}
 
@@ -182,7 +200,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)
 		ret = mtd->erase(mtd, &instr);
 		if (ret) {
 			printf("erase failed block %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       (u32)onenand_block(this, ofs), (u32)ofs);
 			continue;
 		}
 	}
@@ -219,25 +237,27 @@ static int onenand_block_test(u32 start, u32 size)
 		return -1;
 	}
 
-	start_block = start >> this->erase_shift;
-	end_block = (start + size) >> this->erase_shift;
+	start_block = onenand_block(this, start);
+	end_block = onenand_block(this, start + size);
 
 	/* 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;
+	if (end_block > onenand_block(this, mtd->size))
+		end_block = onenand_block(this, mtd->size);
 
 	blocks = start_block;
 	ofs = start;
 	while (blocks < end_block) {
-		printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);
+		printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), (u32)ofs);
+
+		blocksize = onenand_blocksize(ofs);
 
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret) {
 			printf("Skip erase bad block %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       (u32)onenand_block(this, ofs), (u32)ofs);
 			goto next;
 		}
 
@@ -341,7 +361,6 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 
 	mtd = &onenand_mtd;
 	this = mtd->priv;
-	blocksize = (1 << this->erase_shift);
 
 	cmd = argv[1];
 
@@ -359,9 +378,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		if (strcmp(cmd, "bad") == 0) {
 			/* Currently only one OneNAND device is supported */
 			printf("\nDevice %d bad blocks:\n", 0);
-			for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
+			for (ofs = 0; ofs < mtd->size; ofs += blocksize) {
 				if (mtd->block_isbad(mtd, ofs))
 					printf("  %08x\n", (u32)ofs);
+
+				blocksize = onenand_blocksize(ofs);
 			}
 
 			return 0;
@@ -459,6 +480,21 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 			return ret == 0 ? 1 : 0;
 		}
 
+		if (strncmp(cmd, "setboundary", 11) == 0) {
+			int die, bdry, lock = 0;
+
+			if (argc < 4)
+				goto usage;
+
+			die = (int) simple_strtoul(argv[2], NULL, 0);
+			bdry = (int) simple_strtoul(argv[3], NULL, 0);
+
+			if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
+				lock = 1;
+
+			return flexonenand_set_boundary(mtd, die, bdry, lock);
+		}
+
 		break;
 	}
 
@@ -478,9 +514,11 @@ U_BOOT_CMD(
 	"onenand write[.oob] addr off size\n"
 	"    read/write 'size' bytes starting at offset 'off'\n"
 	"    to/from memory address 'addr', skipping bad blocks.\n"
-	"onenand erase [force] [off size] - erase 'size' bytes from\n"
+	"onenand erase [force] [off size] - erase 'size' bytes from off\n"
 	"onenand test [off size] - test 'size' bytes from\n"
 	"    offset 'off' (entire device if not specified)\n"
 	"onenand dump[.oob] off - dump page\n"
 	"onenand markbad off - mark bad block@offset (UNSAFE)\n"
+	"onenand setboundary DIE BOUNDARY [LOCK] - "
+	"Change SLC boundary of Flex-OneNAND\n"
 );

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-08  6:47 ` Rohit Hagargundgi
@ 2009-03-09 21:38   ` Scott Wood
  2009-03-23  7:06     ` Amul Kumar Saha
  2009-03-25 15:14     ` Amul Kumar Saha
  0 siblings, 2 replies; 9+ messages in thread
From: Scott Wood @ 2009-03-09 21:38 UTC (permalink / raw)
  To: u-boot

On Sun, Mar 08, 2009 at 12:17:36PM +0530, Rohit Hagargundgi wrote:
> +static inline int onenand_blocksize(loff_t ofs)
> +{
> +	struct onenand_chip *this = mtd->priv;
> +	int i;
> +
> +	if (!FLEXONENAND(this))
> +		return mtd->erasesize;
> +
> +	i = flexonenand_region(mtd, ofs);
> +	return mtd->eraseregions[i].erasesize;

Can we define the interface to the onenand code such that the caller
doesn't need to care what type of onenand it is, and non-flex will simply
appear to have one region?

> +		if (strncmp(cmd, "setboundary", 11) == 0) {
> +			int die, bdry, lock = 0;
> +
> +			if (argc < 4)
> +				goto usage;
> +
> +			die = (int) simple_strtoul(argv[2], NULL, 0);
> +			bdry = (int) simple_strtoul(argv[3], NULL, 0);
> +
> +			if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
> +				lock = 1;
> +
> +			return flexonenand_set_boundary(mtd, die, bdry, lock);
> +		}

What happens if the user runs the setboundary command on non-flex
onenand?  Does it fail gracefully?

> +
>  		break;
>  	}
>  
> @@ -478,9 +514,11 @@ U_BOOT_CMD(
>  	"onenand write[.oob] addr off size\n"
>  	"    read/write 'size' bytes starting at offset 'off'\n"
>  	"    to/from memory address 'addr', skipping bad blocks.\n"
> -	"onenand erase [force] [off size] - erase 'size' bytes from\n"
> +	"onenand erase [force] [off size] - erase 'size' bytes from off\n"

Quotes around 'off', as is done elsewhere in the help text.

-Scott

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-09 21:38   ` Scott Wood
@ 2009-03-23  7:06     ` Amul Kumar Saha
  2009-03-23 20:17       ` Scott Wood
  2009-03-25 15:14     ` Amul Kumar Saha
  1 sibling, 1 reply; 9+ messages in thread
From: Amul Kumar Saha @ 2009-03-23  7:06 UTC (permalink / raw)
  To: u-boot

Hi Scott,

>> +static inline int onenand_blocksize(loff_t ofs)
>> +{
>> + struct onenand_chip *this = mtd->priv;
>> + int i;
>> +
>> + if (!FLEXONENAND(this))
>> + return mtd->erasesize;
>> +
>> + i = flexonenand_region(mtd, ofs);
>> + return mtd->eraseregions[i].erasesize;
> 
> Can we define the interface to the onenand code such that the caller
> doesn't need to care what type of onenand it is, and non-flex will simply
> appear to have one region?
> 

Right. We shall take this on moving ahead. Guess this is fine for now.

>> + if (strncmp(cmd, "setboundary", 11) == 0) {
>> + int die, bdry, lock = 0;
>> +
>> + if (argc < 4)
>> + goto usage;
>> +
>> + die = (int) simple_strtoul(argv[2], NULL, 0);
>> + bdry = (int) simple_strtoul(argv[3], NULL, 0);
>> +
>> + if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
>> + lock = 1;
>> +
>> + return flexonenand_set_boundary(mtd, die, bdry, lock);
>> + }
> 
> What happens if the user runs the setboundary command on non-flex
> onenand?  Does it fail gracefully?
> 

Resolved.

>> +
>>  break;
>>  }
>>  
>> @@ -478,9 +514,11 @@ U_BOOT_CMD(
>>  "onenand write[.oob] addr off size\n"
>>  "    read/write 'size' bytes starting at offset 'off'\n"
>>  "    to/from memory address 'addr', skipping bad blocks.\n"
>> - "onenand erase [force] [off size] - erase 'size' bytes from\n"
>> + "onenand erase [force] [off size] - erase 'size' bytes from off\n"
> 
> Quotes around 'off', as is done elsewhere in the help text.
> 

Resolved


OneNAND commands now work for Flex-OneNAND.
Add command for changing Flex-OneNAND SLC / MLC boundary.

Thank You,
Amul Kumar Saha


Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com>
Signed-off-by: Amul Kumar Saha <amul.saha@samsung.com>
---
 common/cmd_onenand.c      |  103 ++++++++++++++++++++++++++++++++--------------
 include/configs/apollon.h |    2
 2 files changed, 74 insertions(+), 31 deletions(-)

diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 5832ff8..ed6681a 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size)
  return 0;
 }
 
+static inline int onenand_blocksize(loff_t ofs)
+{
+ struct onenand_chip *this = mtd->priv;
+ int i;
+
+ if (!FLEXONENAND(this))
+  return mtd->erasesize;
+
+ i = flexonenand_region(mtd, ofs);
+ return mtd->eraseregions[i].erasesize;
+}
+
 static int onenand_block_read(loff_t from, size_t len,
          size_t *retlen, u_char *buf, int oob)
 {
  struct onenand_chip *this = mtd->priv;
- int blocks = (int) len >> this->erase_shift;
- int blocksize = (1 << this->erase_shift);
+ int blocks = (int) onenand_block(this, from + len)
+    - onenand_block(this, from);
+ int blocksize;
  loff_t ofs = from;
  struct mtd_oob_ops ops = {
   .retlen  = 0,
  };
  int ret;
 
- if (oob)
-  ops.ooblen = blocksize;
- else
-  ops.len = blocksize;
-
  while (blocks) {
+  blocksize = onenand_blocksize(ofs);
+
   ret = mtd->block_isbad(mtd, ofs);
   if (ret) {
    printk("Bad blocks %d at 0x%x\n",
-          (u32)(ofs >> this->erase_shift), (u32)ofs);
+          (u32)onenand_block(this, ofs), (u32)ofs);
    ofs += blocksize;
    continue;
   }
 
-  if (oob)
+  if (oob) {
    ops.oobbuf = buf;
-  else
+   ops.ooblen = blocksize;
+  } else {
    ops.datbuf = buf;
+   ops.len = blocksize;
+  }
 
   ops.retlen = 0;
   ret = mtd->read_oob(mtd, ofs, &ops);
@@ -116,8 +129,7 @@ static int onenand_block_write(loff_t to, size_t len,
           size_t *retlen, const u_char * buf)
 {
  struct onenand_chip *this = mtd->priv;
- int blocks = len >> this->erase_shift;
- int blocksize = (1 << this->erase_shift);
+ int blocks, blocksize;
  loff_t ofs;
  size_t _retlen = 0;
  int ret;
@@ -131,11 +143,15 @@ static int onenand_block_write(loff_t to, size_t len,
  }
  ofs = to;
 
+ blocks = (int) onenand_block(this, ofs + len) - onenand_block(this, ofs);
+
  while (blocks) {
+  blocksize = onenand_blocksize(ofs);
+
   ret = mtd->block_isbad(mtd, ofs);
   if (ret) {
    printk("Bad blocks %d at 0x%x\n",
-          (u32)(ofs >> this->erase_shift), (u32)ofs);
+          (u32)onenand_block(this, ofs), (u32)ofs);
    skip_ofs += blocksize;
    goto next;
   }
@@ -165,13 +181,15 @@ static int onenand_block_erase(u32 start, u32 size, int force)
  };
  loff_t ofs;
  int ret;
- int blocksize = 1 << this->erase_shift;
+ int blocksize;
 
  for (ofs = start; ofs < (start + size); ofs += blocksize) {
+  blocksize = onenand_blocksize(ofs);
+
   ret = mtd->block_isbad(mtd, ofs);
   if (ret && !force) {
    printf("Skip erase bad block %d at 0x%x\n",
-          (u32)(ofs >> this->erase_shift), (u32)ofs);
+          (u32)onenand_block(this, ofs), (u32)ofs);
    continue;
   }
 
@@ -182,7 +200,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)
   ret = mtd->erase(mtd, &instr);
   if (ret) {
    printf("erase failed block %d at 0x%x\n",
-          (u32)(ofs >> this->erase_shift), (u32)ofs);
+          (u32)onenand_block(this, ofs), (u32)ofs);
    continue;
   }
  }
@@ -219,25 +237,27 @@ static int onenand_block_test(u32 start, u32 size)
   return -1;
  }
 
- start_block = start >> this->erase_shift;
- end_block = (start + size) >> this->erase_shift;
+ start_block = onenand_block(this, start);
+ end_block = onenand_block(this, start + size);
 
  /* 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;
+ if (end_block > onenand_block(this, mtd->size))
+  end_block = onenand_block(this, mtd->size);
 
  blocks = start_block;
  ofs = start;
  while (blocks < end_block) {
-  printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);
+  printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), (u32)ofs);
+
+  blocksize = onenand_blocksize(ofs);
 
   ret = mtd->block_isbad(mtd, ofs);
   if (ret) {
    printf("Skip erase bad block %d at 0x%x\n",
-          (u32)(ofs >> this->erase_shift), (u32)ofs);
+          (u32)onenand_block(this, ofs), (u32)ofs);
    goto next;
   }
 
@@ -341,7 +361,6 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 
  mtd = &onenand_mtd;
  this = mtd->priv;
- blocksize = (1 << this->erase_shift);
 
  cmd = argv[1];
 
@@ -359,9 +378,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
   if (strcmp(cmd, "bad") == 0) {
    /* Currently only one OneNAND device is supported */
    printf("\nDevice %d bad blocks:\n", 0);
-   for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
+   for (ofs = 0; ofs < mtd->size; ofs += blocksize) {
     if (mtd->block_isbad(mtd, ofs))
      printf("  %08x\n", (u32)ofs);
+
+    blocksize = onenand_blocksize(ofs);
    }
 
    return 0;
@@ -459,6 +480,26 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
    return ret == 0 ? 1 : 0;
   }
 
+  /*
+   * The following cmd holds true only for a Flex-OneNAND
+   */
+  if (FLEXONENAND(this)) {
+   if (strncmp(cmd, "setboundary", 11) == 0) {
+    int die, bdry, lock = 0;
+
+    if (argc < 4)
+     goto usage;
+
+    die = (int) simple_strtoul(argv[2], NULL, 0);
+    bdry = (int) simple_strtoul(argv[3], NULL, 0);
+
+    if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
+     lock = 1;
+
+    return flexonenand_set_boundary(mtd, die, bdry, lock);
+   }
+  }
+
   break;
  }
 
@@ -474,13 +515,15 @@ U_BOOT_CMD(
  "OneNAND sub-system",
  "info - show available OneNAND devices\n"
  "onenand bad - show bad blocks\n"
- "onenand read[.oob] addr off size\n"
- "onenand write[.oob] addr off size\n"
+ "onenand read[.oob] addr 'off' size\n"
+ "onenand write[.oob] addr 'off' size\n"
  "    read/write 'size' bytes starting at offset 'off'\n"
  "    to/from memory address 'addr', skipping bad blocks.\n"
- "onenand erase [force] [off size] - erase 'size' bytes from\n"
- "onenand test [off size] - test 'size' bytes from\n"
+ "onenand erase [force] ['off' size] - erase 'size' bytes from 'off'\n"
+ "onenand test ['off' size] - test 'size' bytes from\n"
  "    offset 'off' (entire device if not specified)\n"
- "onenand dump[.oob] off - dump page\n"
- "onenand markbad off - mark bad block at offset (UNSAFE)\n"
+ "onenand dump[.oob] 'off' - dump page\n"
+ "onenand markbad 'off' - mark bad block@offset (UNSAFE)\n"
+ "onenand setboundary DIE BOUNDARY [LOCK] - "
+ "Change SLC boundary of Flex-OneNAND\n"
 );
diff --git a/include/configs/apollon.h b/include/configs/apollon.h
index 0fcb22b..3a096c8 100644
--- a/include/configs/apollon.h
+++ b/include/configs/apollon.h
@@ -77,7 +77,7 @@
  */
 #define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */
 #define CONFIG_ENV_SIZE_FLEX SZ_256K
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M)
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_2M)
 /* bytes reserved for initial data */
 #define CONFIG_SYS_GBL_DATA_SIZE 128

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-23  7:06     ` Amul Kumar Saha
@ 2009-03-23 20:17       ` Scott Wood
  0 siblings, 0 replies; 9+ messages in thread
From: Scott Wood @ 2009-03-23 20:17 UTC (permalink / raw)
  To: u-boot

On Mon, Mar 23, 2009 at 12:36:32PM +0530, Amul Kumar Saha wrote:
> diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
> index 5832ff8..ed6681a 100644
> --- a/common/cmd_onenand.c
> +++ b/common/cmd_onenand.c
> @@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong 
> *off, size_t *size)
>  return 0;
> }
> 
> +static inline int onenand_blocksize(loff_t ofs)
> +{
> + struct onenand_chip *this = mtd->priv;
> + int i;

Patch is whitespace-damaged.  Please send the patch separately (not as a
reply; it's easy to miss patches at the end of a reply, and I have to
manually strip the discussion from the changelog) using something that
will preserve the patch text intact (not Outlook Express).

> + int blocks = (int) onenand_block(this, from + len)
> +    - onenand_block(this, from);

Why the (int) cast?  onenand_block() already returns int.

> - if (end_block > (mtd->size >> this->erase_shift))
> -  end_block = mtd->size >> this->erase_shift;
> + if (end_block > onenand_block(this, mtd->size))
> +  end_block = onenand_block(this, mtd->size);

This should probably be:

if (end_block >= onenand_block(this, mtd->size - 1))

...to avoid asking for a block that doesn't exist.

>  blocks = start_block;
>  ofs = start;
>  while (blocks < end_block) {
> -  printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), 
> (u32)ofs);
> +  printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), 
> (u32)ofs);

No (u32) cast on return from onenand_block().  Likewise elsewhere.

> @@ -359,9 +378,11 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, 
> char *argv[])
>   if (strcmp(cmd, "bad") == 0) {
>    /* Currently only one OneNAND device is supported */
>    printf("\nDevice %d bad blocks:\n", 0);
> -   for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
> +   for (ofs = 0; ofs < mtd->size; ofs += blocksize) {
>     if (mtd->block_isbad(mtd, ofs))
>      printf("  %08x\n", (u32)ofs);
> +
> +    blocksize = onenand_blocksize(ofs);
>    }

Hmm, not sure I like blocksize being used in the for loop when it's first
initialized in the body of the loop.  It's valid code, but it might be
more readable as a while loop.

> +    die = (int) simple_strtoul(argv[2], NULL, 0);
> +    bdry = (int) simple_strtoul(argv[3], NULL, 0);

Casts should not be necessary.

> +    if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
> +     lock = 1;

Please have commands be lower-case, just like all the other ones.

-Scott

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-09 21:38   ` Scott Wood
  2009-03-23  7:06     ` Amul Kumar Saha
@ 2009-03-25 15:14     ` Amul Kumar Saha
  2009-03-25 17:23       ` Scott Wood
  1 sibling, 1 reply; 9+ messages in thread
From: Amul Kumar Saha @ 2009-03-25 15:14 UTC (permalink / raw)
  To: u-boot

Hi Scott,

> 
>> + int blocks = (int) onenand_block(this, from + len)
>> +    - onenand_block(this, from);
> 
> Why the (int) cast?  onenand_block() already returns int.
> 

Resolved

>> - if (end_block > (mtd->size >> this->erase_shift))
>> -  end_block = mtd->size >> this->erase_shift;
>> + if (end_block > onenand_block(this, mtd->size))
>> +  end_block = onenand_block(this, mtd->size);
> 
> This should probably be:
> 
> if (end_block >= onenand_block(this, mtd->size - 1))
> 
> ...to avoid asking for a block that doesn't exist.
> 

Changed from mtd->size to (mtd->size) - 1,
In the OP, end_block was understood to accomodate (last_block_no + 1).
But, as you have pointed it may be more conventional to have the exact last_block_no

made necessary changes in some other places as well.

>>  blocks = start_block;
>>  ofs = start;
>>  while (blocks < end_block) {
>> -  printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), 
>> (u32)ofs);
>> +  printf("\rTesting block %d at 0x%x", (u32) onenand_block(this, ofs), 
>> (u32)ofs);
> 
> No (u32) cast on return from onenand_block().  Likewise elsewhere.
> 

Accepted and changed.

>> +   for (ofs = 0; ofs < mtd->size; ofs += blocksize) {
>>     if (mtd->block_isbad(mtd, ofs))
>>      printf("  %08x\n", (u32)ofs);
>> +
>> +    blocksize = onenand_blocksize(ofs);
>>    }
> 
> Hmm, not sure I like blocksize being used in the for loop when it's first
> initialized in the body of the loop.  It's valid code, but it might be
> more readable as a while loop.
> 

Modified it to a while loop. Thanks :)

ofs = 0;
while (ofs < mtd->size) {
 if (mtd->block_isbad(mtd, ofs))
     printf("  %08x\n", (u32)ofs);
 ofs += onenand_blocksize(ofs);
}

>> +    die = (int) simple_strtoul(argv[2], NULL, 0);
>> +    bdry = (int) simple_strtoul(argv[3], NULL, 0);
> 
> Casts should not be necessary.
> 

I believe that typecasting a UL to an int, is OK.
Do let me know.

>> +    if (argc == 5 && strncmp(argv[4], "LOCK", 4) == 0)
>> +     lock = 1;
> 
> Please have commands be lower-case, just like all the other ones.
> 
Changed

Do let me know, your feedback on the changes made.
I'll send the updated patch, in the next post.

With regards,
Amul

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-25 15:14     ` Amul Kumar Saha
@ 2009-03-25 17:23       ` Scott Wood
  2009-03-26 12:21         ` Amul Kumar Saha
  2009-03-26 12:35         ` Amul Kumar Saha
  0 siblings, 2 replies; 9+ messages in thread
From: Scott Wood @ 2009-03-25 17:23 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 25, 2009 at 08:44:37PM +0530, Amul Kumar Saha wrote:
> >> +    die = (int) simple_strtoul(argv[2], NULL, 0);
> >> +    bdry = (int) simple_strtoul(argv[3], NULL, 0);
> > 
> > Casts should not be necessary.
> > 
> 
> I believe that typecasting a UL to an int, is OK.
> Do let me know.

The compiler will implicitly cast unsigned long to int.  The explicit cast
is unnecessary clutter which makes it harder to find casts that aren't OK.

-Scott

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-25 17:23       ` Scott Wood
@ 2009-03-26 12:21         ` Amul Kumar Saha
  2009-03-26 12:35         ` Amul Kumar Saha
  1 sibling, 0 replies; 9+ messages in thread
From: Amul Kumar Saha @ 2009-03-26 12:21 UTC (permalink / raw)
  To: u-boot

Hi Scott,

>> I believe that typecasting a UL to an int, is OK.
>> Do let me know.
> 
> The compiler will implicitly cast unsigned long to int.  The explicit cast
> is unnecessary clutter which makes it harder to find casts that aren't OK.

Accepted and changed.

Thank You
Amul.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
  2009-03-25 17:23       ` Scott Wood
  2009-03-26 12:21         ` Amul Kumar Saha
@ 2009-03-26 12:35         ` Amul Kumar Saha
  1 sibling, 0 replies; 9+ messages in thread
From: Amul Kumar Saha @ 2009-03-26 12:35 UTC (permalink / raw)
  To: u-boot

OneNAND commands now work for Flex-OneNAND.
Add command for changing Flex-OneNAND SLC / MLC boundary.

Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com>
Signed-off-by: Amul Kumar Saha <amul.saha@samsung.com>
---
common/cmd_onenand.c      |  103 ++++++++++++++++++++++++++++++++--------------
include/configs/apollon.h |    2
2 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 5832ff8..8d25238 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -65,36 +65,49 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size)
 	return 0;
 }
 
+static inline int onenand_blocksize(loff_t ofs)
+{
+	struct onenand_chip *this = mtd->priv;
+	int i;
+
+	if (!FLEXONENAND(this))
+		return mtd->erasesize;
+
+	i = flexonenand_region(mtd, ofs);
+	return mtd->eraseregions[i].erasesize;
+}
+
 static int onenand_block_read(loff_t from, size_t len,
 			      size_t *retlen, u_char *buf, int oob)
 {
 	struct onenand_chip *this = mtd->priv;
-	int blocks = (int) len >> this->erase_shift;
-	int blocksize = (1 << this->erase_shift);
+	int blocks = onenand_block(this, from + len)
+			 - onenand_block(this, from);
+	int blocksize;
 	loff_t ofs = from;
 	struct mtd_oob_ops ops = {
 		.retlen		= 0,
 	};
 	int ret;
 
-	if (oob)
-		ops.ooblen = blocksize;
-	else
-		ops.len = blocksize;
-
 	while (blocks) {
+		blocksize = onenand_blocksize(ofs);
+
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret) {
 			printk("Bad blocks %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       onenand_block(this, ofs), (u32)ofs);
 			ofs += blocksize;
 			continue;
 		}
 
-		if (oob)
+		if (oob) {
 			ops.oobbuf = buf;
-		else
+			ops.ooblen = blocksize;
+		} else {
 			ops.datbuf = buf;
+			ops.len = blocksize;
+		}
 
 		ops.retlen = 0;
 		ret = mtd->read_oob(mtd, ofs, &ops);
@@ -116,8 +129,7 @@ static int onenand_block_write(loff_t to, size_t len,
 			       size_t *retlen, const u_char * buf)
 {
 	struct onenand_chip *this = mtd->priv;
-	int blocks = len >> this->erase_shift;
-	int blocksize = (1 << this->erase_shift);
+	int blocks, blocksize;
 	loff_t ofs;
 	size_t _retlen = 0;
 	int ret;
@@ -131,11 +143,15 @@ static int onenand_block_write(loff_t to, size_t len,
 	}
 	ofs = to;
 
+	blocks = onenand_block(this, ofs + len) - onenand_block(this, ofs);
+
 	while (blocks) {
+		blocksize = onenand_blocksize(ofs);
+
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret) {
 			printk("Bad blocks %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       onenand_block(this, ofs), (u32)ofs);
 			skip_ofs += blocksize;
 			goto next;
 		}
@@ -165,13 +181,15 @@ static int onenand_block_erase(u32 start, u32 size, int force)
 	};
 	loff_t ofs;
 	int ret;
-	int blocksize = 1 << this->erase_shift;
+	int blocksize;
 
 	for (ofs = start; ofs < (start + size); ofs += blocksize) {
+		blocksize = onenand_blocksize(ofs);
+
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret && !force) {
 			printf("Skip erase bad block %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       onenand_block(this, ofs), (u32)ofs);
 			continue;
 		}
 
@@ -182,7 +200,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)
 		ret = mtd->erase(mtd, &instr);
 		if (ret) {
 			printf("erase failed block %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       onenand_block(this, ofs), (u32)ofs);
 			continue;
 		}
 	}
@@ -219,25 +237,27 @@ static int onenand_block_test(u32 start, u32 size)
 		return -1;
 	}
 
-	start_block = start >> this->erase_shift;
-	end_block = (start + size) >> this->erase_shift;
+	start_block = onenand_block(this, start);
+	end_block = onenand_block(this, start + size - 1);
 
 	/* 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;
+	if (end_block > onenand_block(this, mtd->size - 1))
+		end_block = onenand_block(this, mtd->size - 1);
 
 	blocks = start_block;
 	ofs = start;
-	while (blocks < end_block) {
-		printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);
+	while (blocks <= end_block) {
+		printf("\rTesting block %d@0x%x", onenand_block(this, ofs), (u32)ofs);
+
+		blocksize = onenand_blocksize(ofs);
 
 		ret = mtd->block_isbad(mtd, ofs);
 		if (ret) {
 			printf("Skip erase bad block %d at 0x%x\n",
-			       (u32)(ofs >> this->erase_shift), (u32)ofs);
+			       onenand_block(this, ofs), (u32)ofs);
 			goto next;
 		}
 
@@ -341,7 +361,6 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 
 	mtd = &onenand_mtd;
 	this = mtd->priv;
-	blocksize = (1 << this->erase_shift);
 
 	cmd = argv[1];
 
@@ -359,9 +378,12 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		if (strcmp(cmd, "bad") == 0) {
 			/* Currently only one OneNAND device is supported */
 			printf("\nDevice %d bad blocks:\n", 0);
-			for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
+			ofs = 0;
+			while (ofs < mtd->size) {
 				if (mtd->block_isbad(mtd, ofs))
 					printf("  %08x\n", (u32)ofs);
+
+				ofs += onenand_blocksize(ofs);
 			}
 
 			return 0;
@@ -459,6 +481,23 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 			return ret == 0 ? 1 : 0;
 		}
 
+		if (FLEXONENAND(this)) {
+			if (strncmp(cmd, "setboundary", 11) == 0) {
+				int die, bdry, lock = 0;
+
+				if (argc < 4)
+					goto usage;
+
+				die = (int) simple_strtoul(argv[2], NULL, 0);
+				bdry = (int) simple_strtoul(argv[3], NULL, 0);
+
+				if (argc == 5 && strncmp(argv[4], "lock", 4) == 0)
+					lock = 1;
+
+				return flexonenand_set_boundary(mtd, die, bdry, lock);
+			}
+		}
+
 		break;
 	}
 
@@ -474,13 +513,15 @@ U_BOOT_CMD(
 	"OneNAND sub-system",
 	"info - show available OneNAND devices\n"
 	"onenand bad - show bad blocks\n"
-	"onenand read[.oob] addr off size\n"
-	"onenand write[.oob] addr off size\n"
+	"onenand read[.oob] addr 'off' size\n"
+	"onenand write[.oob] addr 'off' size\n"
 	"    read/write 'size' bytes starting at offset 'off'\n"
 	"    to/from memory address 'addr', skipping bad blocks.\n"
-	"onenand erase [force] [off size] - erase 'size' bytes from\n"
-	"onenand test [off size] - test 'size' bytes from\n"
+	"onenand erase [force] ['off' size] - erase 'size' bytes from 'off'\n"
+	"onenand test ['off' size] - test 'size' bytes from\n"
 	"    offset 'off' (entire device if not specified)\n"
-	"onenand dump[.oob] off - dump page\n"
-	"onenand markbad off - mark bad block at offset (UNSAFE)\n"
+	"onenand dump[.oob] 'off' - dump page\n"
+	"onenand markbad 'off' - mark bad block@offset (UNSAFE)\n"
+	"onenand setboundary DIE BOUNDARY [LOCK] - "
+	"Change SLC boundary of Flex-OneNAND\n"
 );
diff --git a/include/configs/apollon.h b/include/configs/apollon.h
index 0fcb22b..3a096c8 100644
--- a/include/configs/apollon.h
+++ b/include/configs/apollon.h
@@ -77,7 +77,7 @@
  */
 #define	CONFIG_ENV_SIZE SZ_128K	/* Total Size of Environment Sector */
 #define CONFIG_ENV_SIZE_FLEX SZ_256K
-#define	CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + SZ_1M)
+#define	CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + SZ_2M)
 /* bytes reserved for initial data */
 #define	CONFIG_SYS_GBL_DATA_SIZE	128

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-03-26 12:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-11 14:27 [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command Rohit Hagargundgi
2009-03-08  6:47 ` Rohit Hagargundgi
2009-03-09 21:38   ` Scott Wood
2009-03-23  7:06     ` Amul Kumar Saha
2009-03-23 20:17       ` Scott Wood
2009-03-25 15:14     ` Amul Kumar Saha
2009-03-25 17:23       ` Scott Wood
2009-03-26 12:21         ` Amul Kumar Saha
2009-03-26 12:35         ` Amul Kumar Saha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox