[U-Boot] [U-Boot-v2][PATCH] imx27: nandboot with 2k pages

frederic Rodo f.rodo at til-technologies.fr
Thu Dec 11 14:14:41 CET 2008


Signed-off-by:Frederic Rodo <fred.rodo at gmail.com>
---
 drivers/nand/nand_imx.c             |   94
+++++++++++++++++++++++++++++------
 include/asm-arm/arch-imx/imx-nand.h |    2 +-
 2 files changed, 79 insertions(+), 17 deletions(-)

diff --git a/drivers/nand/nand_imx.c b/drivers/nand/nand_imx.c
index f7f50b0..3bf67de 100644
--- a/drivers/nand/nand_imx.c
+++ b/drivers/nand/nand_imx.c
@@ -1090,26 +1090,74 @@ static struct driver_d imx_nand_driver = {
 
 static void __nand_boot_init nfc_addr(struct imx_nand_host *host, u32 offs)
 {
-    send_addr(host, offs & 0xff);
-    send_addr(host, (offs >> 9) & 0xff);
-    send_addr(host, (offs >> 17) & 0xff);
-    send_addr(host, (offs >> 25) & 0xff);
+    if (!host->pagesize_2k) {
+        send_addr(host, offs & 0xff);
+        send_addr(host, (offs >> 9) & 0xff);
+        send_addr(host, (offs >> 17) & 0xff);
+        send_addr(host, (offs >> 25) & 0xff);
+    } else {
+        /* imx27 Nand flash controller can only read full 2k page */
+        send_addr(host, 0);
+        send_addr(host, 0);
+        send_addr(host, (offs >> 11) & 0xff);
+        send_addr(host, (offs >> 19) & 0xff);
+        /* FIXME: add another send_addr for nandflash > 1Gbit
+         * if (read electronic signature byte 5 > 1 Gbit)
+         *    send_addr(host, (offs >> 28) & 0xff);
+         */
+
+        /* send read start command */
+        send_cmd(host, NAND_CMD_READSTART);
+    }
 }
 
-static int __nand_boot_init block_is_bad(struct imx_nand_host *host,
u32 offs)
+static int __nand_boot_init block_is_bad(struct imx_nand_host *host,
u32 offs,
+                     u32 pagesize)
 {
-    send_cmd(host, NAND_CMD_READOOB);
-    nfc_addr(host, offs);
-    send_read_page(host, 0, 1);
-
-    return (readw(host->regs + SPARE_AREA0) & 0xff) == 0xff ? 0 : 1;
+    if (!host->pagesize_2k) {
+        send_cmd(host, NAND_CMD_READOOB);
+        nfc_addr(host, offs);
+        send_read_page(host, 0, 1);
+        if ((readw(host->regs + SPARE_AREA0) & 0xff) != 0xff)
+            return 1;
+    } else {
+        /* The AdvancedToolKit Mark the two first page of each block */
+        /* check first page */
+        send_cmd(host, NAND_CMD_READ0);
+        nfc_addr(host, offs);
+        send_read_page(host, 0, 1);
+        send_read_page(host, 1, 1);
+        send_read_page(host, 2, 1);
+        send_read_page(host, 3, 1);
+
+        if (readw(host->regs + NFC_ECC_STATUS_RESULT) & 0xa)
+            return 1;
+
+        if ((readw(host->regs + SPARE_AREA0 + 4) & 0xFF00) != 0xFF00)
+            return 1;
+
+        /* check second page */
+        send_cmd(host, NAND_CMD_READ0);
+        nfc_addr(host, offs + pagesize);
+        send_read_page(host, 0, 1);
+        send_read_page(host, 1, 1);
+        send_read_page(host, 2, 1);
+        send_read_page(host, 3, 1);
+
+        if (readw(host->regs + NFC_ECC_STATUS_RESULT) & 0xa)
+            return 1;
+
+        if ((readw(host->regs + SPARE_AREA0 + 4) & 0xFF00) != 0xFF00)
+            return 1;
+   
+    }
+    return 0;
 }
 
-void __nand_boot_init imx_nand_load_image(void *dest, int size, int
pagesize,
-        int blocksize)
+void __nand_boot_init imx_nand_load_image(void *dest, int size, int
blocksize)
 {
     struct imx_nand_host host;
-    u32 tmp, page, block;
+    u32 tmp, page, block, pagesize;
 
     PCCR1 |= PCCR1_NFC_BAUDEN;
 
@@ -1117,6 +1165,10 @@ void __nand_boot_init imx_nand_load_image(void
*dest, int size, int pagesize,
     case GPCR_BOOT_8BIT_NAND_2k:
     case GPCR_BOOT_16BIT_NAND_2k:
         host.pagesize_2k = 1;
+        pagesize = 2048;
+        break;
+    default:
+        pagesize = 512;
     }
 
     host.regs = (void __iomem *)IMX_NFC_BASE;
@@ -1134,14 +1186,19 @@ void __nand_boot_init imx_nand_load_image(void
*dest, int size, int pagesize,
     /* Unlock Block Command for given address range */
     writew(0x4, host.regs + NFC_WRPROT);
 
+    /* clear all operation  */
+    writew(0x8000, host.regs + NFC_CONFIG1);
+
+    /* enable ECC, disable spare only and interrupt */
     tmp = readw(host.regs + NFC_CONFIG1);
-    tmp |= NFC_ECC_EN;
+    tmp |= NFC_ECC_EN | NFC_INT_MSK;
+    tmp &= ~ NFC_SP_EN;
     writew(tmp, host.regs + NFC_CONFIG1);
 
     block = page = 0;
 
     while (1) {
-        if (!block_is_bad(&host, block * blocksize)) {
+        if (!block_is_bad(&host, block * blocksize, pagesize)) {
             page = 0;
             while (page * pagesize < blocksize) {
                 debug("page: %d block: %d dest: %p src "
@@ -1154,8 +1211,13 @@ void __nand_boot_init imx_nand_load_image(void
*dest, int size, int pagesize,
                 nfc_addr(&host, block * blocksize +
                         page * pagesize);
                 send_read_page(&host, 0, 0);
+                if (host.pagesize_2k) {
+                    send_read_page(&host, 1, 0);
+                    send_read_page(&host, 2, 0);
+                    send_read_page(&host, 3, 0);
+                }
                 page++;
-                memcpy32(dest, host.regs, 512);
+                memcpy32(dest, host.regs, pagesize);
                 dest += pagesize;
                 size -= pagesize;
                 if (size <= 0)
diff --git a/include/asm-arm/arch-imx/imx-nand.h
b/include/asm-arm/arch-imx/imx-nand.h
index 5ebe0be..eca8fef 100644
--- a/include/asm-arm/arch-imx/imx-nand.h
+++ b/include/asm-arm/arch-imx/imx-nand.h
@@ -3,7 +3,7 @@
 
 #include <linux/mtd/mtd.h>
 
-void imx_nand_load_image(void *dest, int size, int pagesize, int
blocksize);
+void imx_nand_load_image(void *dest, int size, int blocksize);
 
 struct imx_nand_platform_data {
     int width;
-- 
1.4.4.4



-------------------------------------------------------------------------
Les informations précédentes peuvent être confidentielles ou privilégiées.
Si vous n'êtes pas le destinataire prévu de ce mail, veuillez en notifier 
l'expéditeur en répondant à ce message puis supprimez-en toute trace 
de vos systèmes.

TIL Technologies
Parc du Golf, Bat 43
350 rue J.R Guilibert Gautier de la Lauzière 
13856 AIX EN PROVENCE
Tel. : +33 4 42 37 11 77
-------------------------------------------------------------------------




More information about the U-Boot mailing list