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 |
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 */
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 --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 */