From mboxrd@z Thu Jan 1 00:00:00 1970 From: Amul Kumar Saha Date: Wed, 04 Nov 2009 10:39:41 +0530 Subject: [U-Boot] [PATCH 3/3] [OneNAND] Flex-OneNAND boundary settings References: Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Add command for changing Flex-OneNAND SLC / MLC boundary. Also onenand commands work for Flex-OneNAND. Signed-off-by: Rohit Hagargundgi Signed-off-by: Amul Kumar Saha --- common/cmd_onenand.c | 90 +++++++++++++++++++++++++++++++++------------- include/configs/apollon.h | 2 - 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 9090940..a34befe 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 = (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); @@ -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); + (u32)onenand_block(this, ofs), (u32)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); + (u32)onenand_block(this, ofs), (u32)ofs); continue; } @@ -186,7 +205,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; } } @@ -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@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; } @@ -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; } @@ -493,9 +531,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(s)@offset (UNSAFE)" + "onenand setboundary DIE BOUNDARY [LOCK] - \n" + "Change 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