2022-10-07 11:16:30

by mikhail.kshevetskiy

[permalink] [raw]
Subject: [PATCH 1/2] mtd: spinand: winbond: fix winbond lashes identifications

From: Mikhail Kshevetskiy <[email protected]>

Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1,
but current driver uses only first 2 bytes of it for devices
idenfification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22)
is identified as W25N01GV (id_bytes: EF, AA, 21).

Fix this by adding missed identification bytes.

Signed-off-by: Mikhail Kshevetskiy <[email protected]>
---
drivers/mtd/nand/spi/winbond.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 76684428354e..ed368a55d68f 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand,

static const struct spinand_info winbond_spinand_table[] = {
SPINAND_INFO("W25M02GV",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab),
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
@@ -86,7 +86,7 @@ static const struct spinand_info winbond_spinand_table[] = {
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
SPINAND_INFO("W25N01GV",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa),
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
--
2.35.1


2022-10-07 11:22:27

by mikhail.kshevetskiy

[permalink] [raw]
Subject: [PATCH 2/2] mtd: spinand: winbond: add Winbond W25N02KV flash support

From: Mikhail Kshevetskiy <[email protected]>

Signed-off-by: Mikhail Kshevetskiy <[email protected]>
---
drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)

diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index ed368a55d68f..3ad58cd284d8 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
return spi_mem_exec_op(spinand->spimem, &op);
}

+static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ region->offset = 64 + (16 * section);
+ region->length = 13;
+
+ return 0;
+}
+
+static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ region->offset = (16 * section) + 2;
+ region->length = 14;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
+ .ecc = w25n02kv_ooblayout_ecc,
+ .free = w25n02kv_ooblayout_free,
+};
+
+static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ struct nand_device *nand = spinand_to_nand(spinand);
+ u8 mbf = 0;
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
+
+ switch (status & STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ case STATUS_ECC_HAS_BITFLIPS:
+ /*
+ * Let's try to retrieve the real maximum number of bitflips
+ * in order to avoid forcing the wear-leveling layer to move
+ * data around if it's not necessary.
+ */
+ if (spi_mem_exec_op(spinand->spimem, &op))
+ return nanddev_get_ecc_conf(nand)->strength;
+
+ mbf >>= 4;
+
+ if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
+ return nanddev_get_ecc_conf(nand)->strength;
+
+ return mbf;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
static const struct spinand_info winbond_spinand_table[] = {
SPINAND_INFO("W25M02GV",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
@@ -94,6 +160,15 @@ static const struct spinand_info winbond_spinand_table[] = {
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+ SPINAND_INFO("W25N02KV",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
};

static int winbond_spinand_init(struct spinand_device *spinand)
--
2.35.1

2022-10-10 07:44:44

by Frieder Schrempf

[permalink] [raw]
Subject: Re: [PATCH 1/2] mtd: spinand: winbond: fix winbond lashes identifications

On 07.10.22 12:48, [email protected] wrote:
> From: Mikhail Kshevetskiy <[email protected]>
>
> Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1,
> but current driver uses only first 2 bytes of it for devices
> idenfification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22)

^ identification

> is identified as W25N01GV (id_bytes: EF, AA, 21).
>
> Fix this by adding missed identification bytes.
>
> Signed-off-by: Mikhail Kshevetskiy <[email protected]>

Two things:

* each time you send a new version of your patches, you should increase
the version number in the prefix (e. g. using "git format-patch -v 2").

* I'm not a native English speaker and I don't get what "fix winbond
lashes identifications" is supposed to mean. Maybe something simple like
"fix identification" or "add missing id bytes" would do?

2022-10-10 08:19:37

by Frieder Schrempf

[permalink] [raw]
Subject: Re: [PATCH 2/2] mtd: spinand: winbond: add Winbond W25N02KV flash support

On 07.10.22 12:48, [email protected] wrote:
> From: Mikhail Kshevetskiy <[email protected]>

Even if the subject line already describes the change, you should
probably add a short sentence here so the body of the commit message
isn't empty.

> Signed-off-by: Mikhail Kshevetskiy <[email protected]>
> ---
> drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++
> 1 file changed, 75 insertions(+)
>
> diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
> index ed368a55d68f..3ad58cd284d8 100644
> --- a/drivers/mtd/nand/spi/winbond.c
> +++ b/drivers/mtd/nand/spi/winbond.c
> @@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
> return spi_mem_exec_op(spinand->spimem, &op);
> }
>
> +static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + if (section > 3)
> + return -ERANGE;
> +
> + region->offset = 64 + (16 * section);
> + region->length = 13;
> +
> + return 0;
> +}
> +
> +static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + if (section > 3)
> + return -ERANGE;
> +
> + region->offset = (16 * section) + 2;
> + region->length = 14;
> +
> + return 0;
> +}
> +
> +static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
> + .ecc = w25n02kv_ooblayout_ecc,
> + .free = w25n02kv_ooblayout_free,
> +};
> +
> +static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
> + u8 status)
> +{
> + struct nand_device *nand = spinand_to_nand(spinand);
> + u8 mbf = 0;
> + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
> +
> + switch (status & STATUS_ECC_MASK) {
> + case STATUS_ECC_NO_BITFLIPS:
> + return 0;
> +
> + case STATUS_ECC_UNCOR_ERROR:
> + return -EBADMSG;
> +
> + case STATUS_ECC_HAS_BITFLIPS:
> + /*
> + * Let's try to retrieve the real maximum number of bitflips
> + * in order to avoid forcing the wear-leveling layer to move
> + * data around if it's not necessary.
> + */
> + if (spi_mem_exec_op(spinand->spimem, &op))
> + return nanddev_get_ecc_conf(nand)->strength;
> +
> + mbf >>= 4;
> +
> + if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
> + return nanddev_get_ecc_conf(nand)->strength;
> +
> + return mbf;
> +
> + default:
> + break;
> + }
> +
> + return -EINVAL;
> +}
> +
> static const struct spinand_info winbond_spinand_table[] = {
> SPINAND_INFO("W25M02GV",
> SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
> @@ -94,6 +160,15 @@ static const struct spinand_info winbond_spinand_table[] = {
> &update_cache_variants),
> 0,
> SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
> + SPINAND_INFO("W25N02KV",
> + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
> + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
> + NAND_ECCREQ(8, 512),
> + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
> + &write_cache_variants,
> + &update_cache_variants),
> + 0,
> + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
> };
>
> static int winbond_spinand_init(struct spinand_device *spinand)