[PATCH 2/5] mtd: spi-nor: spansion: Rework octal_dtr_enable()
tkuw584924 at gmail.com
tkuw584924 at gmail.com
Mon Jun 12 03:04:06 PDT 2023
From: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
S28HS02GT is multi-chip package (MCP) device that requires Octal DTR
configuraion for each die. As preparation for MCP support, this patch
replaces cypress_nor_octal_dtr_en/dis() with cypress_nor_setup_memlat()
and cypress_nor_setup_opiddr(). And the ID check part is moved to
cypress_nor_octal_dtr_enable().
Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
---
drivers/mtd/spi-nor/spansion.c | 118 +++++++++++++++++----------------
1 file changed, 62 insertions(+), 56 deletions(-)
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index 7804be3a9f2a..0daa3a357ae8 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -156,7 +156,7 @@ static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor)
return 1;
}
-static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
+static int cypress_nor_setup_memlat(struct spi_nor *nor)
{
struct spi_mem_op op;
u8 *buf = nor->bouncebuf;
@@ -178,67 +178,37 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
SPINOR_REG_CYPRESS_CFR2V, 1, buf);
- ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
- if (ret)
- return ret;
-
- nor->read_dummy = 24;
-
- /* Set the octal and DTR enable bits. */
- buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
- op = (struct spi_mem_op)
- CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
- SPINOR_REG_CYPRESS_CFR5V, 1, buf);
-
- ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
- if (ret)
- return ret;
-
- /* Read flash ID to make sure the switch was successful. */
- ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf,
- SNOR_PROTO_8_8_8_DTR);
- if (ret) {
- dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
- return ret;
- }
-
- if (memcmp(buf, nor->info->id, nor->info->id_len))
- return -EINVAL;
-
- return 0;
+ return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
}
-static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
+static int cypress_nor_setup_opiddr(struct spi_nor *nor, bool enable)
{
struct spi_mem_op op;
u8 *buf = nor->bouncebuf;
- int ret;
-
- /*
- * The register is 1-byte wide, but 1-byte transactions are not allowed
- * in 8D-8D-8D mode. Since there is no register at the next location,
- * just initialize the value to 0 and let the transaction go on.
- */
- buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS;
- buf[1] = 0;
- op = (struct spi_mem_op)
- CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes,
- SPINOR_REG_CYPRESS_CFR5V, 2, buf);
- ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
- if (ret)
- return ret;
- /* Read flash ID to make sure the switch was successful. */
- ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
- if (ret) {
- dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
- return ret;
+ if (enable) {
+ /* Set the octal and DTR enable bits. */
+ buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
+ op = (struct spi_mem_op)
+ CYPRESS_NOR_WR_ANY_REG_OP(nor->params->addr_mode_nbytes,
+ SPINOR_REG_CYPRESS_CFR5V, 1,
+ buf);
+ } else {
+ /*
+ * The register is 1-byte wide, but 1-byte transactions are not
+ * allowed in 8D-8D-8D mode. Since there is no register at the
+ * next location, just initialize the value to 0 and let the
+ * transaction go on.
+ */
+ buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS;
+ buf[1] = 0;
+ op = (struct spi_mem_op)
+ CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes,
+ SPINOR_REG_CYPRESS_CFR5V, 2,
+ buf);
}
- if (memcmp(buf, nor->info->id, nor->info->id_len))
- return -EINVAL;
-
- return 0;
+ return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
}
static int cypress_nor_quad_enable_volatile_reg(struct spi_nor *nor, u64 addr)
@@ -642,8 +612,44 @@ static struct spi_nor_fixups s25hx_t_fixups = {
*/
static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
{
- return enable ? cypress_nor_octal_dtr_en(nor) :
- cypress_nor_octal_dtr_dis(nor);
+ int ret;
+ u8 naddr, ndummy;
+ enum spi_nor_protocol proto;
+
+ if (enable) {
+ ret = cypress_nor_setup_memlat(nor);
+ if (ret)
+ return ret;
+
+ nor->read_dummy = 24;
+ }
+
+ ret = cypress_nor_setup_opiddr(nor, enable);
+ if (ret)
+ return ret;
+
+ /* Read flash ID to make sure the switch was successful. */
+ if (enable) {
+ naddr = nor->addr_nbytes;
+ ndummy = 3;
+ proto = SNOR_PROTO_8_8_8_DTR;
+ } else {
+ naddr = 0;
+ ndummy = 0;
+ proto = SNOR_PROTO_1_1_1;
+ }
+
+ ret = spi_nor_read_id(nor, naddr, ndummy, nor->bouncebuf, proto);
+ if (ret) {
+ dev_dbg(nor->dev, "error %d reading JEDEC ID after %s 8D-8D-8D mode\n",
+ ret, enable ? "enabling" : "disabling");
+ return ret;
+ }
+
+ if (memcmp(nor->bouncebuf, nor->info->id, nor->info->id_len))
+ return -EINVAL;
+
+ return 0;
}
static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
--
2.34.1
More information about the linux-mtd
mailing list