* 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox