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