mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/4] mtd: nand: nand_mxs: Factor out BCH setup function
@ 2016-05-10  6:24 Sascha Hauer
  2016-05-10  6:24 ` [PATCH 2/4] mtd: nand: Pass page argument to read_subpage hook Sascha Hauer
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Sascha Hauer @ 2016-05-10  6:24 UTC (permalink / raw)
  To: Barebox List

The BCH setup has to be changed during runtime with the following
patches, so factor out a function for it.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 20bda14..be7f88f 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -635,6 +635,33 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd)
 	return buf;
 }
 
+static void mxs_nand_config_bch(struct mtd_info *mtd, int readlen)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct mxs_nand_info *nand_info = nand->priv;
+	int chunk_size;
+	void __iomem *bch_regs = nand_info->bch_base;
+
+	if (mxs_nand_is_imx6(nand_info))
+		chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE >> 2;
+	else
+		chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
+
+	writel((mxs_nand_ecc_chunk_cnt(readlen) - 1)
+			<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET |
+		MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET |
+		(mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
+			<< IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET |
+		chunk_size,
+		bch_regs + BCH_FLASH0LAYOUT0);
+
+	writel(readlen	<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET |
+		(mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
+			<< IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET |
+		chunk_size,
+		bch_regs + BCH_FLASH0LAYOUT1);
+}
+
 /*
  * Read a page from NAND.
  */
@@ -1104,7 +1131,6 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
 	struct nand_chip *nand = mtd->priv;
 	struct mxs_nand_info *nand_info = nand->priv;
 	void __iomem *bch_regs = nand_info->bch_base;
-	uint32_t layout0, layout1;
 	int ret;
 
 	/* Reset BCH. Don't use SFTRST on MX23 due to Errata #2847 */
@@ -1113,36 +1139,7 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
 	if (ret)
 		return ret;
 
-	if (mxs_nand_is_imx6(nand_info)) {
-		layout0 = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1)
-					<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET |
-			MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET |
-			(mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
-					<< IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET |
-			MXS_NAND_CHUNK_DATA_CHUNK_SIZE >> 2;
-
-		layout1 = (mtd->writesize + mtd->oobsize)
-					<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET |
-			(mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
-					<< IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET |
-			MXS_NAND_CHUNK_DATA_CHUNK_SIZE >> 2;
-	} else {
-		layout0 = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1)
-					<< BCH_FLASHLAYOUT0_NBLOCKS_OFFSET |
-			MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET |
-			(mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
-					<< BCH_FLASHLAYOUT0_ECC0_OFFSET |
-			MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
-
-		layout1 = (mtd->writesize + mtd->oobsize)
-					<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET |
-			(mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
-					<< BCH_FLASHLAYOUT1_ECCN_OFFSET |
-			MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
-	}
-
-	writel(layout0, bch_regs + BCH_FLASH0LAYOUT0);
-	writel(layout1, bch_regs + BCH_FLASH0LAYOUT1);
+	mxs_nand_config_bch(mtd, mtd->writesize + mtd->oobsize);
 
 	/* Set *all* chip selects to use layout 0 */
 	writel(0, bch_regs + BCH_LAYOUTSELECT);
-- 
2.8.0.rc3


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

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

* [PATCH 2/4] mtd: nand: Pass page argument to read_subpage hook
  2016-05-10  6:24 [PATCH 1/4] mtd: nand: nand_mxs: Factor out BCH setup function Sascha Hauer
@ 2016-05-10  6:24 ` Sascha Hauer
  2016-05-10  6:24 ` [PATCH 3/4] mtd: nand: Enable subpage reads Sascha Hauer
  2016-05-10  6:24 ` [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support Sascha Hauer
  2 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2016-05-10  6:24 UTC (permalink / raw)
  To: Barebox List

Similar to what the kernel does in e004debda (mtd: nand: add "page" argument for
read_subpage hook).

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_base.c | 4 ++--
 include/linux/mtd/nand.h     | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 79c1edd..670720a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1185,7 +1185,7 @@ static __maybe_unused int nand_read_page_swecc(struct mtd_info *mtd,
  */
 static __maybe_unused int nand_read_subpage(struct mtd_info *mtd,
 		struct nand_chip *chip, uint32_t data_offs, uint32_t readlen,
-		uint8_t *bufpoi)
+		uint8_t *bufpoi, int page)
 {
 	int start_step, end_step, num_steps;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -1540,7 +1540,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 			else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
 				 !oob)
 				ret = chip->ecc.read_subpage(mtd, chip,
-							col, bytes, bufpoi);
+							col, bytes, bufpoi, page);
 			else
 				ret = chip->ecc.read_page(mtd, chip, bufpoi,
 							  oob_required, page);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 5beec39..dfb94d7 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -352,7 +352,7 @@ struct nand_ecc_ctrl {
 	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
 	int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
-			uint32_t offs, uint32_t len, uint8_t *buf);
+			uint32_t offs, uint32_t len, uint8_t *buf, int page);
 	int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offset, uint32_t data_len,
 			const uint8_t *data_buf, int oob_required);
-- 
2.8.0.rc3


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

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

* [PATCH 3/4] mtd: nand: Enable subpage reads
  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 ` Sascha Hauer
  2016-05-10  6:24 ` [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support Sascha Hauer
  2 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2016-05-10  6:24 UTC (permalink / raw)
  To: Barebox List

Until now we did not support subpage reads for smaller binary sizes.
Scanning UBI volumes on large page NANDs can be painfully slow,
subpage reads can speed this up significantly, so enable subpage reads.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/mtd/nand.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index dfb94d7..76a6425 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -169,7 +169,7 @@ typedef enum {
 
 /* Device supports subpage reads */
 /* Disabled in barebox for smaller binary sizes */
-#define NAND_SUBPAGE_READ	(__BAREBOX__ ? 0x0 : 0x00001000)
+#define NAND_SUBPAGE_READ	(0x00001000)
 
 /* Options valid for Samsung large page devices */
 #define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
-- 
2.8.0.rc3


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

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

* [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support
  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
  2016-05-18  6:52   ` Stefan Christ
  2 siblings, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2016-05-10  6:24 UTC (permalink / raw)
  To: Barebox List

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

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

* Re: [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support
  2016-05-10  6:24 ` [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support Sascha Hauer
@ 2016-05-18  6:52   ` Stefan Christ
  2016-05-19  7:00     ` Sascha Hauer
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Christ @ 2016-05-18  6:52 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi Sascha,

On Tue, May 10, 2016 at 08:24:43AM +0200, Sascha Hauer wrote:
> 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>

Here is my 

    Tested-by: Stefan Christ <s.christ@phytec.de>

I measured the ubiattach time for two different NAND chips after an ubiformat
on the devices. It's around 30% faster. Here are the results:

    nand: NAND device: Manufacturer ID: 0x01, Chip ID: 0xd3
    (AMD/Spansion S34ML08G2), 1024MiB, page size: 2048, OOB size: 128

    # without patches
    barebox@Phytec phyFLEX-i.MX6 Quad Carrier-Board:/ time ubiattach  /dev/nand0.root
    UBI: scanning is finished
    UBI: registering /dev/nand0.root.ubi
    UBI: attached mtd0 (name "nand0.root", size 1010 MiB) to ubi0
    time: 9208ms

    # with patches
    barebox@Phytec phyFLEX-i.MX6 Quad Carrier-Board:/ time ubiattach  /dev/nand0.root
    time: 6524ms

    # Saved time 2684ms (-29%)
    

    nand: NAND device: Manufacturer ID: 0x2c, Chip ID: 0xdc
    (Micron MT29F4G08ABADAWP), 512MiB, page size: 2048, OOB size: 64

    # without patches 
    barebox@Phytec phyCORE-i.MX6 Duallite/SOLO with NAND:/ time ubiattach /dev/nand0.root
    time: 4158ms

    # with patches
    barebox@Phytec phyCORE-i.MX6 Duallite/SOLO with NAND:/ time ubiattach /dev/nand0.root
    time: 2842ms

    # Saved time 1316ms (-31%)

Mit freundlichen Grüßen / Kind regards,
	Stefan Christ

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

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

* Re: [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support
  2016-05-18  6:52   ` Stefan Christ
@ 2016-05-19  7:00     ` Sascha Hauer
  0 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2016-05-19  7:00 UTC (permalink / raw)
  To: Stefan Christ; +Cc: Barebox List

On Wed, May 18, 2016 at 08:52:16AM +0200, Stefan Christ wrote:
> Hi Sascha,
> 
> On Tue, May 10, 2016 at 08:24:43AM +0200, Sascha Hauer wrote:
> > 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>
> 
> Here is my 
> 
>     Tested-by: Stefan Christ <s.christ@phytec.de>
> 
> I measured the ubiattach time for two different NAND chips after an ubiformat
> on the devices. It's around 30% faster. Here are the results:

Thanks for testing this.

The results become even better with bigger pages. I have a board with 8k
page Nand here. The scanning time reduced from 31s to 3.5s.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

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

end of thread, other threads:[~2016-05-19  7:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 4/4] mtd: nand: nand_mxs: Add subpage read support Sascha Hauer
2016-05-18  6:52   ` Stefan Christ
2016-05-19  7:00     ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox