Message ID | 20231221090702.103027-4-jaimeliao.tw@gmail.com |
---|---|
State | Changes Requested |
Delegated to: | Ambarus Tudor |
Headers | show |
Series | Add octal DTR support for Macronix flash | expand |
Hi, > Macronix swaps bytes on a 16-bit boundary when configured in Octal DTR. > The byte order of 16-bit words is swapped when read or written in > 8D-8D-8D > mode compared to STR modes. Allow operations to specify the byte order > in > DTR mode, so that controllers can swap the bytes back at run-time to > address the flash's endianness requirements, if they are capable. If > the > controllers are not capable of swapping the bytes, the protocol is > downgrade via spi_nor_spimem_adjust_hwcaps(). When available, the > swapping > of the bytes is always done regardless if it's a data or register > access, > so that we comply with the JESD216 requirements: "Byte order of 16-bit > words is swapped when read in 8D-8D-8D mode compared to 1-1-1". > > Merge Tudor's patch and add modifications for suiting newer version > of Linux kernel. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw> > --- > drivers/mtd/spi-nor/core.c | 8 ++++++++ > drivers/mtd/spi-nor/core.h | 1 + > 2 files changed, 9 insertions(+) > > diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c > index 1c443fe568cf..f659dd037a25 100644 > --- a/drivers/mtd/spi-nor/core.c > +++ b/drivers/mtd/spi-nor/core.c > @@ -70,6 +70,13 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor > *nor, > } > } > > +static inline bool spi_nor_is_octal_dtr_swab16(const struct spi_nor > *nor, > + enum spi_nor_protocol proto) > +{ > + return (proto == SNOR_PROTO_8_8_8_DTR) && > + (nor->flags & SNOR_F_DTR_SWAB16); > +} > + > /** > * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem > op. > * @nor: pointer to a 'struct spi_nor' > @@ -105,6 +112,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor > *nor, > op->addr.dtr = true; > op->dummy.dtr = true; > op->data.dtr = true; > + op->data.dtr_swab16 = spi_nor_is_octal_dtr_swab16(nor, proto); Just use dtr_swap16 = nor->flags & SNOR_F_DTR_SWAP16; Again, I don't really like DTR_SWAP16. JESD216 just mention swapping for 8d8d8d. Depends on how generic we want to go. I'd go with swap16 and mention that for now, it is only applicable if data.buswidth == 8 and data.dtr == true. -michael > /* 2 bytes per clock cycle in DTR mode. */ > op->dummy.nbytes *= 2; > diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h > index 93cd2fc3606d..fe1259b32110 100644 > --- a/drivers/mtd/spi-nor/core.h > +++ b/drivers/mtd/spi-nor/core.h > @@ -140,6 +140,7 @@ enum spi_nor_option_flags { > SNOR_F_RWW = BIT(14), > SNOR_F_ECC = BIT(15), > SNOR_F_NO_WP = BIT(16), > + SNOR_F_DTR_SWAB16 = BIT(17), > }; > > struct spi_nor_read_command {
Hi Michael > > Hi, > > > Macronix swaps bytes on a 16-bit boundary when configured in Octal DTR. > > The byte order of 16-bit words is swapped when read or written in > > 8D-8D-8D > > mode compared to STR modes. Allow operations to specify the byte order > > in > > DTR mode, so that controllers can swap the bytes back at run-time to > > address the flash's endianness requirements, if they are capable. If > > the > > controllers are not capable of swapping the bytes, the protocol is > > downgrade via spi_nor_spimem_adjust_hwcaps(). When available, the > > swapping > > of the bytes is always done regardless if it's a data or register > > access, > > so that we comply with the JESD216 requirements: "Byte order of 16-bit > > words is swapped when read in 8D-8D-8D mode compared to 1-1-1". > > > > Merge Tudor's patch and add modifications for suiting newer version > > of Linux kernel. > > > > Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> > > Signed-off-by: JaimeLiao <jaimeliao@mxic.com.tw> > > --- > > drivers/mtd/spi-nor/core.c | 8 ++++++++ > > drivers/mtd/spi-nor/core.h | 1 + > > 2 files changed, 9 insertions(+) > > > > diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c > > index 1c443fe568cf..f659dd037a25 100644 > > --- a/drivers/mtd/spi-nor/core.c > > +++ b/drivers/mtd/spi-nor/core.c > > @@ -70,6 +70,13 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor > > *nor, > > } > > } > > > > +static inline bool spi_nor_is_octal_dtr_swab16(const struct spi_nor > > *nor, > > + enum spi_nor_protocol proto) > > +{ > > + return (proto == SNOR_PROTO_8_8_8_DTR) && > > + (nor->flags & SNOR_F_DTR_SWAB16); > > +} > > + > > /** > > * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem > > op. > > * @nor: pointer to a 'struct spi_nor' > > @@ -105,6 +112,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor > > *nor, > > op->addr.dtr = true; > > op->dummy.dtr = true; > > op->data.dtr = true; > > + op->data.dtr_swab16 = spi_nor_is_octal_dtr_swab16(nor, proto); > > Just use > dtr_swap16 = nor->flags & SNOR_F_DTR_SWAP16; Got it. > > Again, I don't really like DTR_SWAP16. JESD216 just mention swapping for > 8d8d8d. Depends on how generic we want to go. I'd go with swap16 and > mention > that for now, it is only applicable if data.buswidth == 8 and > data.dtr == true. > > -michael > > > /* 2 bytes per clock cycle in DTR mode. */ > > op->dummy.nbytes *= 2; > > diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h > > index 93cd2fc3606d..fe1259b32110 100644 > > --- a/drivers/mtd/spi-nor/core.h > > +++ b/drivers/mtd/spi-nor/core.h > > @@ -140,6 +140,7 @@ enum spi_nor_option_flags { > > SNOR_F_RWW = BIT(14), > > SNOR_F_ECC = BIT(15), > > SNOR_F_NO_WP = BIT(16), > > + SNOR_F_DTR_SWAB16 = BIT(17), > > }; > > > > struct spi_nor_read_command { Thanks Jaime
On 12/21/23 09:06, Jaime Liao wrote:
> From: JaimeLiao <jaimeliao@mxic.com.tw>
Please keep my authorship, as the patch does not differ from what I've
sent at
https://patchwork.ozlabs.org/project/linux-mtd/patch/20220311080147.453483-3-tudor.ambarus@microchip.com/
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 1c443fe568cf..f659dd037a25 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -70,6 +70,13 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor, } } +static inline bool spi_nor_is_octal_dtr_swab16(const struct spi_nor *nor, + enum spi_nor_protocol proto) +{ + return (proto == SNOR_PROTO_8_8_8_DTR) && + (nor->flags & SNOR_F_DTR_SWAB16); +} + /** * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem op. * @nor: pointer to a 'struct spi_nor' @@ -105,6 +112,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor, op->addr.dtr = true; op->dummy.dtr = true; op->data.dtr = true; + op->data.dtr_swab16 = spi_nor_is_octal_dtr_swab16(nor, proto); /* 2 bytes per clock cycle in DTR mode. */ op->dummy.nbytes *= 2; diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 93cd2fc3606d..fe1259b32110 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -140,6 +140,7 @@ enum spi_nor_option_flags { SNOR_F_RWW = BIT(14), SNOR_F_ECC = BIT(15), SNOR_F_NO_WP = BIT(16), + SNOR_F_DTR_SWAB16 = BIT(17), }; struct spi_nor_read_command {