Linuxppc-dev Digest, Vol 88, Issue 24
Liu Shengzhou-B36685
B36685 at freescale.com
Fri Dec 9 20:27:57 EST 2011
> -----Original Message-----
>
> Message: 4
> Date: Sun, 4 Dec 2011 12:31:38 +0800
> From: <shuo.liu at freescale.com>
> To: <dwmw2 at infradead.org>, <Artem.Bityutskiy at nokia.com>,
> <scottwood at freescale.com>
> Cc: linux-kernel at vger.kernel.org, shuo.liu at freescale.com,
> linux-mtd at lists.infradead.org, akpm at linux-foundation.org,
> linuxppc-dev at 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.liu at freescale.com>
> Content-Type: text/plain
>
> From: Liu Shuo <shuo.liu at 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.liu at 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);
More information about the Linuxppc-dev
mailing list