[PATCH] nandboot with 2k pages
Thu Dec 11 11:56:01 CET 2008
---
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
------=_Part_52959_933696.1229345345706--
More information about the U-Boot
mailing list