All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mason Yang <masonccyang@mxic.com.tw>
To: broonie@kernel.org, miquel.raynal@bootlin.com, richard@nod.at,
	marek.vasut@gmail.com, dwmw2@infradead.org,
	computersforpeace@gmail.com, vigneshr@ti.com,
	bbrezillon@kernel.org, tudor.ambarus@microchip.com
Cc: juliensu@mxic.com.tw, linux-kernel@vger.kernel.org,
	linux-mtd@lists.infradead.org, linux-spi@vger.kernel.org,
	Mason Yang <masonccyang@mxic.com.tw>,
	Boris Brezillon <boris.brezillon@bootlin.com>
Subject: [PATCH 3/4] mtd: spi-nor: Add Octal 8D-8D-8D mode support for Macronix mx25uw51245g
Date: Fri, 15 Nov 2019 16:58:07 +0800	[thread overview]
Message-ID: <1573808288-19365-4-git-send-email-masonccyang@mxic.com.tw> (raw)
In-Reply-To: <1573808288-19365-1-git-send-email-masonccyang@mxic.com.tw>

mx25uw51245g is a SPI NOR that supports 1-1-1/8-8-8 mode and the SFDPRD
command but returns an empty SFDP page. This forces us to add a new entry
in the flash_info table and patch spi_nor_fixups hooks to tweak flash
parameters for spi_nor_read/pp_setting() and then to enter
Octal 8D-8D-8D modes.

Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
---
 drivers/mtd/spi-nor/spi-nor.c | 114 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/spi-nor.h   |   3 ++
 2 files changed, 117 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 4cdf52d..9013590 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -615,6 +615,56 @@ static int write_disable(struct spi_nor *nor)
 }
 
 /*
+ * Read configuration register 2, returning its value in the
+ * location. Return the configuration register 2 value.
+ * Returns negative if error occurred.
+ */
+static int read_cr2(struct spi_nor *nor, u32 addr)
+{
+	int ret;
+
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDCR2, 1),
+				   SPI_MEM_OP_ADDR(4, addr, 1),
+				   SPI_MEM_OP_DUMMY(4, 1),
+				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+
+		if (spi_nor_protocol_is_8_8_8(nor->read_proto)) {
+			op.cmd.buswidth = 8;
+			op.addr.buswidth = 8;
+			op.dummy.buswidth = 8;
+			op.data.buswidth = 8;
+			op.cmd.nbytes = 2;
+
+			if (spi_nor_protocol_is_8D_8D_8D(nor->read_proto)) {
+				op.dummy.nbytes *= 2;
+				op.cmd.dtr = true;
+				op.addr.dtr = true;
+				op.dummy.dtr = true;
+				op.data.dtr = true;
+			}
+
+			if (nor->ext_cmd_mode == EXT_CMD_IS_INVERSE)
+				op.cmd.ext_opcode = ~SPINOR_OP_RDCR2;
+			else
+				op.cmd.ext_opcode = SPINOR_OP_RDCR2;
+		}
+
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = -ENOTSUPP;
+	}
+
+	if (ret < 0) {
+		dev_err(nor->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return nor->bouncebuf[0];
+}
+
+/*
  * Write configuration register 2 one byte
  * Returns negative if error occurred.
  */
@@ -2275,10 +2325,72 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	return 0;
 }
 
+static void
+spi_nor_set_read_settings(struct spi_nor_read_command *read,
+			  u8 num_mode_clocks,
+			  u8 num_wait_states,
+			  u8 opcode,
+			  enum spi_nor_protocol proto);
+
+static void
+spi_nor_set_pp_settings(struct spi_nor_pp_command *pp,
+			u8 opcode,
+			enum spi_nor_protocol proto);
+
+static void
+mx25uw51245g_default_init(struct spi_nor *nor)
+{
+	struct spi_nor_flash_parameter *params = &nor->params;
+
+	if (!(nor->spimem->spi->mode & (SPI_RX_OCTAL | SPI_TX_OCTAL)))
+		return;
+
+	/* Octal 8S-8S-8S mode */
+	params->hwcaps.mask |= SNOR_HWCAPS_OPI_FULL_STR;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8_8_8],
+				  0, 20, SPINOR_OP_READ_8_8_8,
+				  SNOR_PROTO_8_8_8);
+
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8],
+				SPINOR_OP_PP_8_8_8, SNOR_PROTO_8_8_8);
+
+	/* Octal 8D-8D-8D mode */
+	params->hwcaps.mask |= SNOR_HWCAPS_OPI_FULL_DTR;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8D_8D_8D],
+				  0, 20, SPINOR_OP_READ_8D_8D_8D,
+				  SNOR_PROTO_8_8_8_DTR);
+
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8D_8D_8D],
+				SPINOR_OP_PP_8D_8D_8D, SNOR_PROTO_8_8_8_DTR);
+
+	nor->ext_cmd_mode = EXT_CMD_IS_INVERSE;
+}
+
+static void
+mx25uw51245g_post_sfdp_fixups(struct spi_nor *nor)
+{
+	struct spi_nor_flash_parameter *params = &nor->params;
+	u8 cr2;
+
+	cr2 = read_cr2(nor, CR2_REG0) & CR2_REG0_MODE_MASK;
+
+	if (params->hwcaps.mask & SNOR_HWCAPS_OPI_FULL_DTR)
+		cr2 |= CR2_REG0_MODE_OPI_DTR;
+	else if (params->hwcaps.mask & SNOR_HWCAPS_OPI_FULL_STR)
+		cr2 |= CR2_REG0_MODE_OPI_STR;
+
+	write_cr2(nor, CR2_REG0, cr2);
+}
+
 static struct spi_nor_fixups mx25l25635_fixups = {
 	.post_bfpt = mx25l25635_post_bfpt_fixups,
 };
 
+static struct spi_nor_fixups mx25uw51245g_fixups = {
+	.default_init = mx25uw51245g_default_init,
+	.post_sfdp = mx25uw51245g_post_sfdp_fixups,
+};
+
 static void gd25q256_default_init(struct spi_nor *nor)
 {
 	/*
@@ -2442,6 +2554,8 @@ static void gd25q256_default_init(struct spi_nor *nor)
 			 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
 			 .fixups = &mx25l25635_fixups },
 	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
+	{ "mx25uw51245g", INFO(0xc2813a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_4B_OPCODES)
+				.fixups = &mx25uw51245g_fixups},
 	{ "mx25v8035f",  INFO(0xc22314, 0, 64 * 1024,  16,
 			 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 2e720ca..3aa54dd 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -114,6 +114,9 @@
 /* Write CFG Reg 2 - defined in JEDEC JESD216C. */
 #define SPINOR_OP_WRCR2		0x72	/* Write configuration register 2 */
 
+/* Used for Macronix flashes only */
+#define SPINOR_OP_RDCR2		0x71	/* Read configuration register 2 */
+
 /* Used for Macronix and Winbond flashes. */
 #define SPINOR_OP_EN4B		0xb7	/* Enter 4-byte mode */
 #define SPINOR_OP_EX4B		0xe9	/* Exit 4-byte mode */
-- 
1.9.1


WARNING: multiple messages have this Message-ID (diff)
From: Mason Yang <masonccyang@mxic.com.tw>
To: broonie@kernel.org, miquel.raynal@bootlin.com, richard@nod.at,
	marek.vasut@gmail.com, dwmw2@infradead.org,
	computersforpeace@gmail.com, vigneshr@ti.com,
	bbrezillon@kernel.org, tudor.ambarus@microchip.com
Cc: juliensu@mxic.com.tw, linux-kernel@vger.kernel.org,
	linux-spi@vger.kernel.org,
	Boris Brezillon <boris.brezillon@bootlin.com>,
	linux-mtd@lists.infradead.org,
	Mason Yang <masonccyang@mxic.com.tw>
Subject: [PATCH 3/4] mtd: spi-nor: Add Octal 8D-8D-8D mode support for Macronix mx25uw51245g
Date: Fri, 15 Nov 2019 16:58:07 +0800	[thread overview]
Message-ID: <1573808288-19365-4-git-send-email-masonccyang@mxic.com.tw> (raw)
In-Reply-To: <1573808288-19365-1-git-send-email-masonccyang@mxic.com.tw>

mx25uw51245g is a SPI NOR that supports 1-1-1/8-8-8 mode and the SFDPRD
command but returns an empty SFDP page. This forces us to add a new entry
in the flash_info table and patch spi_nor_fixups hooks to tweak flash
parameters for spi_nor_read/pp_setting() and then to enter
Octal 8D-8D-8D modes.

Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
---
 drivers/mtd/spi-nor/spi-nor.c | 114 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/spi-nor.h   |   3 ++
 2 files changed, 117 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 4cdf52d..9013590 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -615,6 +615,56 @@ static int write_disable(struct spi_nor *nor)
 }
 
 /*
+ * Read configuration register 2, returning its value in the
+ * location. Return the configuration register 2 value.
+ * Returns negative if error occurred.
+ */
+static int read_cr2(struct spi_nor *nor, u32 addr)
+{
+	int ret;
+
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDCR2, 1),
+				   SPI_MEM_OP_ADDR(4, addr, 1),
+				   SPI_MEM_OP_DUMMY(4, 1),
+				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+
+		if (spi_nor_protocol_is_8_8_8(nor->read_proto)) {
+			op.cmd.buswidth = 8;
+			op.addr.buswidth = 8;
+			op.dummy.buswidth = 8;
+			op.data.buswidth = 8;
+			op.cmd.nbytes = 2;
+
+			if (spi_nor_protocol_is_8D_8D_8D(nor->read_proto)) {
+				op.dummy.nbytes *= 2;
+				op.cmd.dtr = true;
+				op.addr.dtr = true;
+				op.dummy.dtr = true;
+				op.data.dtr = true;
+			}
+
+			if (nor->ext_cmd_mode == EXT_CMD_IS_INVERSE)
+				op.cmd.ext_opcode = ~SPINOR_OP_RDCR2;
+			else
+				op.cmd.ext_opcode = SPINOR_OP_RDCR2;
+		}
+
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = -ENOTSUPP;
+	}
+
+	if (ret < 0) {
+		dev_err(nor->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return nor->bouncebuf[0];
+}
+
+/*
  * Write configuration register 2 one byte
  * Returns negative if error occurred.
  */
@@ -2275,10 +2325,72 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	return 0;
 }
 
+static void
+spi_nor_set_read_settings(struct spi_nor_read_command *read,
+			  u8 num_mode_clocks,
+			  u8 num_wait_states,
+			  u8 opcode,
+			  enum spi_nor_protocol proto);
+
+static void
+spi_nor_set_pp_settings(struct spi_nor_pp_command *pp,
+			u8 opcode,
+			enum spi_nor_protocol proto);
+
+static void
+mx25uw51245g_default_init(struct spi_nor *nor)
+{
+	struct spi_nor_flash_parameter *params = &nor->params;
+
+	if (!(nor->spimem->spi->mode & (SPI_RX_OCTAL | SPI_TX_OCTAL)))
+		return;
+
+	/* Octal 8S-8S-8S mode */
+	params->hwcaps.mask |= SNOR_HWCAPS_OPI_FULL_STR;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8_8_8],
+				  0, 20, SPINOR_OP_READ_8_8_8,
+				  SNOR_PROTO_8_8_8);
+
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8],
+				SPINOR_OP_PP_8_8_8, SNOR_PROTO_8_8_8);
+
+	/* Octal 8D-8D-8D mode */
+	params->hwcaps.mask |= SNOR_HWCAPS_OPI_FULL_DTR;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8D_8D_8D],
+				  0, 20, SPINOR_OP_READ_8D_8D_8D,
+				  SNOR_PROTO_8_8_8_DTR);
+
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8D_8D_8D],
+				SPINOR_OP_PP_8D_8D_8D, SNOR_PROTO_8_8_8_DTR);
+
+	nor->ext_cmd_mode = EXT_CMD_IS_INVERSE;
+}
+
+static void
+mx25uw51245g_post_sfdp_fixups(struct spi_nor *nor)
+{
+	struct spi_nor_flash_parameter *params = &nor->params;
+	u8 cr2;
+
+	cr2 = read_cr2(nor, CR2_REG0) & CR2_REG0_MODE_MASK;
+
+	if (params->hwcaps.mask & SNOR_HWCAPS_OPI_FULL_DTR)
+		cr2 |= CR2_REG0_MODE_OPI_DTR;
+	else if (params->hwcaps.mask & SNOR_HWCAPS_OPI_FULL_STR)
+		cr2 |= CR2_REG0_MODE_OPI_STR;
+
+	write_cr2(nor, CR2_REG0, cr2);
+}
+
 static struct spi_nor_fixups mx25l25635_fixups = {
 	.post_bfpt = mx25l25635_post_bfpt_fixups,
 };
 
+static struct spi_nor_fixups mx25uw51245g_fixups = {
+	.default_init = mx25uw51245g_default_init,
+	.post_sfdp = mx25uw51245g_post_sfdp_fixups,
+};
+
 static void gd25q256_default_init(struct spi_nor *nor)
 {
 	/*
@@ -2442,6 +2554,8 @@ static void gd25q256_default_init(struct spi_nor *nor)
 			 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
 			 .fixups = &mx25l25635_fixups },
 	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
+	{ "mx25uw51245g", INFO(0xc2813a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_4B_OPCODES)
+				.fixups = &mx25uw51245g_fixups},
 	{ "mx25v8035f",  INFO(0xc22314, 0, 64 * 1024,  16,
 			 SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 2e720ca..3aa54dd 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -114,6 +114,9 @@
 /* Write CFG Reg 2 - defined in JEDEC JESD216C. */
 #define SPINOR_OP_WRCR2		0x72	/* Write configuration register 2 */
 
+/* Used for Macronix flashes only */
+#define SPINOR_OP_RDCR2		0x71	/* Read configuration register 2 */
+
 /* Used for Macronix and Winbond flashes. */
 #define SPINOR_OP_EN4B		0xb7	/* Enter 4-byte mode */
 #define SPINOR_OP_EX4B		0xe9	/* Exit 4-byte mode */
-- 
1.9.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  parent reply	other threads:[~2019-11-15  8:58 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-15  8:58 [PATCH 0/4] mtd: spi-nor: Add support for Octal 8D-8D-8D mode Mason Yang
2019-11-15  8:58 ` Mason Yang
2019-11-15  8:58 ` [PATCH 1/4] spi: spi-mem: " Mason Yang
2019-11-15  8:58   ` Mason Yang
2019-11-15  8:58 ` [PATCH 2/4] mtd: spi-nor: " Mason Yang
2019-11-15  8:58   ` Mason Yang
2019-11-15 12:30   ` kbuild test robot
2019-11-15 12:30     ` kbuild test robot
2019-11-15 12:30     ` kbuild test robot
2019-11-15 13:42   ` kbuild test robot
2019-11-15 13:42     ` kbuild test robot
2019-11-15 13:42     ` kbuild test robot
2019-12-04 12:46   ` Vignesh Raghavendra
2019-12-04 12:46     ` Vignesh Raghavendra
2019-12-09  7:56     ` masonccyang
2019-12-09  7:56       ` masonccyang
2019-12-09  9:53       ` Vignesh Raghavendra
2019-12-09  9:53         ` Vignesh Raghavendra
2019-12-10  7:21         ` masonccyang
2019-12-10  7:21           ` masonccyang
2019-11-15  8:58 ` Mason Yang [this message]
2019-11-15  8:58   ` [PATCH 3/4] mtd: spi-nor: Add Octal 8D-8D-8D mode support for Macronix mx25uw51245g Mason Yang
2019-12-04 13:03   ` Vignesh Raghavendra
2019-12-04 13:03     ` Vignesh Raghavendra
2019-12-09  6:38     ` masonccyang
2019-12-09  6:38       ` masonccyang
2019-11-15  8:58 ` [PATCH 4/4] spi: mxic: Add support for Octal 8D-8D-8D mode Mason Yang
2019-11-15  8:58   ` Mason Yang
2019-11-15 14:39   ` kbuild test robot
2019-11-15 14:39     ` kbuild test robot
2019-11-15 14:39     ` kbuild test robot
2019-11-16  7:20   ` kbuild test robot
2019-11-16  7:20     ` kbuild test robot
2019-11-16  7:20     ` kbuild test robot
2019-12-10 17:00 ` [PATCH 0/4] mtd: spi-nor: " Tudor.Ambarus
2019-12-10 17:00   ` Tudor.Ambarus
2019-12-11  2:14   ` masonccyang
2019-12-11  2:14     ` masonccyang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1573808288-19365-4-git-send-email-masonccyang@mxic.com.tw \
    --to=masonccyang@mxic.com.tw \
    --cc=bbrezillon@kernel.org \
    --cc=boris.brezillon@bootlin.com \
    --cc=broonie@kernel.org \
    --cc=computersforpeace@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=juliensu@mxic.com.tw \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=marek.vasut@gmail.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=richard@nod.at \
    --cc=tudor.ambarus@microchip.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.