* [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