diff mbox series

mtd: spi-nor: sfdp: Get the 1-1-8 protocol from BFPT

Message ID 20231207075121.21788-1-jaimeliao.tw@gmail.com
State Changes Requested
Headers show
Series mtd: spi-nor: sfdp: Get the 1-1-8 protocol from BFPT | expand

Commit Message

liao jaime Dec. 7, 2023, 7:51 a.m. UTC
From: JaimeLiao <jaimeliao@mxic.com.tw>

BFPT 17th DWORD contains the informations about 1-1-8,
The difference from Dual and Quad mode is not determined
by a single bit indicating support but rather by using
1-byte instruction, which content is the opcode.
A value of 0x00 represents not support.
Therefore, parse BFPT 17 DWORD instruction to determine
whether flash support 1-1-8, and set its dummy cycle
accordingly.

Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw>
---
 drivers/mtd/spi-nor/sfdp.c | 15 ++++++++++++++-
 drivers/mtd/spi-nor/sfdp.h |  3 +++
 2 files changed, 17 insertions(+), 1 deletion(-)

Comments

Michael Walle Dec. 11, 2023, 10:49 a.m. UTC | #1
Hi,

> BFPT 17th DWORD contains the informations about 1-1-8,

Ok.

> The difference from Dual and Quad mode is not determined
> by a single bit indicating support but rather by using
> 1-byte instruction, which content is the opcode.

I don't get what you try to express here.

> A value of 0x00 represents not support.
> Therefore, parse BFPT 17 DWORD instruction to determine
> whether flash support 1-1-8, and set its dummy cycle
> accordingly.
> 
> Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw>
> ---
>  drivers/mtd/spi-nor/sfdp.c | 15 ++++++++++++++-
>  drivers/mtd/spi-nor/sfdp.h |  3 +++
>  2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> index b3b11dfed789..d04dbddb70d6 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -446,6 +446,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
>  	u32 dword;
>  	u16 half;
>  	u8 erase_mask;
> +	u8 dummy, opcode;
> 
>  	/* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs. 
> */
>  	if (bfpt_header->length < BFPT_DWORD_MAX_JESD216)
> @@ -516,6 +517,18 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
>  		spi_nor_set_read_settings_from_bfpt(read, half, rd->proto);
>  	}
> 
> +	/* Make sure BFPT provide dwords more than 16 and parsing 1-1-8 
> information */
> +	if (bfpt_header->length > BFPT_DWORD_MAX_JESD216B) {

Move that into the JESD216B and later parsing code and you don't
need this condition anymore. That is below

if (bfpt_header->length == BFPT_DWORD_MAX_JESD216)
	return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt);

> +		opcode = FIELD_GET(BFPT_DWORD17_RD_1_1_8_CMD, 
> bfpt.dwords[SFDP_DWORD(17)]);
> +		dummy = FIELD_GET(BFPT_DWORD17_RD_1_1_8_DUMMY, 
> bfpt.dwords[SFDP_DWORD(17)]);
> +		if (opcode) {

move the dummy here and you can just declare dummy here.

everything else looks sane to me.

-michael

> +			nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
> +			spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_1_1_8],
> +					  0, dummy, opcode,
> +					  SNOR_PROTO_1_1_8);
> +		}
> +	}
> +
>  	/*
>  	 * Sector Erase settings. Reinitialize the uniform erase map using 
> the
>  	 * Erase Types defined in the bfpt table.
> @@ -525,7 +538,6 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
>  	for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) {
>  		const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i];
>  		u32 erasesize;
> -		u8 opcode;
> 
>  		half = bfpt.dwords[er->dword] >> er->shift;
>  		erasesize = half & 0xff;
> @@ -968,6 +980,7 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,
>  		{ SNOR_HWCAPS_READ_1_1_1_DTR,	BIT(13) },
>  		{ SNOR_HWCAPS_READ_1_2_2_DTR,	BIT(14) },
>  		{ SNOR_HWCAPS_READ_1_4_4_DTR,	BIT(15) },
> +		{ SNOR_HWCAPS_READ_1_1_8,	BIT(20) },
>  	};
>  	static const struct sfdp_4bait programs[] = {
>  		{ SNOR_HWCAPS_PP,		BIT(6) },
> diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h
> index 6eb99e1cdd61..584a05f9931d 100644
> --- a/drivers/mtd/spi-nor/sfdp.h
> +++ b/drivers/mtd/spi-nor/sfdp.h
> @@ -118,6 +118,9 @@ struct sfdp_bfpt {
>  	(BFPT_DWORD16_EN4B_EN4B | BFPT_DWORD16_EX4B_EX4B)
>  #define BFPT_DWORD16_SWRST_EN_RST		BIT(12)
> 
> +#define BFPT_DWORD17_RD_1_1_8_CMD		GENMASK(31, 24)
> +#define BFPT_DWORD17_RD_1_1_8_DUMMY		GENMASK(20, 16)
> +
>  #define BFPT_DWORD18_CMD_EXT_MASK		GENMASK(30, 29)
>  #define BFPT_DWORD18_CMD_EXT_REP		(0x0UL << 29) /* Repeat */
>  #define BFPT_DWORD18_CMD_EXT_INV		(0x1UL << 29) /* Invert */
liao jaime Dec. 12, 2023, 2:15 a.m. UTC | #2
Hi Michael


>
> Hi,
>
> > BFPT 17th DWORD contains the informations about 1-1-8,
>
> Ok.
>
> > The difference from Dual and Quad mode is not determined
> > by a single bit indicating support but rather by using
> > 1-byte instruction, which content is the opcode.
>
> I don't get what you try to express here.
In struct sfdp_bfpt_reads[], support bit and setting are defined
for every Dual and Quad protocol.
It is a good way for checking whether the protocol support.
1-1-8 would be check by 1-byte instruction but sfdp_bfpt_reads[].

>
> > A value of 0x00 represents not support.
> > Therefore, parse BFPT 17 DWORD instruction to determine
> > whether flash support 1-1-8, and set its dummy cycle
> > accordingly.
> >
> > Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw>
> > ---
> >  drivers/mtd/spi-nor/sfdp.c | 15 ++++++++++++++-
> >  drivers/mtd/spi-nor/sfdp.h |  3 +++
> >  2 files changed, 17 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> > index b3b11dfed789..d04dbddb70d6 100644
> > --- a/drivers/mtd/spi-nor/sfdp.c
> > +++ b/drivers/mtd/spi-nor/sfdp.c
> > @@ -446,6 +446,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
> >       u32 dword;
> >       u16 half;
> >       u8 erase_mask;
> > +     u8 dummy, opcode;
> >
> >       /* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs.
> > */
> >       if (bfpt_header->length < BFPT_DWORD_MAX_JESD216)
> > @@ -516,6 +517,18 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
> >               spi_nor_set_read_settings_from_bfpt(read, half, rd->proto);
> >       }
> >
> > +     /* Make sure BFPT provide dwords more than 16 and parsing 1-1-8
> > information */
> > +     if (bfpt_header->length > BFPT_DWORD_MAX_JESD216B) {
>
> Move that into the JESD216B and later parsing code and you don't
> need this condition anymore. That is below
Sounds good, got it.
>
> if (bfpt_header->length == BFPT_DWORD_MAX_JESD216)
>         return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt);
>
> > +             opcode = FIELD_GET(BFPT_DWORD17_RD_1_1_8_CMD,
> > bfpt.dwords[SFDP_DWORD(17)]);
> > +             dummy = FIELD_GET(BFPT_DWORD17_RD_1_1_8_DUMMY,
> > bfpt.dwords[SFDP_DWORD(17)]);
> > +             if (opcode) {
>
> move the dummy here and you can just declare dummy here.
Got it.

>
> everything else looks sane to me.
>
> -michael

Thanks
Jaime
>
> > +                     nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
> > +                     spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_1_1_8],
> > +                                       0, dummy, opcode,
> > +                                       SNOR_PROTO_1_1_8);
> > +             }
> > +     }
> > +
> >       /*
> >        * Sector Erase settings. Reinitialize the uniform erase map using
> > the
> >        * Erase Types defined in the bfpt table.
> > @@ -525,7 +538,6 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
> >       for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) {
> >               const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i];
> >               u32 erasesize;
> > -             u8 opcode;
> >
> >               half = bfpt.dwords[er->dword] >> er->shift;
> >               erasesize = half & 0xff;
> > @@ -968,6 +980,7 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,
> >               { SNOR_HWCAPS_READ_1_1_1_DTR,   BIT(13) },
> >               { SNOR_HWCAPS_READ_1_2_2_DTR,   BIT(14) },
> >               { SNOR_HWCAPS_READ_1_4_4_DTR,   BIT(15) },
> > +             { SNOR_HWCAPS_READ_1_1_8,       BIT(20) },
> >       };
> >       static const struct sfdp_4bait programs[] = {
> >               { SNOR_HWCAPS_PP,               BIT(6) },
> > diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h
> > index 6eb99e1cdd61..584a05f9931d 100644
> > --- a/drivers/mtd/spi-nor/sfdp.h
> > +++ b/drivers/mtd/spi-nor/sfdp.h
> > @@ -118,6 +118,9 @@ struct sfdp_bfpt {
> >       (BFPT_DWORD16_EN4B_EN4B | BFPT_DWORD16_EX4B_EX4B)
> >  #define BFPT_DWORD16_SWRST_EN_RST            BIT(12)
> >
> > +#define BFPT_DWORD17_RD_1_1_8_CMD            GENMASK(31, 24)
> > +#define BFPT_DWORD17_RD_1_1_8_DUMMY          GENMASK(20, 16)
> > +
> >  #define BFPT_DWORD18_CMD_EXT_MASK            GENMASK(30, 29)
> >  #define BFPT_DWORD18_CMD_EXT_REP             (0x0UL << 29) /* Repeat */
> >  #define BFPT_DWORD18_CMD_EXT_INV             (0x1UL << 29) /* Invert */
diff mbox series

Patch

diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index b3b11dfed789..d04dbddb70d6 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -446,6 +446,7 @@  static int spi_nor_parse_bfpt(struct spi_nor *nor,
 	u32 dword;
 	u16 half;
 	u8 erase_mask;
+	u8 dummy, opcode;
 
 	/* JESD216 Basic Flash Parameter Table length is at least 9 DWORDs. */
 	if (bfpt_header->length < BFPT_DWORD_MAX_JESD216)
@@ -516,6 +517,18 @@  static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		spi_nor_set_read_settings_from_bfpt(read, half, rd->proto);
 	}
 
+	/* Make sure BFPT provide dwords more than 16 and parsing 1-1-8 information */
+	if (bfpt_header->length > BFPT_DWORD_MAX_JESD216B) {
+		opcode = FIELD_GET(BFPT_DWORD17_RD_1_1_8_CMD, bfpt.dwords[SFDP_DWORD(17)]);
+		dummy = FIELD_GET(BFPT_DWORD17_RD_1_1_8_DUMMY, bfpt.dwords[SFDP_DWORD(17)]);
+		if (opcode) {
+			nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8;
+			spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_1_1_8],
+					  0, dummy, opcode,
+					  SNOR_PROTO_1_1_8);
+		}
+	}
+
 	/*
 	 * Sector Erase settings. Reinitialize the uniform erase map using the
 	 * Erase Types defined in the bfpt table.
@@ -525,7 +538,6 @@  static int spi_nor_parse_bfpt(struct spi_nor *nor,
 	for (i = 0; i < ARRAY_SIZE(sfdp_bfpt_erases); i++) {
 		const struct sfdp_bfpt_erase *er = &sfdp_bfpt_erases[i];
 		u32 erasesize;
-		u8 opcode;
 
 		half = bfpt.dwords[er->dword] >> er->shift;
 		erasesize = half & 0xff;
@@ -968,6 +980,7 @@  static int spi_nor_parse_4bait(struct spi_nor *nor,
 		{ SNOR_HWCAPS_READ_1_1_1_DTR,	BIT(13) },
 		{ SNOR_HWCAPS_READ_1_2_2_DTR,	BIT(14) },
 		{ SNOR_HWCAPS_READ_1_4_4_DTR,	BIT(15) },
+		{ SNOR_HWCAPS_READ_1_1_8,	BIT(20) },
 	};
 	static const struct sfdp_4bait programs[] = {
 		{ SNOR_HWCAPS_PP,		BIT(6) },
diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h
index 6eb99e1cdd61..584a05f9931d 100644
--- a/drivers/mtd/spi-nor/sfdp.h
+++ b/drivers/mtd/spi-nor/sfdp.h
@@ -118,6 +118,9 @@  struct sfdp_bfpt {
 	(BFPT_DWORD16_EN4B_EN4B | BFPT_DWORD16_EX4B_EX4B)
 #define BFPT_DWORD16_SWRST_EN_RST		BIT(12)
 
+#define BFPT_DWORD17_RD_1_1_8_CMD		GENMASK(31, 24)
+#define BFPT_DWORD17_RD_1_1_8_DUMMY		GENMASK(20, 16)
+
 #define BFPT_DWORD18_CMD_EXT_MASK		GENMASK(30, 29)
 #define BFPT_DWORD18_CMD_EXT_REP		(0x0UL << 29) /* Repeat */
 #define BFPT_DWORD18_CMD_EXT_INV		(0x1UL << 29) /* Invert */