linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly
@ 2011-12-09  9:42 shuo.liu
  2011-12-09  9:42 ` [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip shuo.liu
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: shuo.liu @ 2011-12-09  9:42 UTC (permalink / raw)
  To: dwmw2, Artem.Bityutskiy, scottwood
  Cc: linux-kernel, shuo.liu, linux-mtd, akpm, linuxppc-dev

From: Liu Shuo <b35362@freescale.com>

If we use the Nand flash chip whose number of pages in a block is greater
than 64(for large page), we must treat the low bit of FBAR as being the
high bit of the page address due to the limitation of FCM, it simply uses
the low 6-bits (for large page) of the combined block/page address as the
FPAR component, rather than considering the actual block size.

Signed-off-by: Liu Shuo <b35362@freescale.com>
Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
Signed-off-by: Tang Yuantian <b29983@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 drivers/mtd/nand/fsl_elbc_nand.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 7db573e..d29479a 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -166,15 +166,22 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
 	elbc_fcm_ctrl->page = page_addr;
 
-	out_be32(&lbc->fbar,
-	         page_addr >> (chip->phys_erase_shift - chip->page_shift));
-
 	if (priv->page_size) {
+		/*
+		 * large page size chip : FPAR[PI] save the lowest 6 bits,
+		 *                        FBAR[BLK] save the other bits.
+		 */
+		out_be32(&lbc->fbar, page_addr >> 6);
 		out_be32(&lbc->fpar,
 		         ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) |
 		         (oob ? FPAR_LP_MS : 0) | column);
 		buf_num = (page_addr & 1) << 2;
 	} else {
+		/*
+		 * small page size chip : FPAR[PI] save the lowest 5 bits,
+		 *                        FBAR[BLK] save the other bits.
+		 */
+		out_be32(&lbc->fbar, page_addr >> 5);
 		out_be32(&lbc->fpar,
 		         ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) |
 		         (oob ? FPAR_SP_MS : 0) | column);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
  2011-12-09  9:42 [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly shuo.liu
@ 2011-12-09  9:42 ` shuo.liu
  2011-12-09 19:24   ` Scott Wood
  2011-12-09 19:23 ` [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly Scott Wood
  2011-12-12 21:04 ` Artem Bityutskiy
  2 siblings, 1 reply; 5+ messages in thread
From: shuo.liu @ 2011-12-09  9:42 UTC (permalink / raw)
  To: dwmw2, Artem.Bityutskiy, scottwood
  Cc: linux-kernel, shuo.liu, linux-mtd, akpm, linuxppc-dev

From: Liu Shuo <shuo.liu@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@freescale.com>
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
v4 : allocate (8+1)k buffer for large page chip.

 drivers/mtd/nand/fsl_elbc_nand.c |  246 ++++++++++++++++++++++++++++++++++----
 1 files changed, 221 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index d29479a..9f58e78 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -55,7 +55,6 @@ struct fsl_elbc_mtd {
 	struct device *dev;
 	int bank;               /* Chip select bank number           */
 	u8 __iomem *vbase;      /* Chip select base virtual address  */
-	int page_size;          /* NAND page size (0=512, 1=2048)    */
 	unsigned int fmr;       /* FCM Flash Mode Register value     */
 };
 
@@ -75,6 +74,8 @@ struct fsl_elbc_fcm_ctrl {
 	unsigned int use_mdr;    /* Non zero if the MDR is to be set      */
 	unsigned int oob;        /* Non zero if operating on OOB data     */
 	unsigned int counter;	 /* counter for the initializations	  */
+
+	char *buffer;            /* just be used when pagesize > 2048     */
 };
 
 /* These map to the positions used by the FCM hardware ECC generator */
@@ -150,6 +151,42 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 };
 
 /*=================================*/
+static void io_to_buffer(struct mtd_info *mtd, int subpage, int oob)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct fsl_elbc_mtd *priv = chip->priv;
+	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
+	void *src, *dst;
+	int len = (oob ? 64 : 2048);
+
+	if (oob)
+		dst = elbc_fcm_ctrl->buffer + mtd->writesize + subpage * 64;
+	else
+		dst = elbc_fcm_ctrl->buffer + subpage * 2048;
+
+	src = elbc_fcm_ctrl->addr + (oob ? 2048 : 0);
+	memcpy_fromio(dst, src, len);
+}
+
+static void buffer_to_io(struct mtd_info *mtd, int subpage, int oob)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct fsl_elbc_mtd *priv = chip->priv;
+	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
+	void *src, *dst;
+	int len = (oob ? 64 : 2048);
+
+	if (oob)
+		src = elbc_fcm_ctrl->buffer + mtd->writesize + subpage * 64;
+	else
+		src = elbc_fcm_ctrl->buffer + subpage * 2048;
+
+	dst = elbc_fcm_ctrl->addr + (oob ? 2048 : 0);
+	memcpy_toio(dst, src, len);
+
+	/* See the in_8() in fsl_elbc_write_buf() */
+	in_8(elbc_fcm_ctrl->addr + (oob ? 2111 : 2047));
+}
 
 /*
  * Set up the FCM hardware block and page address fields, and the fcm
@@ -166,7 +203,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
 	elbc_fcm_ctrl->page = page_addr;
 
-	if (priv->page_size) {
+	if (mtd->writesize >= 2048) {
 		/*
 		 * large page size chip : FPAR[PI] save the lowest 6 bits,
 		 *                        FBAR[BLK] save the other bits.
@@ -193,7 +230,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
 	/* for OOB data point to the second half of the buffer */
 	if (oob)
-		elbc_fcm_ctrl->index += priv->page_size ? 2048 : 512;
+		elbc_fcm_ctrl->index += mtd->writesize;
 
 	dev_vdbg(priv->dev, "set_addr: bank=%d, "
 			    "elbc_fcm_ctrl->addr=0x%p (0x%p), "
@@ -272,13 +309,14 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
 	return 0;
 }
 
-static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
+static void fsl_elbc_do_read(struct mtd_info *mtd, int oob)
 {
+	struct nand_chip *chip = mtd->priv;
 	struct fsl_elbc_mtd *priv = chip->priv;
 	struct fsl_lbc_ctrl *ctrl = priv->ctrl;
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
-	if (priv->page_size) {
+	if (mtd->writesize >= 2048) {
 		out_be32(&lbc->fir,
 		         (FIR_OP_CM0 << FIR_OP0_SHIFT) |
 		         (FIR_OP_CA  << FIR_OP1_SHIFT) |
@@ -311,6 +349,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 	struct fsl_lbc_ctrl *ctrl = priv->ctrl;
 	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+	int i, n;
 
 	elbc_fcm_ctrl->use_mdr = 0;
 
@@ -337,8 +376,30 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
 		elbc_fcm_ctrl->index += column;
 
-		fsl_elbc_do_read(chip, 0);
+		fsl_elbc_do_read(mtd, 0);
 		fsl_elbc_run_command(mtd);
+
+		if (mtd->writesize <= 2048)
+			return;
+
+		/* Continue to read the rest bytes if writesize > 2048 */
+		io_to_buffer(mtd, 0, 0);
+		io_to_buffer(mtd, 0, 1);
+
+		/*
+		 * Maybe there are some reasons of FCM hardware timing,
+		 * we must insert a FIR_OP_NOP(0x00) before FIR_OP_RB.
+		 */
+		out_be32(&lbc->fir, (FIR_OP_NOP << FIR_OP0_SHIFT) |
+				    (FIR_OP_RB  << FIR_OP1_SHIFT));
+
+		n = mtd->writesize / 2048;
+		for (i = 1; i < n; i++) {
+			fsl_elbc_run_command(mtd);
+			io_to_buffer(mtd, i, 0);
+			io_to_buffer(mtd, i, 1);
+		}
+
 		return;
 
 	/* READOOB reads only the OOB because no ECC is performed. */
@@ -347,13 +408,38 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		         "fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:"
 			 " 0x%x, column: 0x%x.\n", page_addr, column);
 
-		out_be32(&lbc->fbcr, mtd->oobsize - column);
-		set_addr(mtd, column, page_addr, 1);
+		if (mtd->writesize <= 2048) {
+			out_be32(&lbc->fbcr, mtd->oobsize - column);
+			set_addr(mtd, column, page_addr, 1);
+		} else {
+			out_be32(&lbc->fbcr, 64);
+			set_addr(mtd, 0, page_addr, 1);
+			elbc_fcm_ctrl->index += column;
+		}
 
 		elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
 
-		fsl_elbc_do_read(chip, 1);
+		fsl_elbc_do_read(mtd, 1);
 		fsl_elbc_run_command(mtd);
+
+		if (mtd->writesize <= 2048)
+			return;
+
+		if (column < 64)
+			io_to_buffer(mtd, 0, 1);
+
+		out_be32(&lbc->fbcr, 2112);
+		out_be32(&lbc->fpar, in_be32(&lbc->fpar) & ~FPAR_LP_MS);
+		out_be32(&lbc->fir, (FIR_OP_NOP << FIR_OP0_SHIFT) |
+				    (FIR_OP_RB  << FIR_OP1_SHIFT));
+
+		n = mtd->writesize / 2048;
+		for (i = 1; i < n; i++) {
+			fsl_elbc_run_command(mtd);
+			if (column < (64 * (i + 1)))
+				io_to_buffer(mtd, i, 1);
+		}
+
 		return;
 
 	/* READID must read all 5 possible bytes while CEB is active */
@@ -429,7 +515,17 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		      (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
 		      (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
 
-		if (priv->page_size) {
+		if (mtd->writesize > 2048) {
+			/* writesize > 2048 */
+			out_be32(&lbc->fir,
+				 (FIR_OP_CM2 << FIR_OP0_SHIFT) |
+				 (FIR_OP_CA  << FIR_OP1_SHIFT) |
+				 (FIR_OP_PA  << FIR_OP2_SHIFT) |
+				 (FIR_OP_WB  << FIR_OP3_SHIFT));
+
+			if (elbc_fcm_ctrl->oob)
+				fcr |= NAND_CMD_RNDIN << FCR_CMD0_SHIFT;
+		} else if (mtd->writesize == 2048) {
 			out_be32(&lbc->fir,
 			         (FIR_OP_CM2 << FIR_OP0_SHIFT) |
 			         (FIR_OP_CA  << FIR_OP1_SHIFT) |
@@ -464,6 +560,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
 	/* PAGEPROG reuses all of the setup from SEQIN and adds the length */
 	case NAND_CMD_PAGEPROG: {
+		int pos;
 		dev_vdbg(priv->dev,
 		         "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG "
 			 "writing %d bytes.\n", elbc_fcm_ctrl->index);
@@ -473,13 +570,74 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		 * write so the HW generates the ECC.
 		 */
 		if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
-		    elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
-			out_be32(&lbc->fbcr,
-				elbc_fcm_ctrl->index - elbc_fcm_ctrl->column);
-		else
+		    elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) {
+			if (elbc_fcm_ctrl->oob && mtd->writesize > 2048) {
+				out_be32(&lbc->fbcr, 64);
+			} else {
+				out_be32(&lbc->fbcr, elbc_fcm_ctrl->index
+						- elbc_fcm_ctrl->column);
+			}
+		} else {
 			out_be32(&lbc->fbcr, 0);
+		}
+
+		if (mtd->writesize > 2048) {
+			if (!elbc_fcm_ctrl->oob)
+				buffer_to_io(mtd, 0, 0);
+			buffer_to_io(mtd, 0, 1);
+		}
 
 		fsl_elbc_run_command(mtd);
+
+		if (mtd->writesize <= 2048)
+			return;
+
+		n = mtd->writesize / 2048;
+
+		if (elbc_fcm_ctrl->oob) {
+			pos = 2048;
+			out_be32(&lbc->fir,
+				(FIR_OP_CM0 << FIR_OP0_SHIFT) |
+				(FIR_OP_UA  << FIR_OP1_SHIFT) |
+				(FIR_OP_UA  << FIR_OP2_SHIFT) |
+				(FIR_OP_WB  << FIR_OP3_SHIFT));
+
+			for (i = 1; i < n; i++) {
+				pos += 2112;
+				elbc_fcm_ctrl->mdr = pos;
+				elbc_fcm_ctrl->use_mdr = 1;
+				if (i == n - 1) {
+					out_be32(&lbc->fir,
+						(FIR_OP_NOP << FIR_OP0_SHIFT) |
+						(FIR_OP_CM0 << FIR_OP1_SHIFT) |
+						(FIR_OP_UA  << FIR_OP2_SHIFT) |
+						(FIR_OP_UA  << FIR_OP3_SHIFT) |
+						(FIR_OP_WB  << FIR_OP4_SHIFT) |
+						(FIR_OP_CM3 << FIR_OP5_SHIFT) |
+						(FIR_OP_CW1 << FIR_OP6_SHIFT) |
+						(FIR_OP_RS  << FIR_OP7_SHIFT));
+				}
+				buffer_to_io(mtd, i, 1);
+				fsl_elbc_run_command(mtd);
+			}
+		} else {
+			out_be32(&lbc->fir, FIR_OP_WB << FIR_OP1_SHIFT);
+			for (i = 1; i < n; i++) {
+				if (i == n - 1) {
+					elbc_fcm_ctrl->use_mdr = 1;
+					out_be32(&lbc->fir,
+						(FIR_OP_NOP << FIR_OP0_SHIFT) |
+						(FIR_OP_WB  << FIR_OP1_SHIFT) |
+						(FIR_OP_CM3 << FIR_OP2_SHIFT) |
+						(FIR_OP_CW1 << FIR_OP3_SHIFT) |
+						(FIR_OP_RS  << FIR_OP4_SHIFT));
+				}
+				buffer_to_io(mtd, i, 0);
+				buffer_to_io(mtd, i, 1);
+				fsl_elbc_run_command(mtd);
+			}
+		}
+
 		return;
 	}
 
@@ -500,6 +658,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);
 		return;
 
 	/* RESET without waiting for the ready line */
@@ -548,7 +707,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);
+	}
+
 	/*
 	 * This is workaround for the weird elbc hangs during nand write,
 	 * Scott Wood says: "...perhaps difference in how long it takes a
@@ -572,8 +738,13 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd)
 	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
 
 	/* If there are still bytes in the FCM, then use the next byte. */
-	if (elbc_fcm_ctrl->index < elbc_fcm_ctrl->read_bytes)
-		return in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index++]);
+	if (elbc_fcm_ctrl->index < elbc_fcm_ctrl->read_bytes) {
+		int index = elbc_fcm_ctrl->index++;
+		if (mtd->writesize > 2048)
+			return elbc_fcm_ctrl->buffer[index];
+		else
+			return in_8(&elbc_fcm_ctrl->addr[index]);
+	}
 
 	dev_err(priv->dev, "read_byte beyond end of buffer\n");
 	return ERR_BYTE;
@@ -594,7 +765,13 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 
 	avail = min((unsigned int)len,
 			elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index);
-	memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], avail);
+	if (mtd->writesize > 2048) {
+		memcpy(buf, &elbc_fcm_ctrl->buffer[elbc_fcm_ctrl->index],
+				avail);
+	} else {
+		memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index],
+				avail);
+	}
 	elbc_fcm_ctrl->index += avail;
 
 	if (len > avail)
@@ -630,10 +807,17 @@ static int fsl_elbc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 		return -EINVAL;
 	}
 
-	for (i = 0; i < len; i++)
-		if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
-				!= buf[i])
-			break;
+	if (mtd->writesize > 2048) {
+		for (i = 0; i < len; i++)
+			if (elbc_fcm_ctrl->buffer[elbc_fcm_ctrl->index + i]
+					!= buf[i])
+				break;
+	} else {
+		for (i = 0; i < len; i++)
+			if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
+					!= buf[i])
+				break;
+	}
 
 	elbc_fcm_ctrl->index += len;
 	return i == len && elbc_fcm_ctrl->status == LTESR_CC ? 0 : -EIO;
@@ -714,10 +898,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
 
 	/* adjust Option Register and ECC to match Flash page size */
 	if (mtd->writesize == 512) {
-		priv->page_size = 0;
 		clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS);
-	} else if (mtd->writesize == 2048) {
-		priv->page_size = 1;
+	} else if (mtd->writesize >= 2048 && mtd->writesize <= 8192) {
 		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 +1073,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 8K).
+		 */
+		elbc_fcm_ctrl->buffer = kmalloc(1024 * 8 + 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;
+		}
 
 		spin_lock_init(&elbc_fcm_ctrl->controller.lock);
 		init_waitqueue_head(&elbc_fcm_ctrl->controller.wq);
@@ -960,6 +1155,7 @@ static int fsl_elbc_nand_remove(struct platform_device *pdev)
 	elbc_fcm_ctrl->counter--;
 	if (!elbc_fcm_ctrl->counter) {
 		fsl_lbc_ctrl_dev->nand = NULL;
+		kfree(elbc_fcm_ctrl->buffer);
 		kfree(elbc_fcm_ctrl);
 	}
 	mutex_unlock(&fsl_elbc_nand_mutex);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly
  2011-12-09  9:42 [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly shuo.liu
  2011-12-09  9:42 ` [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip shuo.liu
@ 2011-12-09 19:23 ` Scott Wood
  2011-12-12 21:04 ` Artem Bityutskiy
  2 siblings, 0 replies; 5+ messages in thread
From: Scott Wood @ 2011-12-09 19:23 UTC (permalink / raw)
  To: shuo.liu
  Cc: Artem.Bityutskiy, linuxppc-dev, linux-kernel, linux-mtd, akpm,
	dwmw2

On 12/09/2011 03:42 AM, shuo.liu@freescale.com wrote:
> From: Liu Shuo <b35362@freescale.com>
> 
> If we use the Nand flash chip whose number of pages in a block is greater
> than 64(for large page), we must treat the low bit of FBAR as being the
> high bit of the page address due to the limitation of FCM, it simply uses
> the low 6-bits (for large page) of the combined block/page address as the
> FPAR component, rather than considering the actual block size.
> 
> Signed-off-by: Liu Shuo <b35362@freescale.com>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Tang Yuantian <b29983@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
>  drivers/mtd/nand/fsl_elbc_nand.c |   13 ++++++++++---
>  1 files changed, 10 insertions(+), 3 deletions(-)

Acked-by: Scott Wood <scottwood@freescale.com>

-Scott

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip
  2011-12-09  9:42 ` [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip shuo.liu
@ 2011-12-09 19:24   ` Scott Wood
  0 siblings, 0 replies; 5+ messages in thread
From: Scott Wood @ 2011-12-09 19:24 UTC (permalink / raw)
  To: shuo.liu
  Cc: Artem.Bityutskiy, linuxppc-dev, linux-kernel, linux-mtd, akpm,
	dwmw2

On 12/09/2011 03:42 AM, shuo.liu@freescale.com wrote:
> From: Liu Shuo <shuo.liu@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@freescale.com>
> Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> v4 : allocate (8+1)k buffer for large page chip.
> 
>  drivers/mtd/nand/fsl_elbc_nand.c |  246 ++++++++++++++++++++++++++++++++++----
>  1 files changed, 221 insertions(+), 25 deletions(-)

Again, I think we need to sort out the bad block migration first -- at
least how we're going to mark the chip as having been migrated, so the
driver can check for it.

-Scott

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly
  2011-12-09  9:42 [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly shuo.liu
  2011-12-09  9:42 ` [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip shuo.liu
  2011-12-09 19:23 ` [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly Scott Wood
@ 2011-12-12 21:04 ` Artem Bityutskiy
  2 siblings, 0 replies; 5+ messages in thread
From: Artem Bityutskiy @ 2011-12-12 21:04 UTC (permalink / raw)
  To: shuo.liu
  Cc: Artem.Bityutskiy, linuxppc-dev, linux-kernel, linux-mtd,
	scottwood, akpm, dwmw2

On Fri, 2011-12-09 at 17:42 +0800, shuo.liu@freescale.com wrote:
> From: Liu Shuo <b35362@freescale.com>
> 
> If we use the Nand flash chip whose number of pages in a block is greater
> than 64(for large page), we must treat the low bit of FBAR as being the
> high bit of the page address due to the limitation of FCM, it simply uses
> the low 6-bits (for large page) of the combined block/page address as the
> FPAR component, rather than considering the actual block size.

Pushed this one to l2-mtd-2.6.git, thanks!

Artem.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-12-12 21:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-09  9:42 [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly shuo.liu
2011-12-09  9:42 ` [PATCH 2/2 v4] mtd/nand : workaround for Freescale FCM to support large-page Nand chip shuo.liu
2011-12-09 19:24   ` Scott Wood
2011-12-09 19:23 ` [PATCH 1/2] mtd/nand : set Nand flash page address to FBAR and FPAR correctly Scott Wood
2011-12-12 21:04 ` Artem Bityutskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).