All of lore.kernel.org
 help / color / mirror / Atom feed
* mtd: nand: mxc: Fix failed/corrected values
@ 2017-12-15  8:55 Sascha Hauer
  2017-12-15  8:55 ` [PATCH 1/3] " Sascha Hauer
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Sascha Hauer @ 2017-12-15  8:55 UTC (permalink / raw)
  To: linux-mtd; +Cc: Boris Brezillon, Richard Weinberger, Brian Norris, kernel

The mxc_nand controller returns bogus corrected/failed values. Fix
this by adding a own read_page function. The other two patches
are cleanups based on the first one. The patches are targeted for
the v2/v3 controller types, we could do the same for v1 controllers
aswell, but I left that out because I don't have any hardware handy
at the moment.

Sascha

----------------------------------------------------------------
Sascha Hauer (3):
      mtd: nand: mxc: Fix failed/corrected values
      mtd: nand: mxc: Add own write_page
      mtd: nand: mxc: Drop now unnecessary correct_data function

 drivers/mtd/nand/mxc_nand.c | 51 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 14 deletions(-)

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

* [PATCH 1/3] mtd: nand: mxc: Fix failed/corrected values
  2017-12-15  8:55 mtd: nand: mxc: Fix failed/corrected values Sascha Hauer
@ 2017-12-15  8:55 ` Sascha Hauer
  2017-12-18 16:52   ` Boris Brezillon
  2017-12-15  8:55 ` [PATCH 2/3] mtd: nand: mxc: Add own write_page Sascha Hauer
  2017-12-15  8:55 ` [PATCH 3/3] mtd: nand: mxc: Drop now unnecessary correct_data function Sascha Hauer
  2 siblings, 1 reply; 9+ messages in thread
From: Sascha Hauer @ 2017-12-15  8:55 UTC (permalink / raw)
  To: linux-mtd
  Cc: Boris Brezillon, Richard Weinberger, Brian Norris, kernel, Sascha Hauer

Currently nand_read_page_hwecc() from nand_base calls
mxc_nand_correct_data_v2_v3() for each subpage, but in this function we
return the corrected/failed results for the whole page instead
of a single subpage. On a 2k page size Nand this leads to results which
are 4 times too high.
The whole ecc.calculate/ecc.correct mechanism used by
nand_read_page_hwecc() is not suitable for devices which correct the
data in hardware, so fix this by using a driver specific read_page
function which does the right thing.

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

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index f3be0b2a8869..65d5cde4692b 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -140,6 +140,8 @@ struct mxc_nand_host;
 
 struct mxc_nand_devtype_data {
 	void (*preset)(struct mtd_info *);
+	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
+			uint8_t *buf, int oob_required, int page);
 	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_page)(struct mtd_info *, unsigned int);
@@ -617,13 +619,23 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
 static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 				 u_char *read_ecc, u_char *calc_ecc)
 {
-	struct nand_chip *nand_chip = mtd_to_nand(mtd);
-	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
+	return 0;
+}
+
+static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
+					  struct nand_chip *chip,
+					  uint8_t *buf, int oob_required,
+					  int page)
+{
+	struct mxc_nand_host *host = nand_get_controller_data(chip);
+	unsigned int max_bitflips = 0;
 	u32 ecc_stat, err;
-	int no_subpages = 1;
-	int ret = 0;
+	int no_subpages;
 	u8 ecc_bit_mask, err_limit;
 
+	chip->read_buf(mtd, buf, mtd->writesize);
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
 	ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
 	err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
 
@@ -634,17 +646,16 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
 	do {
 		err = ecc_stat & ecc_bit_mask;
 		if (err > err_limit) {
-			dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n");
-			return -EBADMSG;
+			mtd->ecc_stats.failed++;
 		} else {
-			ret += err;
+			mtd->ecc_stats.corrected += err;
+			max_bitflips = max_t(unsigned int, max_bitflips, err);
 		}
+
 		ecc_stat >>= 4;
 	} while (--no_subpages);
 
-	dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret);
-
-	return ret;
+	return max_bitflips;
 }
 
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
@@ -1444,6 +1455,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 /* v21: i.MX25, i.MX35 */
 static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.preset = preset_v2,
+	.read_page = mxc_nand_read_page_hwecc_v2_v3,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v2,
@@ -1469,6 +1481,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 /* v3.2a: i.MX51 */
 static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_hwecc_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1494,6 +1507,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 /* v3.2b: i.MX53 */
 static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.preset = preset_v3,
+	.read_page = mxc_nand_read_page_hwecc_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1751,6 +1765,7 @@ static int mxcnd_probe(struct platform_device *pdev)
 
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
+		this->ecc.read_page = host->devtype_data->read_page;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0

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

* [PATCH 2/3] mtd: nand: mxc: Add own write_page
  2017-12-15  8:55 mtd: nand: mxc: Fix failed/corrected values Sascha Hauer
  2017-12-15  8:55 ` [PATCH 1/3] " Sascha Hauer
@ 2017-12-15  8:55 ` Sascha Hauer
  2017-12-18 16:59   ` Boris Brezillon
  2017-12-18 17:03   ` Boris Brezillon
  2017-12-15  8:55 ` [PATCH 3/3] mtd: nand: mxc: Drop now unnecessary correct_data function Sascha Hauer
  2 siblings, 2 replies; 9+ messages in thread
From: Sascha Hauer @ 2017-12-15  8:55 UTC (permalink / raw)
  To: linux-mtd
  Cc: Boris Brezillon, Richard Weinberger, Brian Norris, kernel, Sascha Hauer

Now that we have our own read_page function add a write_page function
for consistency aswell. This can be a lot easier than the generic
function since we do not have to iterate over subpages but can write
the whole page at once.

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

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 65d5cde4692b..a54804f14bb1 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -142,6 +142,8 @@ struct mxc_nand_devtype_data {
 	void (*preset)(struct mtd_info *);
 	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
+	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+			  const uint8_t *buf, int oob_required, int page);
 	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
 	void (*send_page)(struct mtd_info *, unsigned int);
@@ -658,6 +660,17 @@ static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
 	return max_bitflips;
 }
 
+static int mxc_nand_write_page_hwecc_v2_v3(struct mtd_info *mtd,
+					   struct nand_chip *chip,
+					   const uint8_t *buf, int oob_required,
+					   int page)
+{
+	chip->write_buf(mtd, buf, mtd->writesize);
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
+}
+
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 				  u_char *ecc_code)
 {
@@ -1456,6 +1469,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
 static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.preset = preset_v2,
 	.read_page = mxc_nand_read_page_hwecc_v2_v3,
+	.write_page = mxc_nand_write_page_hwecc_v2_v3,
 	.send_cmd = send_cmd_v1_v2,
 	.send_addr = send_addr_v1_v2,
 	.send_page = send_page_v2,
@@ -1482,6 +1496,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.preset = preset_v3,
 	.read_page = mxc_nand_read_page_hwecc_v2_v3,
+	.write_page = mxc_nand_write_page_hwecc_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1508,6 +1523,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.preset = preset_v3,
 	.read_page = mxc_nand_read_page_hwecc_v2_v3,
+	.write_page = mxc_nand_write_page_hwecc_v2_v3,
 	.send_cmd = send_cmd_v3,
 	.send_addr = send_addr_v3,
 	.send_page = send_page_v3,
@@ -1766,6 +1782,7 @@ static int mxcnd_probe(struct platform_device *pdev)
 	switch (this->ecc.mode) {
 	case NAND_ECC_HW:
 		this->ecc.read_page = host->devtype_data->read_page;
+		this->ecc.write_page = host->devtype_data->write_page;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = host->devtype_data->correct_data;
-- 
2.11.0

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

* [PATCH 3/3] mtd: nand: mxc: Drop now unnecessary correct_data function
  2017-12-15  8:55 mtd: nand: mxc: Fix failed/corrected values Sascha Hauer
  2017-12-15  8:55 ` [PATCH 1/3] " Sascha Hauer
  2017-12-15  8:55 ` [PATCH 2/3] mtd: nand: mxc: Add own write_page Sascha Hauer
@ 2017-12-15  8:55 ` Sascha Hauer
  2 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2017-12-15  8:55 UTC (permalink / raw)
  To: linux-mtd
  Cc: Boris Brezillon, Richard Weinberger, Brian Norris, kernel, Sascha Hauer

correct_data is no longer used for v2_v3 controllers, so remove
it.

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

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index a54804f14bb1..41838ee79bb5 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -618,12 +618,6 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
 	return 0;
 }
 
-static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
-				 u_char *read_ecc, u_char *calc_ecc)
-{
-	return 0;
-}
-
 static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
 					  struct nand_chip *chip,
 					  uint8_t *buf, int oob_required,
@@ -1480,7 +1474,6 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v2,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v2,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.setup_data_interface = mxc_nand_v2_setup_data_interface,
 	.irqpending_quirk = 0,
 	.needs_ip = 0,
@@ -1507,7 +1500,6 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
@@ -1534,7 +1526,6 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
 	.get_ecc_status = get_ecc_status_v3,
 	.ooblayout = &mxc_v2_ooblayout_ops,
 	.select_chip = mxc_nand_select_chip_v1_v3,
-	.correct_data = mxc_nand_correct_data_v2_v3,
 	.irqpending_quirk = 0,
 	.needs_ip = 1,
 	.regs_offset = 0,
-- 
2.11.0

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

* Re: [PATCH 1/3] mtd: nand: mxc: Fix failed/corrected values
  2017-12-15  8:55 ` [PATCH 1/3] " Sascha Hauer
@ 2017-12-18 16:52   ` Boris Brezillon
  0 siblings, 0 replies; 9+ messages in thread
From: Boris Brezillon @ 2017-12-18 16:52 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linux-mtd, Richard Weinberger, Brian Norris, kernel

On Fri, 15 Dec 2017 09:55:02 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> Currently nand_read_page_hwecc() from nand_base calls
> mxc_nand_correct_data_v2_v3() for each subpage, but in this function we
> return the corrected/failed results for the whole page instead
> of a single subpage. On a 2k page size Nand this leads to results which
> are 4 times too high.
> The whole ecc.calculate/ecc.correct mechanism used by
> nand_read_page_hwecc() is not suitable for devices which correct the
> data in hardware, so fix this by using a driver specific read_page
> function which does the right thing.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 35 +++++++++++++++++++++++++----------
>  1 file changed, 25 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index f3be0b2a8869..65d5cde4692b 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -140,6 +140,8 @@ struct mxc_nand_host;
>  
>  struct mxc_nand_devtype_data {
>  	void (*preset)(struct mtd_info *);
> +	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
> +			uint8_t *buf, int oob_required, int page);
>  	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_page)(struct mtd_info *, unsigned int);
> @@ -617,13 +619,23 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
>  static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
>  				 u_char *read_ecc, u_char *calc_ecc)
>  {
> -	struct nand_chip *nand_chip = mtd_to_nand(mtd);
> -	struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
> +	return 0;
> +}
> +
> +static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
> +					  struct nand_chip *chip,
> +					  uint8_t *buf, int oob_required,
> +					  int page)
> +{
> +	struct mxc_nand_host *host = nand_get_controller_data(chip);
> +	unsigned int max_bitflips = 0;
>  	u32 ecc_stat, err;
> -	int no_subpages = 1;
> -	int ret = 0;
> +	int no_subpages;
>  	u8 ecc_bit_mask, err_limit;

Sorry but you'll have to rebase this work on nand/next.
->read_page() hooks are now expected to send the READ0 command on
their own.

>  
> +	chip->read_buf(mtd, buf, mtd->writesize);
> +	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
> +
>  	ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
>  	err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
>  
> @@ -634,17 +646,16 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
>  	do {
>  		err = ecc_stat & ecc_bit_mask;
>  		if (err > err_limit) {
> -			dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n");
> -			return -EBADMSG;
> +			mtd->ecc_stats.failed++;
>  		} else {
> -			ret += err;
> +			mtd->ecc_stats.corrected += err;
> +			max_bitflips = max_t(unsigned int, max_bitflips, err);
>  		}
> +
>  		ecc_stat >>= 4;
>  	} while (--no_subpages);
>  
> -	dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret);
> -
> -	return ret;
> +	return max_bitflips;
>  }
>  
>  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
> @@ -1444,6 +1455,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
>  /* v21: i.MX25, i.MX35 */
>  static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
>  	.preset = preset_v2,
> +	.read_page = mxc_nand_read_page_hwecc_v2_v3,
>  	.send_cmd = send_cmd_v1_v2,
>  	.send_addr = send_addr_v1_v2,
>  	.send_page = send_page_v2,
> @@ -1469,6 +1481,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
>  /* v3.2a: i.MX51 */
>  static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
>  	.preset = preset_v3,
> +	.read_page = mxc_nand_read_page_hwecc_v2_v3,
>  	.send_cmd = send_cmd_v3,
>  	.send_addr = send_addr_v3,
>  	.send_page = send_page_v3,
> @@ -1494,6 +1507,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
>  /* v3.2b: i.MX53 */
>  static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
>  	.preset = preset_v3,
> +	.read_page = mxc_nand_read_page_hwecc_v2_v3,
>  	.send_cmd = send_cmd_v3,
>  	.send_addr = send_addr_v3,
>  	.send_page = send_page_v3,
> @@ -1751,6 +1765,7 @@ static int mxcnd_probe(struct platform_device *pdev)
>  
>  	switch (this->ecc.mode) {
>  	case NAND_ECC_HW:
> +		this->ecc.read_page = host->devtype_data->read_page;
>  		this->ecc.calculate = mxc_nand_calculate_ecc;
>  		this->ecc.hwctl = mxc_nand_enable_hwecc;
>  		this->ecc.correct = host->devtype_data->correct_data;

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

* Re: [PATCH 2/3] mtd: nand: mxc: Add own write_page
  2017-12-15  8:55 ` [PATCH 2/3] mtd: nand: mxc: Add own write_page Sascha Hauer
@ 2017-12-18 16:59   ` Boris Brezillon
  2017-12-18 17:03   ` Boris Brezillon
  1 sibling, 0 replies; 9+ messages in thread
From: Boris Brezillon @ 2017-12-18 16:59 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linux-mtd, Richard Weinberger, Brian Norris, kernel

On Fri, 15 Dec 2017 09:55:03 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> Now that we have our own read_page function add a write_page function
> for consistency aswell. This can be a lot easier than the generic
> function since we do not have to iterate over subpages but can write
> the whole page at once.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 65d5cde4692b..a54804f14bb1 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -142,6 +142,8 @@ struct mxc_nand_devtype_data {
>  	void (*preset)(struct mtd_info *);
>  	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
>  			uint8_t *buf, int oob_required, int page);
> +	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
> +			  const uint8_t *buf, int oob_required, int page);
>  	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_page)(struct mtd_info *, unsigned int);
> @@ -658,6 +660,17 @@ static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
>  	return max_bitflips;
>  }
>  
> +static int mxc_nand_write_page_hwecc_v2_v3(struct mtd_info *mtd,
> +					   struct nand_chip *chip,
> +					   const uint8_t *buf, int oob_required,
> +					   int page)
> +{

Same as for the ->read_page() hooks, this needs to be rebased on top of
nand/next.

Note that I've seen other drivers implementing the exact same sequence
(one example is fsl_elbc_write_subpage() [1] but AFAIR there are
others), so maybe it's worth creating a nand_write_page_raw_force_oob()
helper.

> +	chip->write_buf(mtd, buf, mtd->writesize);
> +	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> +
> +	return 0;
> +}
> +

[1]http://elixir.free-electrons.com/linux/v4.15-rc3/source/drivers/mtd/nand/fsl_elbc_nand.c#L741

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

* Re: [PATCH 2/3] mtd: nand: mxc: Add own write_page
  2017-12-15  8:55 ` [PATCH 2/3] mtd: nand: mxc: Add own write_page Sascha Hauer
  2017-12-18 16:59   ` Boris Brezillon
@ 2017-12-18 17:03   ` Boris Brezillon
  2017-12-18 20:49     ` Sascha Hauer
  1 sibling, 1 reply; 9+ messages in thread
From: Boris Brezillon @ 2017-12-18 17:03 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linux-mtd, Richard Weinberger, Brian Norris, kernel

On Fri, 15 Dec 2017 09:55:03 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> Now that we have our own read_page function add a write_page function
> for consistency aswell. This can be a lot easier than the generic
> function since we do not have to iterate over subpages but can write
> the whole page at once.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/mtd/nand/mxc_nand.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index 65d5cde4692b..a54804f14bb1 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -142,6 +142,8 @@ struct mxc_nand_devtype_data {
>  	void (*preset)(struct mtd_info *);
>  	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
>  			uint8_t *buf, int oob_required, int page);
> +	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
> +			  const uint8_t *buf, int oob_required, int page);
>  	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
>  	void (*send_page)(struct mtd_info *, unsigned int);
> @@ -658,6 +660,17 @@ static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
>  	return max_bitflips;
>  }
>  
> +static int mxc_nand_write_page_hwecc_v2_v3(struct mtd_info *mtd,
> +					   struct nand_chip *chip,
> +					   const uint8_t *buf, int oob_required,
> +					   int page)
> +{
> +	chip->write_buf(mtd, buf, mtd->writesize);
> +	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> +
> +	return 0;
> +}
> +
>  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
>  				  u_char *ecc_code)
>  {
> @@ -1456,6 +1469,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
>  static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
>  	.preset = preset_v2,
>  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
>  	.send_cmd = send_cmd_v1_v2,
>  	.send_addr = send_addr_v1_v2,
>  	.send_page = send_page_v2,
> @@ -1482,6 +1496,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
>  static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
>  	.preset = preset_v3,
>  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
>  	.send_cmd = send_cmd_v3,
>  	.send_addr = send_addr_v3,
>  	.send_page = send_page_v3,
> @@ -1508,6 +1523,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
>  static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
>  	.preset = preset_v3,
>  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
>  	.send_cmd = send_cmd_v3,
>  	.send_addr = send_addr_v3,
>  	.send_page = send_page_v3,
> @@ -1766,6 +1782,7 @@ static int mxcnd_probe(struct platform_device *pdev)
>  	switch (this->ecc.mode) {
>  	case NAND_ECC_HW:
>  		this->ecc.read_page = host->devtype_data->read_page;
> +		this->ecc.write_page = host->devtype_data->write_page;
>  		this->ecc.calculate = mxc_nand_calculate_ecc;

I'm pretty sure you don't need this dummy calculate method now that you
provide your own ->write/read_page() implementations.

>  		this->ecc.hwctl = mxc_nand_enable_hwecc;
>  		this->ecc.correct = host->devtype_data->correct_data;

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

* Re: [PATCH 2/3] mtd: nand: mxc: Add own write_page
  2017-12-18 17:03   ` Boris Brezillon
@ 2017-12-18 20:49     ` Sascha Hauer
  2017-12-18 21:00       ` Boris Brezillon
  0 siblings, 1 reply; 9+ messages in thread
From: Sascha Hauer @ 2017-12-18 20:49 UTC (permalink / raw)
  To: Boris Brezillon; +Cc: linux-mtd, Richard Weinberger, Brian Norris, kernel

On Mon, Dec 18, 2017 at 06:03:08PM +0100, Boris Brezillon wrote:
> On Fri, 15 Dec 2017 09:55:03 +0100
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Now that we have our own read_page function add a write_page function
> > for consistency aswell. This can be a lot easier than the generic
> > function since we do not have to iterate over subpages but can write
> > the whole page at once.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> >  drivers/mtd/nand/mxc_nand.c | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> > 
> > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > index 65d5cde4692b..a54804f14bb1 100644
> > --- a/drivers/mtd/nand/mxc_nand.c
> > +++ b/drivers/mtd/nand/mxc_nand.c
> > @@ -142,6 +142,8 @@ struct mxc_nand_devtype_data {
> >  	void (*preset)(struct mtd_info *);
> >  	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
> >  			uint8_t *buf, int oob_required, int page);
> > +	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
> > +			  const uint8_t *buf, int oob_required, int page);
> >  	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
> >  	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
> >  	void (*send_page)(struct mtd_info *, unsigned int);
> > @@ -658,6 +660,17 @@ static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
> >  	return max_bitflips;
> >  }
> >  
> > +static int mxc_nand_write_page_hwecc_v2_v3(struct mtd_info *mtd,
> > +					   struct nand_chip *chip,
> > +					   const uint8_t *buf, int oob_required,
> > +					   int page)
> > +{
> > +	chip->write_buf(mtd, buf, mtd->writesize);
> > +	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> > +
> > +	return 0;
> > +}
> > +
> >  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
> >  				  u_char *ecc_code)
> >  {
> > @@ -1456,6 +1469,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
> >  static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
> >  	.preset = preset_v2,
> >  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> > +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
> >  	.send_cmd = send_cmd_v1_v2,
> >  	.send_addr = send_addr_v1_v2,
> >  	.send_page = send_page_v2,
> > @@ -1482,6 +1496,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
> >  static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
> >  	.preset = preset_v3,
> >  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> > +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
> >  	.send_cmd = send_cmd_v3,
> >  	.send_addr = send_addr_v3,
> >  	.send_page = send_page_v3,
> > @@ -1508,6 +1523,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
> >  static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
> >  	.preset = preset_v3,
> >  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> > +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
> >  	.send_cmd = send_cmd_v3,
> >  	.send_addr = send_addr_v3,
> >  	.send_page = send_page_v3,
> > @@ -1766,6 +1782,7 @@ static int mxcnd_probe(struct platform_device *pdev)
> >  	switch (this->ecc.mode) {
> >  	case NAND_ECC_HW:
> >  		this->ecc.read_page = host->devtype_data->read_page;
> > +		this->ecc.write_page = host->devtype_data->write_page;
> >  		this->ecc.calculate = mxc_nand_calculate_ecc;
> 
> I'm pretty sure you don't need this dummy calculate method now that you
> provide your own ->write/read_page() implementations.

True for the v2/v3 type controllers, but not for v1 which I haven't
changed in this series.

Will update the series next year.

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

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

* Re: [PATCH 2/3] mtd: nand: mxc: Add own write_page
  2017-12-18 20:49     ` Sascha Hauer
@ 2017-12-18 21:00       ` Boris Brezillon
  0 siblings, 0 replies; 9+ messages in thread
From: Boris Brezillon @ 2017-12-18 21:00 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linux-mtd, Richard Weinberger, Brian Norris, kernel

On Mon, 18 Dec 2017 21:49:35 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Mon, Dec 18, 2017 at 06:03:08PM +0100, Boris Brezillon wrote:
> > On Fri, 15 Dec 2017 09:55:03 +0100
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> >   
> > > Now that we have our own read_page function add a write_page function
> > > for consistency aswell. This can be a lot easier than the generic
> > > function since we do not have to iterate over subpages but can write
> > > the whole page at once.
> > > 
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > ---
> > >  drivers/mtd/nand/mxc_nand.c | 17 +++++++++++++++++
> > >  1 file changed, 17 insertions(+)
> > > 
> > > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > > index 65d5cde4692b..a54804f14bb1 100644
> > > --- a/drivers/mtd/nand/mxc_nand.c
> > > +++ b/drivers/mtd/nand/mxc_nand.c
> > > @@ -142,6 +142,8 @@ struct mxc_nand_devtype_data {
> > >  	void (*preset)(struct mtd_info *);
> > >  	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
> > >  			uint8_t *buf, int oob_required, int page);
> > > +	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
> > > +			  const uint8_t *buf, int oob_required, int page);
> > >  	void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
> > >  	void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
> > >  	void (*send_page)(struct mtd_info *, unsigned int);
> > > @@ -658,6 +660,17 @@ static int mxc_nand_read_page_hwecc_v2_v3(struct mtd_info *mtd,
> > >  	return max_bitflips;
> > >  }
> > >  
> > > +static int mxc_nand_write_page_hwecc_v2_v3(struct mtd_info *mtd,
> > > +					   struct nand_chip *chip,
> > > +					   const uint8_t *buf, int oob_required,
> > > +					   int page)
> > > +{
> > > +	chip->write_buf(mtd, buf, mtd->writesize);
> > > +	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
> > >  				  u_char *ecc_code)
> > >  {
> > > @@ -1456,6 +1469,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = {
> > >  static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
> > >  	.preset = preset_v2,
> > >  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> > > +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
> > >  	.send_cmd = send_cmd_v1_v2,
> > >  	.send_addr = send_addr_v1_v2,
> > >  	.send_page = send_page_v2,
> > > @@ -1482,6 +1496,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
> > >  static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
> > >  	.preset = preset_v3,
> > >  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> > > +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
> > >  	.send_cmd = send_cmd_v3,
> > >  	.send_addr = send_addr_v3,
> > >  	.send_page = send_page_v3,
> > > @@ -1508,6 +1523,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
> > >  static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
> > >  	.preset = preset_v3,
> > >  	.read_page = mxc_nand_read_page_hwecc_v2_v3,
> > > +	.write_page = mxc_nand_write_page_hwecc_v2_v3,
> > >  	.send_cmd = send_cmd_v3,
> > >  	.send_addr = send_addr_v3,
> > >  	.send_page = send_page_v3,
> > > @@ -1766,6 +1782,7 @@ static int mxcnd_probe(struct platform_device *pdev)
> > >  	switch (this->ecc.mode) {
> > >  	case NAND_ECC_HW:
> > >  		this->ecc.read_page = host->devtype_data->read_page;
> > > +		this->ecc.write_page = host->devtype_data->write_page;
> > >  		this->ecc.calculate = mxc_nand_calculate_ecc;  
> > 
> > I'm pretty sure you don't need this dummy calculate method now that you
> > provide your own ->write/read_page() implementations.  
> 
> True for the v2/v3 type controllers, but not for v1 which I haven't
> changed in this series.

Indeed, forgot that v1 support was not updated.

> 
> Will update the series next year.

Thanks.

> 
> Thanks
>   Sascha
> 

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

end of thread, other threads:[~2017-12-18 21:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-15  8:55 mtd: nand: mxc: Fix failed/corrected values Sascha Hauer
2017-12-15  8:55 ` [PATCH 1/3] " Sascha Hauer
2017-12-18 16:52   ` Boris Brezillon
2017-12-15  8:55 ` [PATCH 2/3] mtd: nand: mxc: Add own write_page Sascha Hauer
2017-12-18 16:59   ` Boris Brezillon
2017-12-18 17:03   ` Boris Brezillon
2017-12-18 20:49     ` Sascha Hauer
2017-12-18 21:00       ` Boris Brezillon
2017-12-15  8:55 ` [PATCH 3/3] mtd: nand: mxc: Drop now unnecessary correct_data function Sascha Hauer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.