[U-Boot] [PATCH 3/3] [OneNAND] Flex-OneNAND boundary settings
Amul Kumar Saha
amul.saha at samsung.com
Wed Nov 11 06:57:52 CET 2009
Add command for changing Flex-OneNAND SLC / MLC boundary.
Also onenand commands work for Flex-OneNAND.
Signed-off-by: Rohit Hagargundgi <h.rohit at samsung.com>
Signed-off-by: Amul Kumar Saha <amul.saha at samsung.com>
---
common/cmd_onenand.c | 106 +++++++++++++++++++++++++++++++---------------
include/configs/apollon.h | 2
2 files changed, 74 insertions(+), 34 deletions(-)
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 9090940..d6aff90 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -69,36 +69,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);
+ printk("Bad blocks %u at 0x%llx\n",
+ onenand_block(this, ofs), 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);
@@ -120,8 +133,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;
@@ -135,11 +147,16 @@ 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);
+ printk("Bad blocks %u at 0x%llx\n",
+ onenand_block(this, ofs), ofs);
skip_ofs += blocksize;
goto next;
}
@@ -169,13 +186,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);
+ printf("Skip erase bad block %u at 0x%llx\n",
+ onenand_block(this, ofs), ofs);
continue;
}
@@ -185,8 +204,8 @@ static int onenand_block_erase(u32 start, u32 size, int force)
instr.mtd = mtd;
ret = mtd->erase(mtd, &instr);
if (ret) {
- printf("erase failed block %d at 0x%x\n",
- (u32)(ofs >> this->erase_shift), (u32)ofs);
+ printf("erase failed block %u at 0x%llx\n",
+ onenand_block(this, ofs), ofs);
continue;
}
}
@@ -223,25 +242,28 @@ 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 at 0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);
+ printf("\rTesting block %u at 0x%llx",
+ onenand_block(this, ofs), 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);
+ printf("Skip erase bad block %u at 0x%llx\n",
+ onenand_block(this, ofs), ofs);
goto next;
}
@@ -345,7 +367,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];
@@ -363,9 +384,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;
@@ -474,6 +497,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;
}
@@ -491,11 +529,13 @@ U_BOOT_CMD(
"onenand bad - show bad blocks\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"
+ "\tread/write 'size' bytes starting at offset 'off'\n"
+ "\tto/from memory address 'addr', skipping bad blocks.\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"
+ "\toffset 'off' (entire device if not specified)\n"
"onenand dump[.oob] off - dump page\n"
"onenand markbad off [...] - mark bad block(s) at offset (UNSAFE)"
+ "onenand setboundary DIE BOUNDARY [LOCK] - \n"
+ "\tChange SLC boundary of Flex-OneNAND\n"
);
diff --git a/include/configs/apollon.h b/include/configs/apollon.h
index ddac5fb..5a97743 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
More information about the U-Boot
mailing list