[PATCH 19/19] mtd: spi-nor: Enable DDR mode functionality with Macronix flash
Tejas Bhumkar
tejas.arvind.bhumkar at amd.com
Mon Mar 11 18:22:49 CET 2024
Added SFDP fixups for Macronix octal flash, with the requirement
of the Invert Dual-byte opcode in Octal DDR mode.
Reference: linux-xlnx at 08cf794
Signed-off-by: Tejas Bhumkar <tejas.arvind.bhumkar at amd.com>
---
drivers/mtd/spi/spi-nor-core.c | 49 +++++++++++++++++++++++++++++-----
drivers/mtd/spi/spi-nor-ids.c | 2 ++
2 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 6b396ce681..9c2d70585a 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -4089,18 +4089,18 @@ static int spi_nor_macronix_octal_dtr_enable(struct spi_nor *nor)
{
struct spi_mem_op op;
int ret;
- u8 buf;
+ u8 *buf = nor->cmd_buf;
ret = write_enable(nor);
if (ret)
return ret;
- buf = SPINOR_REG_MXIC_DC_20;
+ *buf = SPINOR_REG_MXIC_DC_20;
op = (struct spi_mem_op)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_CR2, 1),
SPI_MEM_OP_ADDR(4, SPINOR_REG_MXIC_CR2_DC, 1),
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_OUT(1, &buf, 1));
+ SPI_MEM_OP_DATA_OUT(1, buf, 1));
ret = spi_mem_exec_op(nor->spi, &op);
if (ret)
@@ -4115,18 +4115,33 @@ static int spi_nor_macronix_octal_dtr_enable(struct spi_nor *nor)
if (ret)
return ret;
- buf = SPINOR_REG_MXIC_OPI_DTR_EN;
+ nor->spi->flags |= SPI_XFER_SET_DDR;
+ *buf = SPINOR_REG_MXIC_OPI_DTR_EN;
op = (struct spi_mem_op)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_CR2, 1),
SPI_MEM_OP_ADDR(4, SPINOR_REG_MXIC_CR2_MODE, 1),
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_OUT(1, &buf, 1));
+ SPI_MEM_OP_DATA_OUT(1, buf, 1));
ret = spi_mem_exec_op(nor->spi, &op);
if (ret) {
dev_err(nor->dev, "Failed to enable octal DTR mode\n");
return ret;
}
+
+ /* Read flash ID to make sure the switch was successful. */
+ op = (struct spi_mem_op)
+ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
+ SPI_MEM_OP_ADDR(4, 0, 1),
+ SPI_MEM_OP_DUMMY(4, 1),
+ SPI_MEM_OP_DATA_IN(round_up(nor->info->id_len, 2), buf, 1));
+
+ spi_nor_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR);
+
+ ret = spi_mem_exec_op(nor->spi, &op);
+ if (ret)
+ return ret;
+
nor->reg_proto = SNOR_PROTO_8_8_8_DTR;
return 0;
@@ -4134,6 +4149,20 @@ static int spi_nor_macronix_octal_dtr_enable(struct spi_nor *nor)
static void macronix_octal_default_init(struct spi_nor *nor)
{
+ u8 id_byte1, id_byte2;
+ /*
+ * Macronix Read Id bytes are always output in STR mode. Since tuning
+ * is based on Read Id command, adjust the Read Id bytes that will
+ * match the Read Id output in DTR mode.
+ */
+ id_byte1 = nor->spi->device_id[1];
+ id_byte2 = nor->spi->device_id[2];
+ nor->spi->device_id[1] = nor->spi->device_id[0];
+ nor->spi->device_id[2] = id_byte1;
+ nor->spi->device_id[3] = id_byte1;
+ nor->spi->device_id[4] = id_byte2;
+ nor->spi->device_id[5] = id_byte2;
+
nor->octal_dtr_enable = spi_nor_macronix_octal_dtr_enable;
}
@@ -4144,8 +4173,16 @@ static void macronix_octal_post_sfdp_fixup(struct spi_nor *nor,
* Adding SNOR_HWCAPS_PP_8_8_8_DTR in hwcaps.mask when
* SPI_NOR_OCTAL_DTR_READ flag exists.
*/
- if (params->hwcaps.mask & SNOR_HWCAPS_READ_8_8_8_DTR)
+ if (params->hwcaps.mask & SNOR_HWCAPS_READ_8_8_8_DTR) {
params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
+ spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_8_8_8_DTR],
+ 0, 20, SPINOR_OP_MXIC_DTR_RD,
+ SNOR_PROTO_8_8_8_DTR);
+ nor->cmd_ext_type = SPI_NOR_EXT_INVERT;
+ nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
+ params->rdsr_dummy = 8;
+ params->rdsr_addr_nbytes = 0;
+ }
}
static struct spi_nor_fixups macronix_octal_fixups = {
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 34fba49592..cd3fcda70c 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -275,6 +275,8 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("mx66l2g45g", 0xc2201c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024, 128, SECT_4K) },
+ { INFO("mx25um51345g", 0xc2813a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP) },
+ { INFO("mx66um2g45g", 0xc2803c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP) },
{ INFO("mx66uw2g345gx0", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66lm1g45g", 0xc2853b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx25lm51245g", 0xc2853a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
--
2.27.0
More information about the U-Boot
mailing list