public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Rohit Hagargundgi <h.rohit@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 4/4] Flex-OneNAND boundary setting command
Date: Sun, 08 Mar 2009 12:17:36 +0530	[thread overview]
Message-ID: <200903081217.36696.h.rohit@samsung.com> (raw)
In-Reply-To: <49412369.6010707@samsung.com>

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"
 );

  reply	other threads:[~2009-03-08  6:47 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200903081217.36696.h.rohit@samsung.com \
    --to=h.rohit@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox