mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree
@ 2019-08-05 12:20 Sascha Hauer
  2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

This series makes the ecc strength used by the mxs-nand controller
configurable via device tree. This feature can be used to reuse NAND
images on devices with different OOB sizes.

Sascha Hauer (8):
  mtd: nand-mxs: consistently rename struct nand_chip * to "chip"
  mtd: nand-mxs: calculate ecc_strength only once
  mtd: nand-mxs: Make locally used variable static
  mtd: nand-mxs: change API between NAND driver and fcb code
  mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset()
  mtd: nand-mxs: inline only once used function
  mtd: nand: Add function to parse device tree properties
  mtd: nand-mxs: Make ecc strength configurable via device tree

 common/imx-bbu-nand-fcb.c    |  15 +-
 drivers/mtd/nand/nand_base.c |  27 ++++
 drivers/mtd/nand/nand_mxs.c  | 273 ++++++++++++++++++++---------------
 include/linux/mtd/nand.h     |   2 +
 include/linux/mtd/nand_mxs.h |   7 +-
 5 files changed, 196 insertions(+), 128 deletions(-)

-- 
2.20.1


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

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

* [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip"
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once Sascha Hauer
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

The struct nand_chip * is sometimes named "nand" and sometimes "chip".
For consistency name it "chip" throughout the driver.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index c3b07aa3f6..f753874956 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -396,8 +396,8 @@ static int mxs_nand_wait_for_bch_complete(struct mxs_nand_info *nand_info)
  */
 static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
 {
-	struct nand_chip *nand = mtd->priv;
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret;
@@ -496,12 +496,12 @@ static int mxs_nand_device_ready(struct mtd_info *mtd)
 /*
  * Select the NAND chip.
  */
-static void mxs_nand_select_chip(struct mtd_info *mtd, int chip)
+static void mxs_nand_select_chip(struct mtd_info *mtd, int chipnum)
 {
-	struct nand_chip *nand = mtd->priv;
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 
-	nand_info->cur_chip = chip;
+	nand_info->cur_chip = chipnum;
 }
 
 /*
@@ -555,8 +555,8 @@ static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
  */
 static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length)
 {
-	struct nand_chip *nand = mtd->priv;
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret;
@@ -633,8 +633,8 @@ rtn:
 static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
 				int length)
 {
-	struct nand_chip *nand = mtd->priv;
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret;
@@ -690,8 +690,8 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd)
 
 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;
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	int chunk_size;
 	void __iomem *bch_regs = nand_info->bch_base;
 
@@ -718,11 +718,11 @@ 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,
+static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 					uint8_t *buf, int oob_required, int page,
 					int readlen)
 {
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	uint32_t corrected = 0, failed = 0;
@@ -899,9 +899,9 @@ static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand
 	 * necessary, it has already been done, so we can rely on the first
 	 * byte of the auxiliary buffer to contain the block mark.
 	 */
-	memset(nand->oob_poi, 0xff, mtd->oobsize);
+	memset(chip->oob_poi, 0xff, mtd->oobsize);
 
-	nand->oob_poi[0] = nand_info->oob_buf[0];
+	chip->oob_poi[0] = nand_info->oob_buf[0];
 
 	ret = 0;
 rtn:
@@ -912,10 +912,10 @@ rtn:
 	return ret ? ret : max_bitflips;
 }
 
-static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 					uint8_t *buf, int oob_required, int page)
 {
-	return __mxs_nand_ecc_read_page(mtd, nand, buf, oob_required, page,
+	return __mxs_nand_ecc_read_page(mtd, chip, buf, oob_required, page,
 					mtd->writesize);
 }
 
@@ -939,16 +939,16 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
  * Write a page to NAND.
  */
 static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
-				struct nand_chip *nand, const uint8_t *buf,
+				struct nand_chip *chip, const uint8_t *buf,
 				int oob_required)
 {
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	struct mxs_dma_desc *d;
 	uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip;
 	int ret = 0;
 
 	memcpy(nand_info->data_buf, buf, mtd->writesize);
-	memcpy(nand_info->oob_buf, nand->oob_poi, mtd->oobsize);
+	memcpy(nand_info->oob_buf, chip->oob_poi, mtd->oobsize);
 
 	/* Handle block mark swapping. */
 	mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
@@ -1112,10 +1112,10 @@ static int mxs_nand_hook_block_markbad(struct mtd_info *mtd, loff_t ofs)
  * raw_oob_mode field so that, when control finally arrives here, we'll know
  * what to do.
  */
-static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
+static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 				int page)
 {
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	int column;
 
 	/*
@@ -1128,18 +1128,18 @@ static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
 		 * If control arrives here, we're doing a "raw" read. Send the
 		 * command to read the conventional OOB and read it.
 		 */
-		nand->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
-		nand->read_buf(mtd, nand->oob_poi, mtd->oobsize);
+		chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
+		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 	} else {
 		/*
 		 * If control arrives here, we're not doing a "raw" read. Fill
 		 * the OOB buffer with set bits and correct the block mark.
 		 */
-		memset(nand->oob_poi, 0xff, mtd->oobsize);
+		memset(chip->oob_poi, 0xff, mtd->oobsize);
 
 		column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize;
-		nand->cmdfunc(mtd, NAND_CMD_READ0, column, page);
-		mxs_nand_read_buf(mtd, nand->oob_poi, 1);
+		chip->cmdfunc(mtd, NAND_CMD_READ0, column, page);
+		mxs_nand_read_buf(mtd, chip->oob_poi, 1);
 	}
 
 	return 0;
@@ -1149,10 +1149,10 @@ static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
 /*
  * Write OOB data to NAND.
  */
-static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
+static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 					int page)
 {
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	int column;
 	uint8_t block_mark = 0;
 
@@ -1172,12 +1172,12 @@ static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
 
 	column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize;
 	/* Write the block mark. */
-	nand->cmdfunc(mtd, NAND_CMD_SEQIN, column, page);
-	nand->write_buf(mtd, &block_mark, 1);
-	nand->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, column, page);
+	chip->write_buf(mtd, &block_mark, 1);
+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
 	/* Check if it worked. */
-	if (nand->waitfunc(mtd, nand) & NAND_STATUS_FAIL)
+	if (chip->waitfunc(mtd, chip) & NAND_STATUS_FAIL)
 		return -EIO;
 
 	return 0;
@@ -1217,8 +1217,8 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
  */
 static int mxs_nand_scan_bbt(struct mtd_info *mtd)
 {
-	struct nand_chip *nand = mtd->priv;
-	struct mxs_nand_info *nand_info = nand->priv;
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
 	void __iomem *bch_regs = nand_info->bch_base;
 	int ret;
 
@@ -1346,13 +1346,13 @@ err1:
 
 static void mxs_nand_probe_dt(struct device_d *dev, struct mxs_nand_info *nand_info)
 {
-	struct nand_chip *nand = &nand_info->nand_chip;
+	struct nand_chip *chip = &nand_info->nand_chip;
 
 	if (!IS_ENABLED(CONFIG_OFTREE))
 		return;
 
 	if (of_get_nand_on_flash_bbt(dev->device_node))
-		nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+		chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
 }
 
 /**
@@ -1433,7 +1433,7 @@ static int mxs_nand_compute_hardware_timing(struct mxs_nand_info *info,
 					struct gpmi_nfc_hardware_timing *hw)
 {
 	struct timing_threshold *nfc = &timing_default_threshold;
-	struct nand_chip *nand = &info->nand_chip;
+	struct nand_chip *chip = &info->nand_chip;
 	struct nand_timing target = info->timing;
 	unsigned long clock_frequency_in_hz;
 	unsigned int clock_period_in_ns;
@@ -1454,11 +1454,11 @@ static int mxs_nand_compute_hardware_timing(struct mxs_nand_info *info,
 	 * If there are multiple chips, we need to relax the timings to allow
 	 * for signal distortion due to higher capacitance.
 	 */
-	if (nand->numchips > 2) {
+	if (chip->numchips > 2) {
 		target.data_setup_in_ns    += 10;
 		target.data_hold_in_ns     += 10;
 		target.address_setup_in_ns += 10;
-	} else if (nand->numchips > 1) {
+	} else if (chip->numchips > 1) {
 		target.data_setup_in_ns    += 5;
 		target.data_hold_in_ns     += 5;
 		target.address_setup_in_ns += 5;
@@ -2004,7 +2004,7 @@ static void mxs_nand_compute_edo_timing(struct mxs_nand_info *info,
 
 static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info)
 {
-	struct nand_chip *nand = &info->nand_chip;
+	struct nand_chip *chip = &info->nand_chip;
 	struct mtd_info	 *mtd = &info->mtd;
 	uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
 	int ret, mode;
@@ -2012,10 +2012,10 @@ static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info)
 	if (!mxs_nand_is_imx6(info))
 		return -ENODEV;
 
-	if (!nand->onfi_version)
+	if (!chip->onfi_version)
 		return -ENOENT;
 
-	mode = onfi_get_async_timing_mode(nand);
+	mode = onfi_get_async_timing_mode(chip);
 
 	/* We only support the timing mode 4 and mode 5. */
 	if (mode & ONFI_TIMING_MODE_5)
@@ -2025,27 +2025,27 @@ static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info)
 	else
 		return -EINVAL;
 
-	nand->select_chip(mtd, 0);
+	chip->select_chip(mtd, 0);
 
-	if (le16_to_cpu(nand->onfi_params.opt_cmd)
+	if (le16_to_cpu(chip->onfi_params.opt_cmd)
 	      & ONFI_OPT_CMD_SET_GET_FEATURES) {
 
 		/* [1] send SET FEATURE commond to NAND */
 		feature[0] = mode;
 
-		ret = nand->onfi_set_features(mtd, nand,
+		ret = chip->onfi_set_features(mtd, chip,
 				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
 		if (ret)
 			goto err_out;
 
 		/* [2] send GET FEATURE command to double-check the timing mode */
-		ret = nand->onfi_get_features(mtd, nand,
+		ret = chip->onfi_get_features(mtd, chip,
 				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
 		if (ret || feature[0] != mode)
 			goto err_out;
 	}
 
-	nand->select_chip(mtd, -1);
+	chip->select_chip(mtd, -1);
 
 	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
 	clk_disable(info->clk);
@@ -2057,7 +2057,7 @@ static int mxs_nand_enable_edo_mode(struct mxs_nand_info *info)
 	return mode;
 
 err_out:
-	nand->select_chip(mtd, -1);
+	chip->select_chip(mtd, -1);
 
 	return -EINVAL;
 }
@@ -2112,7 +2112,7 @@ static int mxs_nand_probe(struct device_d *dev)
 {
 	struct resource *iores;
 	struct mxs_nand_info *nand_info;
-	struct nand_chip *nand;
+	struct nand_chip *chip;
 	struct mtd_info *mtd;
 	enum gpmi_type type;
 	int err;
@@ -2168,35 +2168,35 @@ static int mxs_nand_probe(struct device_d *dev)
 	memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout));
 
 	/* structures must be linked */
-	nand = &nand_info->nand_chip;
+	chip = &nand_info->nand_chip;
 	mtd = &nand_info->mtd;
-	mtd->priv = nand;
+	mtd->priv = chip;
 	mtd->parent = dev;
 
-	nand->priv = nand_info;
+	chip->priv = nand_info;
 
-	nand->cmd_ctrl		= mxs_nand_cmd_ctrl;
+	chip->cmd_ctrl		= mxs_nand_cmd_ctrl;
 
-	nand->dev_ready		= mxs_nand_device_ready;
-	nand->select_chip	= mxs_nand_select_chip;
-	nand->block_bad		= mxs_nand_block_bad;
-	nand->scan_bbt		= mxs_nand_scan_bbt;
+	chip->dev_ready		= mxs_nand_device_ready;
+	chip->select_chip	= mxs_nand_select_chip;
+	chip->block_bad		= mxs_nand_block_bad;
+	chip->scan_bbt		= mxs_nand_scan_bbt;
 
-	nand->read_byte		= mxs_nand_read_byte;
+	chip->read_byte		= mxs_nand_read_byte;
 
-	nand->read_buf		= mxs_nand_read_buf;
-	nand->write_buf		= mxs_nand_write_buf;
+	chip->read_buf		= mxs_nand_read_buf;
+	chip->write_buf		= mxs_nand_write_buf;
 
-	nand->ecc.read_page	= mxs_nand_ecc_read_page;
-	nand->ecc.write_page	= mxs_nand_ecc_write_page;
-	nand->ecc.read_oob	= mxs_nand_ecc_read_oob;
-	nand->ecc.write_oob	= mxs_nand_ecc_write_oob;
+	chip->ecc.read_page	= mxs_nand_ecc_read_page;
+	chip->ecc.write_page	= mxs_nand_ecc_write_page;
+	chip->ecc.read_oob	= mxs_nand_ecc_read_oob;
+	chip->ecc.write_oob	= mxs_nand_ecc_write_oob;
 
-	nand->ecc.layout	= &fake_ecc_layout;
-	nand->ecc.mode		= NAND_ECC_HW;
-	nand->ecc.bytes		= 9;
-	nand->ecc.size		= 512;
-	nand->ecc.strength	= 8;
+	chip->ecc.layout	= &fake_ecc_layout;
+	chip->ecc.mode		= NAND_ECC_HW;
+	chip->ecc.bytes		= 9;
+	chip->ecc.size		= 512;
+	chip->ecc.strength	= 8;
 
 	/* first scan to find the device and get the page size */
 	err = nand_scan_ident(mtd, 4, NULL);
@@ -2204,11 +2204,11 @@ static int mxs_nand_probe(struct device_d *dev)
 		goto err2;
 
 	if ((13 * mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) % 8) == 0) {
-		nand->ecc.read_subpage = gpmi_ecc_read_subpage;
-		nand->options |= NAND_SUBPAGE_READ;
+		chip->ecc.read_subpage = gpmi_ecc_read_subpage;
+		chip->options |= NAND_SUBPAGE_READ;
 	}
 
-	nand->options |= NAND_NO_SUBPAGE_WRITE;
+	chip->options |= NAND_NO_SUBPAGE_WRITE;
 
 	mxs_nand_setup_timing(nand_info);
 
-- 
2.20.1


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

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

* [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
  2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 3/8] mtd: nand-mxs: Make locally used variable static Sascha Hauer
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

Instead of calculating the ecc strength multiple times with each page
read just do it once and store the result in chip->ecc.strength.

While at it also store the correct value in chip->ecc.bytes instead of
writing a bogus value into it.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index f753874956..fb3e2b7958 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -232,6 +232,8 @@ struct mxs_nand_info {
 #define GPMI_TIMING_INIT_OK	(1 << 1)
 	unsigned		flags;
 	struct nand_timing	timing;
+
+	int		bb_mark_bit_offset;
 };
 
 struct nand_ecclayout fake_ecc_layout;
@@ -362,6 +364,29 @@ uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
 	return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7;
 }
 
+static int mxs_nand_calc_geo(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct mxs_nand_info *nand_info = chip->priv;
+	int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(mtd->writesize);
+	int ecc_strength;
+	int gf_len = 13;  /* length of Galois Field for non-DDR nand */
+
+	ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8)
+		/ (gf_len * ecc_chunk_count);
+
+	/* We need the minor even number. */
+	chip->ecc.strength = rounddown(ecc_strength, 2);
+
+	chip->ecc.bytes = DIV_ROUND_UP(13 * chip->ecc.strength, 8);
+	chip->ecc.size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
+
+	nand_info->bb_mark_bit_offset = mxs_nand_get_mark_offset(mtd->writesize,
+								 chip->ecc.strength);
+
+	return 0;
+}
+
 /*
  * Wait for BCH complete IRQ and clear the IRQ
  */
@@ -527,8 +552,8 @@ static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
 	if (nand_info->version == GPMI_VERSION_TYPE_MX23)
 		return;
 
-	bit_offset = mxs_nand_mark_bit_offset(mtd);
-	buf_offset = mxs_nand_mark_byte_offset(mtd);
+	bit_offset = nand_info->bb_mark_bit_offset & 0x7;
+	buf_offset = nand_info->bb_mark_bit_offset >> 3;
 
 	/*
 	 * Get the byte from the data area that overlays the block mark. Since
@@ -703,13 +728,13 @@ static void mxs_nand_config_bch(struct mtd_info *mtd, int readlen)
 	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)
+		(chip->ecc.strength >> 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)
+		(chip->ecc.strength >> 1)
 			<< IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET |
 		chunk_size,
 		bch_regs + BCH_FLASH0LAYOUT1);
@@ -728,15 +753,13 @@ static int __mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip
 	uint32_t corrected = 0, failed = 0;
 	uint8_t	*status;
 	unsigned int  max_bitflips = 0;
-	int i, ret, readtotal, nchunks, eccstrength;
-
-	eccstrength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
+	int i, ret, readtotal, nchunks;
 
 	readlen = roundup(readlen, MXS_NAND_CHUNK_DATA_CHUNK_SIZE);
 	nchunks = mxs_nand_ecc_chunk_cnt(readlen);
 	readtotal =  MXS_NAND_METADATA_SIZE;
 	readtotal += MXS_NAND_CHUNK_DATA_CHUNK_SIZE * nchunks;
-	readtotal += DIV_ROUND_UP(13 * eccstrength * nchunks, 8);
+	readtotal += DIV_ROUND_UP(13 * chip->ecc.strength * nchunks, 8);
 
 	mxs_nand_config_bch(mtd, readtotal);
 
@@ -2194,16 +2217,17 @@ static int mxs_nand_probe(struct device_d *dev)
 
 	chip->ecc.layout	= &fake_ecc_layout;
 	chip->ecc.mode		= NAND_ECC_HW;
-	chip->ecc.bytes		= 9;
-	chip->ecc.size		= 512;
-	chip->ecc.strength	= 8;
 
 	/* first scan to find the device and get the page size */
 	err = nand_scan_ident(mtd, 4, NULL);
 	if (err)
 		goto err2;
 
-	if ((13 * mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) % 8) == 0) {
+	err = mxs_nand_calc_geo(mtd);
+	if (err)
+		goto err2;
+
+	if ((13 * chip->ecc.strength % 8) == 0) {
 		chip->ecc.read_subpage = gpmi_ecc_read_subpage;
 		chip->options |= NAND_SUBPAGE_READ;
 	}
-- 
2.20.1


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

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

* [PATCH 3/8] mtd: nand-mxs: Make locally used variable static
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
  2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer
  2019-08-05 12:20 ` [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code Sascha Hauer
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

fake_ecc_layout is only used in the mxs nand driver, so make it static.
Also it's not necessary to zero the structure.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index fb3e2b7958..4317c30805 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -236,7 +236,7 @@ struct mxs_nand_info {
 	int		bb_mark_bit_offset;
 };
 
-struct nand_ecclayout fake_ecc_layout;
+static struct nand_ecclayout fake_ecc_layout;
 
 static inline int mxs_nand_is_imx6(struct mxs_nand_info *info)
 {
@@ -2188,8 +2188,6 @@ static int mxs_nand_probe(struct device_d *dev)
 	if (err)
 		goto err2;
 
-	memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout));
-
 	/* structures must be linked */
 	chip = &nand_info->nand_chip;
 	mtd = &nand_info->mtd;
-- 
2.20.1


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

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

* [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
                   ` (2 preceding siblings ...)
  2019-08-05 12:20 ` [PATCH 3/8] mtd: nand-mxs: Make locally used variable static Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() Sascha Hauer
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

The imx-bbu-nand-fcb update handler code calls into the NAND driver
to get the ecc strength and bad block marker position. Change the
API so that only a single function is necessary and not three functions.
Also in future the ecc strength will be configurable via device tree.
This means static parameters like page size / oob size are no longer
enough to calculate the ecc strength and so we store a pointer to our
mtd_info struct in a static global variable.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/imx-bbu-nand-fcb.c    | 15 ++++++---
 drivers/mtd/nand/nand_mxs.c  | 62 +++++++++++++++++++-----------------
 include/linux/mtd/nand_mxs.h |  7 +---
 3 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c
index 6d773b59df..e28ce6b9ea 100644
--- a/common/imx-bbu-nand-fcb.c
+++ b/common/imx-bbu-nand-fcb.c
@@ -486,15 +486,22 @@ err:
 static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
 		struct fcb_block *fcb, struct mtd_info *mtd)
 {
+	int ecc_strength;
+	int bb_mark_bit_offset;
+	int ret;
+
 	fcb->FingerPrint = 0x20424346;
 	fcb->Version = 0x01000000;
 	fcb->PageDataSize = mtd->writesize;
 	fcb->TotalPageSize = mtd->writesize + mtd->oobsize;
 	fcb->SectorsPerBlock = mtd->erasesize / mtd->writesize;
 
+	ret = mxs_nand_get_geo(&ecc_strength, &bb_mark_bit_offset);
+	if (ret)
+		return ret;
+
 	/* Divide ECC strength by two and save the value into FCB structure. */
-	fcb->EccBlock0EccType =
-		mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1;
+	fcb->EccBlock0EccType = ecc_strength >> 1;
 	fcb->EccBlockNEccType = fcb->EccBlock0EccType;
 
 	fcb->EccBlock0Size = 0x00000200;
@@ -505,8 +512,8 @@ static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
 	/* DBBT search area starts at second page on first block */
 	fcb->DBBTSearchAreaStartAddress = 1;
 
-	fcb->BadBlockMarkerByte = mxs_nand_mark_byte_offset(mtd);
-	fcb->BadBlockMarkerStartBit = mxs_nand_mark_bit_offset(mtd);
+	fcb->BadBlockMarkerByte = bb_mark_bit_offset >> 3;
+	fcb->BadBlockMarkerStartBit = bb_mark_bit_offset & 0x7;
 
 	fcb->BBMarkerPhysicalOffset = mtd->writesize;
 
diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 4317c30805..92d78db6c9 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -287,20 +287,6 @@ static uint32_t mxs_nand_aux_status_offset(void)
 	return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
 }
 
-uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
-						uint32_t page_oob_size)
-{
-	int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(page_data_size);
-	int ecc_strength = 0;
-	int gf_len = 13;  /* length of Galois Field for non-DDR nand */
-
-	ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8)
-		/ (gf_len * ecc_chunk_count);
-
-	/* We need the minor even number. */
-	return rounddown(ecc_strength, 2);
-}
-
 static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
 						uint32_t ecc_strength)
 {
@@ -350,20 +336,6 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
 	return block_mark_bit_offset;
 }
 
-uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
-{
-	uint32_t ecc_strength;
-	ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
-	return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3;
-}
-
-uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
-{
-	uint32_t ecc_strength;
-	ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
-	return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7;
-}
-
 static int mxs_nand_calc_geo(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd->priv;
@@ -387,6 +359,25 @@ static int mxs_nand_calc_geo(struct mtd_info *mtd)
 	return 0;
 }
 
+static struct mtd_info *mxs_nand_mtd;
+
+int mxs_nand_get_geo(int *ecc_strength, int *bb_mark_bit_offset)
+{
+	struct nand_chip *chip;
+	struct mxs_nand_info *nand_info;
+
+	if (!mxs_nand_mtd)
+		return -ENODEV;
+
+	chip = mxs_nand_mtd->priv;
+	nand_info = chip->priv;
+
+	*ecc_strength = chip->ecc.strength;
+	*bb_mark_bit_offset = nand_info->bb_mark_bit_offset;
+
+	return 0;
+}
+
 /*
  * Wait for BCH complete IRQ and clear the IRQ
  */
@@ -2140,6 +2131,10 @@ static int mxs_nand_probe(struct device_d *dev)
 	enum gpmi_type type;
 	int err;
 
+	/* We expect only one */
+	if (mxs_nand_mtd)
+		return -EBUSY;
+
 	err = dev_get_drvdata(dev, (const void **)&type);
 	if (err)
 		type = GPMI_MXS;
@@ -2239,12 +2234,21 @@ static int mxs_nand_probe(struct device_d *dev)
 	if (err)
 		goto err2;
 
-	return add_mtd_nand_device(mtd, "nand");
+	err = add_mtd_nand_device(mtd, "nand");
+	if (err)
+		goto err2;
+
+	mxs_nand_mtd = mtd;
+
+	return 0;
 err2:
 	free(nand_info->data_buf);
 	free(nand_info->cmd_buf);
 err1:
 	free(nand_info);
+
+	mxs_nand_mtd = NULL;
+
 	return err;
 }
 
diff --git a/include/linux/mtd/nand_mxs.h b/include/linux/mtd/nand_mxs.h
index eca31777f5..7eda0b8e63 100644
--- a/include/linux/mtd/nand_mxs.h
+++ b/include/linux/mtd/nand_mxs.h
@@ -27,11 +27,6 @@
  * update handler code, the generic calculation from the driver code is used.
  */
 
-uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
-						uint32_t page_oob_size);
-
-uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd);
-
-uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd);
+int mxs_nand_get_geo(int *ecc_strength, int *bb_mark_bit_offset);
 
 #endif /* __NAND_MXS_H */
-- 
2.20.1


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

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

* [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset()
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
                   ` (3 preceding siblings ...)
  2019-08-05 12:20 ` [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 6/8] mtd: nand-mxs: inline only once used function Sascha Hauer
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

struct mtd_info * contains everything mxs_nand_get_mark_offset() needs,
so pass this pointer rather than several integer arguments.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 92d78db6c9..2b2e80d4c5 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -287,9 +287,9 @@ static uint32_t mxs_nand_aux_status_offset(void)
 	return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
 }
 
-static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
-						uint32_t ecc_strength)
+static uint32_t mxs_nand_get_mark_offset(struct mtd_info *mtd)
 {
+	struct nand_chip *chip = mtd->priv;
 	uint32_t chunk_data_size_in_bits;
 	uint32_t chunk_ecc_size_in_bits;
 	uint32_t chunk_total_size_in_bits;
@@ -298,13 +298,13 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
 	uint32_t block_mark_bit_offset;
 
 	chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
-	chunk_ecc_size_in_bits  = mxs_nand_ecc_size_in_bits(ecc_strength);
+	chunk_ecc_size_in_bits  = mxs_nand_ecc_size_in_bits(chip->ecc.strength);
 
 	chunk_total_size_in_bits =
 			chunk_data_size_in_bits + chunk_ecc_size_in_bits;
 
 	/* Compute the bit offset of the block mark within the physical page. */
-	block_mark_bit_offset = page_data_size * 8;
+	block_mark_bit_offset = mtd->writesize * 8;
 
 	/* Subtract the metadata bits. */
 	block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;
@@ -353,8 +353,7 @@ static int mxs_nand_calc_geo(struct mtd_info *mtd)
 	chip->ecc.bytes = DIV_ROUND_UP(13 * chip->ecc.strength, 8);
 	chip->ecc.size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
 
-	nand_info->bb_mark_bit_offset = mxs_nand_get_mark_offset(mtd->writesize,
-								 chip->ecc.strength);
+	nand_info->bb_mark_bit_offset = mxs_nand_get_mark_offset(mtd);
 
 	return 0;
 }
-- 
2.20.1


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

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

* [PATCH 6/8] mtd: nand-mxs: inline only once used function
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
                   ` (4 preceding siblings ...)
  2019-08-05 12:20 ` [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 7/8] mtd: nand: Add function to parse device tree properties Sascha Hauer
  2019-08-05 12:20 ` [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

mxs_nand_ecc_size_in_bits() is used only once and is simple enough to
be inlined.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 2b2e80d4c5..7555b1013d 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -277,11 +277,6 @@ static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size)
 	return page_data_size / MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
 }
 
-static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
-{
-	return ecc_strength * 13;
-}
-
 static uint32_t mxs_nand_aux_status_offset(void)
 {
 	return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
@@ -298,7 +293,7 @@ static uint32_t mxs_nand_get_mark_offset(struct mtd_info *mtd)
 	uint32_t block_mark_bit_offset;
 
 	chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
-	chunk_ecc_size_in_bits  = mxs_nand_ecc_size_in_bits(chip->ecc.strength);
+	chunk_ecc_size_in_bits  = chip->ecc.strength * 13;
 
 	chunk_total_size_in_bits =
 			chunk_data_size_in_bits + chunk_ecc_size_in_bits;
-- 
2.20.1


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

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

* [PATCH 7/8] mtd: nand: Add function to parse device tree properties
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
                   ` (5 preceding siblings ...)
  2019-08-05 12:20 ` [PATCH 6/8] mtd: nand-mxs: inline only once used function Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  2019-08-05 12:20 ` [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

This adds nand_of_parse_node() which can be used to parse generic
NAND device properties. Not very complete yet, but it's a start.

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

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index bf15e6ccee..e103eac596 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -43,6 +43,7 @@
 #include <io.h>
 #include <malloc.h>
 #include <module.h>
+#include <of_mtd.h>
 
 /* Define default oob placement schemes for large and small page devices */
 static struct nand_ecclayout nand_oob_8 = {
@@ -3506,6 +3507,32 @@ ident_done:
 	return type;
 }
 
+/**
+ * nand_of_parse_node - parse generic NAND properties
+ * @mtd: MTD device structure
+ * @np: Device node to read information from
+ *
+ * This parses device tree properties generic to NAND controllers and fills in
+ * the various fields in struct nand_chip.
+ */
+void nand_of_parse_node(struct mtd_info *mtd, struct device_node *np)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ecc_strength, ecc_size;
+
+	if (!IS_ENABLED(CONFIG_OFDEVICE))
+		return;
+
+	ecc_strength = of_get_nand_ecc_strength(np);
+	ecc_size = of_get_nand_ecc_step_size(np);
+
+	if (ecc_strength >= 0)
+		chip->ecc.strength = ecc_strength;
+
+	if (ecc_size >= 0)
+		chip->ecc.size = ecc_size;
+}
+
 /**
  * nand_scan_ident - [NAND Interface] Scan for the NAND device
  * @mtd: MTD device structure
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 785cb06030..7f17767c69 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -52,6 +52,8 @@ extern int nand_check_erased_ecc_chunk(void *data, int datalen,
 				       int bitflips_threshold);
 int nand_check_erased_buf(void *buf, int len, int bitflips_threshold);
 
+void nand_of_parse_node(struct mtd_info *mtd, struct device_node *np);
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS		8
 
-- 
2.20.1


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

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

* [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree
  2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
                   ` (6 preceding siblings ...)
  2019-08-05 12:20 ` [PATCH 7/8] mtd: nand: Add function to parse device tree properties Sascha Hauer
@ 2019-08-05 12:20 ` Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2019-08-05 12:20 UTC (permalink / raw)
  To: Barebox List

According to the binding doc the mxs NAND driver supports the
"nand-ecc-strength" and "nand-ecc-step-size" options. This adds support
for these options to the driver. The "nand-ecc-step-size" is not
really configurable, the only accepted value is 512 so this is merely
to sanity check that there's nothing specified that we can't yet
support.

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

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 7555b1013d..b016c5bff0 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -336,14 +336,31 @@ static int mxs_nand_calc_geo(struct mtd_info *mtd)
 	struct nand_chip *chip = mtd->priv;
 	struct mxs_nand_info *nand_info = chip->priv;
 	int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(mtd->writesize);
-	int ecc_strength;
 	int gf_len = 13;  /* length of Galois Field for non-DDR nand */
+	int max_ecc_strength;
 
-	ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8)
-		/ (gf_len * ecc_chunk_count);
+	nand_of_parse_node(mtd, mtd->parent->device_node);
 
+	max_ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8)
+			   / (gf_len * ecc_chunk_count);
 	/* We need the minor even number. */
-	chip->ecc.strength = rounddown(ecc_strength, 2);
+	max_ecc_strength = rounddown(max_ecc_strength, 2);
+
+	if (chip->ecc.strength) {
+		if (chip->ecc.strength > max_ecc_strength) {
+			dev_err(nand_info->dev, "invalid ecc strength %d (maximum %d)\n",
+				chip->ecc.strength, max_ecc_strength);
+			return -EINVAL;
+		}
+	} else {
+		chip->ecc.strength = max_ecc_strength;
+	}
+
+	if (chip->ecc.size && chip->ecc.size != MXS_NAND_CHUNK_DATA_CHUNK_SIZE) {
+		dev_err(nand_info->dev, "invalid ecc size %d, this driver only supports %d\n",
+			chip->ecc.size, MXS_NAND_CHUNK_DATA_CHUNK_SIZE);
+		return -EINVAL;
+	}
 
 	chip->ecc.bytes = DIV_ROUND_UP(13 * chip->ecc.strength, 8);
 	chip->ecc.size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
-- 
2.20.1


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

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

end of thread, other threads:[~2019-08-05 12:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-05 12:20 [PATCH 0/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer
2019-08-05 12:20 ` [PATCH 1/8] mtd: nand-mxs: consistently rename struct nand_chip * to "chip" Sascha Hauer
2019-08-05 12:20 ` [PATCH 2/8] mtd: nand-mxs: calculate ecc_strength only once Sascha Hauer
2019-08-05 12:20 ` [PATCH 3/8] mtd: nand-mxs: Make locally used variable static Sascha Hauer
2019-08-05 12:20 ` [PATCH 4/8] mtd: nand-mxs: change API between NAND driver and fcb code Sascha Hauer
2019-08-05 12:20 ` [PATCH 5/8] mtd: nand-mxs: pass mtd_info to mxs_nand_get_mark_offset() Sascha Hauer
2019-08-05 12:20 ` [PATCH 6/8] mtd: nand-mxs: inline only once used function Sascha Hauer
2019-08-05 12:20 ` [PATCH 7/8] mtd: nand: Add function to parse device tree properties Sascha Hauer
2019-08-05 12:20 ` [PATCH 8/8] mtd: nand-mxs: Make ecc strength configurable via device tree Sascha Hauer

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