-Original Message-
Message: 4
Date: Sun, 4 Dec 2011 12:31:38 +0800
From: shuo@freescale.com
To: dw...@infradead.org, artem.bityuts...@nokia.com,
scottw...@freescale.com
Cc: linux-ker...@vger.kernel.org, shuo@freescale.com,
linux-...@lists.infradead.org, a...@linux-foundation.org,
linuxppc-dev@lists.ozlabs.org
Subject: [PATCH 3/3] mtd/nand : workaround for Freescale FCM to
support large-page Nand chip
Message-ID: 1322973098-2528-3-git-send-email-shuo@freescale.com
Content-Type: text/plain
From: Liu Shuo shuo@freescale.com
Freescale FCM controller has a 2K size limitation of buffer RAM. In order
to support the Nand flash chip whose page size is larger than 2K bytes,
we read/write 2k data repeatedly by issuing FIR_OP_RB/FIR_OP_WB and save
them to a large buffer.
Signed-off-by: Liu Shuo shuo@freescale.com
---
v3:
-remove page_size of struct fsl_elbc_mtd.
-do a oob write by NAND_CMD_RNDIN.
drivers/mtd/nand/fsl_elbc_nand.c | 243
++
1 files changed, 218 insertions(+), 25 deletions(-)
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c
b/drivers/mtd/nand/fsl_elbc_nand.c
index d634c5f..a92411a 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
[SNIP]
@@ -500,6 +654,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd,
unsigned int command,
* write-protected, even when it is not.
*/
setbits8(elbc_fcm_ctrl-addr, NAND_STATUS_WP);
+ elbc_fcm_ctrl-buffer[0] = in_8(elbc_fcm_ctrl-addr);
[Shengzhou] add if (mtd-writesize 2048)
return;
/* RESET without waiting for the ready line */
@@ -548,7 +703,14 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd,
const u8 *buf, int len)
len = bufsize - elbc_fcm_ctrl-index;
}
- memcpy_toio(elbc_fcm_ctrl-addr[elbc_fcm_ctrl-index], buf, len);
+ if (mtd-writesize 2048) {
+ memcpy(elbc_fcm_ctrl-buffer[elbc_fcm_ctrl-index],
+ buf, len);
+ } else {
+ memcpy_toio(elbc_fcm_ctrl-addr[elbc_fcm_ctrl-index],
+ buf, len);
+ }
+
setbits32(lbc-bank[priv-bank].or, OR_FCM_PGS);
/* adjust ecc setup if needed */
if ((in_be32(lbc-bank[priv-bank].br) BR_DECC) ==
@@ -891,6 +1070,19 @@ static int __devinit fsl_elbc_nand_probe(struct
platform_device *pdev)
goto err;
}
elbc_fcm_ctrl-counter++;
+ /*
+ * Freescale FCM controller has a 2K size limitation of
buffer
+ * RAM, so elbc_fcm_ctrl-buffer have to be used if writesize
+ * of chip is greater than 2048.
+ * We malloc a large enough buffer (maximum page size is 16K).
+ */
+ elbc_fcm_ctrl-buffer = kmalloc(1024 * 16 + 1024, GFP_KERNEL);
+ if (!elbc_fcm_ctrl-buffer) {
+ dev_err(dev, failed to allocate memory\n);
+ mutex_unlock(fsl_elbc_nand_mutex);
+ ret = -ENOMEM;
+ goto err;
+ }
[Shengzhou]
Before calling nand_scan_ident(), we can still use 2k FCM RAM, not need a
buffer greater than 2k,
After nand_scan_ident(), if writesize 2048, then allocate a large buffer.
We can do it in fsl_elbc_chip_init_tail()
if (mtd-writesize 2048)
ctrl-buffer = kmalloc(mtd-writesize + mtd-oobsize, GFP_KERNEL);
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev