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.ro...@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 at 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 at offset (UNSAFE)\n"
+       "onenand setboundary DIE BOUNDARY [LOCK] - "
+       "Change SLC boundary of Flex-OneNAND\n"
 );
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to