> -----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