mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support
Date: Tue, 10 May 2016 08:24:43 +0200	[thread overview]
Message-ID: <1462861483-19983-4-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1462861483-19983-1-git-send-email-s.hauer@pengutronix.de>

subpage read support can significantly speed up scanning UBI volumes, so
add support for it. This is inspired by the corresponding Kernel commit.
Unlike in the kernel we add subpage read support for i.MX28 aswell.
Testing it on i.MX28 revealed no problems.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_mxs.c | 55 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index be7f88f..a9c6e96 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -665,8 +665,9 @@ static void mxs_nand_config_bch(struct mtd_info *mtd, int readlen)
 /*
  * Read a page from NAND.
  */
-static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
-					uint8_t *buf, int oob_required, int page)
+static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
+					uint8_t *buf, int oob_required, int page,
+					int readlen)
 {
 	struct mxs_nand_info *nand_info = nand->priv;
 	struct mxs_dma_desc *d;
@@ -674,7 +675,17 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 	uint32_t corrected = 0, failed = 0;
 	uint8_t	*status;
 	unsigned int  max_bitflips = 0;
-	int i, ret;
+	int i, ret, readtotal, nchunks, eccstrength, ecc_parity_size;
+
+	eccstrength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
+
+	readlen = roundup(readlen, MXS_NAND_CHUNK_DATA_CHUNK_SIZE);
+	nchunks = mxs_nand_ecc_chunk_cnt(readlen);
+	ecc_parity_size = 13 * eccstrength / 8;
+	readtotal = MXS_NAND_METADATA_SIZE +
+		(MXS_NAND_CHUNK_DATA_CHUNK_SIZE + ecc_parity_size) * nchunks;
+
+	mxs_nand_config_bch(mtd, readtotal);
 
 	/* Compile the DMA descriptor - wait for ready. */
 	d = mxs_nand_get_dma_desc(nand_info);
@@ -706,13 +717,13 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 		GPMI_CTRL0_WORD_LENGTH |
 		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
-		(mtd->writesize + mtd->oobsize);
+		readtotal;
 	d->cmd.pio_words[1] = 0;
 	d->cmd.pio_words[2] =
 		GPMI_ECCCTRL_ENABLE_ECC |
 		GPMI_ECCCTRL_ECC_CMD_DECODE |
 		GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
-	d->cmd.pio_words[3] = mtd->writesize + mtd->oobsize;
+	d->cmd.pio_words[3] = readtotal;
 	d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
 	d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
@@ -732,7 +743,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 		GPMI_CTRL0_WORD_LENGTH |
 		(nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
 		GPMI_CTRL0_ADDRESS_NAND_DATA |
-		(mtd->writesize + mtd->oobsize);
+		readtotal;
 	d->cmd.pio_words[1] = 0;
 	d->cmd.pio_words[2] = 0;
 
@@ -764,11 +775,11 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 	/* Read DMA completed, now do the mark swapping. */
 	mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
 
-	memcpy(buf, nand_info->data_buf, mtd->writesize);
+	memcpy(buf, nand_info->data_buf, readlen);
 
 	/* Loop over status bytes, accumulating ECC status. */
 	status = nand_info->oob_buf + mxs_nand_aux_status_offset();
-	for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd->writesize); i++) {
+	for (i = 0; i < nchunks; i++) {
 		if (status[i] == 0x00)
 			continue;
 
@@ -843,9 +854,34 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 rtn:
 	mxs_nand_return_dma_descs(nand_info);
 
+	mxs_nand_config_bch(mtd, mtd->writesize + mtd->oobsize);
+
 	return ret ? ret : max_bitflips;
 }
 
+static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
+					uint8_t *buf, int oob_required, int page)
+{
+	return __mxs_nand_ecc_read_page(mtd, nand, buf, oob_required, page,
+					mtd->writesize);
+}
+
+static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+			uint32_t offs, uint32_t len, uint8_t *buf, int page)
+{
+	/*
+	 * For now always read from the beginning of a page. Allowing
+	 * offsets here makes __mxs_nand_ecc_read_page() more
+	 * complicated.
+	 */
+	if (offs) {
+		len += offs;
+		offs = 0;
+	}
+
+	return __mxs_nand_ecc_read_page(mtd, chip, buf, 0, page, len);
+}
+
 /*
  * Write a page to NAND.
  */
@@ -1356,6 +1392,9 @@ static int mxs_nand_probe(struct device_d *dev)
 	nand->ecc.size		= 512;
 	nand->ecc.strength	= 8;
 
+	nand->ecc.read_subpage = gpmi_ecc_read_subpage;
+	nand->options |= NAND_SUBPAGE_READ;
+
 	/* first scan to find the device and get the page size */
 	err = nand_scan_ident(mtd, 4, NULL);
 	if (err)
-- 
2.8.0.rc3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2016-05-10  6:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-10  6:24 [PATCH 1/4] mtd: nand: nand_mxs: Factor out BCH setup function Sascha Hauer
2016-05-10  6:24 ` [PATCH 2/4] mtd: nand: Pass page argument to read_subpage hook Sascha Hauer
2016-05-10  6:24 ` [PATCH 3/4] mtd: nand: Enable subpage reads Sascha Hauer
2016-05-10  6:24 ` Sascha Hauer [this message]
2016-05-18  6:52   ` [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support Stefan Christ
2016-05-19  7:00     ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1462861483-19983-4-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox