All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pratyush Yadav <p.yadav@ti.com>
To: u-boot@lists.denx.de
Subject: [PATCH v8 27/28] mtd: spi-nor-core: Add support for Cypress Semper flash
Date: Fri, 2 Apr 2021 01:01:32 +0530	[thread overview]
Message-ID: <20210401193133.18129-28-p.yadav@ti.com> (raw)
In-Reply-To: <20210401193133.18129-1-p.yadav@ti.com>

The Cypress Semper flash is an xSPI compliant octal DTR flash. Add
support for using it in octal DTR mode.

The flash by default boots in a hybrid sector mode. Switch to uniform
sector mode on boot. Use the default 20 dummy cycles for a read fast
command.

The SFDP programming on some older versions of the flash was incorrect.
Fixes for that are included in the fixup hooks.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---
 drivers/mtd/spi/Kconfig        |   8 ++
 drivers/mtd/spi/spi-nor-core.c | 187 +++++++++++++++++++++++++++++++++
 drivers/mtd/spi/spi-nor-ids.c  |   3 +
 include/linux/mtd/spi-nor.h    |  13 +++
 4 files changed, 211 insertions(+)

diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index b46035aee4..98c0b23478 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -167,6 +167,14 @@ config SPI_FLASH_SPANSION
 	help
 	  Add support for various Spansion SPI flash chips (S25FLxxx)
 
+config SPI_FLASH_S28HS512T
+	bool "Cypress S28HS512T chip support"
+	depends on SPI_FLASH_SPANSION
+	help
+	 Add support for the Cypress S28HS512T chip. This is a separate config
+	 because the fixup hooks for this flash add extra size overhead. Boards
+	 that don't use the flash can disable this to save space.
+
 config SPI_FLASH_STMICRO
 	bool "STMicro SPI flash support"
 	help
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 7637539087..52e493fdc0 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -2965,6 +2965,189 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info,
 	return nor->setup(nor, info, params);
 }
 
+#ifdef CONFIG_SPI_FLASH_S28HS512T
+/**
+ * spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
+ * @nor:		pointer to a 'struct spi_nor'
+ *
+ * This also sets the memory access latency cycles to 24 to allow the flash to
+ * run at up to 200MHz.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor)
+{
+	struct spi_mem_op op;
+	u8 buf;
+	u8 addr_width = 3;
+	int ret;
+
+	/* Use 24 dummy cycles for memory array reads. */
+	ret = write_enable(nor);
+	if (ret)
+		return ret;
+
+	buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
+	op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
+			SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR2V, 1),
+			SPI_MEM_OP_NO_DUMMY,
+			SPI_MEM_OP_DATA_OUT(1, &buf, 1));
+	ret = spi_mem_exec_op(nor->spi, &op);
+	if (ret) {
+		dev_warn(nor->dev,
+			 "failed to set default memory latency value: %d\n",
+			 ret);
+		return ret;
+	}
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+
+	nor->read_dummy = 24;
+
+	/* Set the octal and DTR enable bits. */
+	ret = write_enable(nor);
+	if (ret)
+		return ret;
+
+	buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
+	op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
+			SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR5V, 1),
+			SPI_MEM_OP_NO_DUMMY,
+			SPI_MEM_OP_DATA_OUT(1, &buf, 1));
+	ret = spi_mem_exec_op(nor->spi, &op);
+	if (ret) {
+		dev_warn(nor->dev, "Failed to enable octal DTR mode\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int s28hs512t_erase_non_uniform(struct spi_nor *nor, loff_t addr)
+{
+	/* Factory default configuration: 32 x 4 KiB sectors at bottom. */
+	return spansion_erase_non_uniform(nor, addr, SPINOR_OP_S28_SE_4K,
+					  0, SZ_128K);
+}
+
+static int s28hs512t_setup(struct spi_nor *nor, const struct flash_info *info,
+			   const struct spi_nor_flash_parameter *params)
+{
+	struct spi_mem_op op;
+	u8 buf;
+	u8 addr_width = 3;
+	int ret;
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+
+	/*
+	 * Check CFR3V to check if non-uniform sector mode is selected. If it
+	 * is, set the erase hook to the non-uniform erase procedure.
+	 */
+	op = (struct spi_mem_op)
+		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
+			   SPI_MEM_OP_ADDR(addr_width,
+					   SPINOR_REG_CYPRESS_CFR3V, 1),
+			   SPI_MEM_OP_NO_DUMMY,
+			   SPI_MEM_OP_DATA_IN(1, &buf, 1));
+
+	ret = spi_mem_exec_op(nor->spi, &op);
+	if (ret)
+		return ret;
+
+	if (!(buf & SPINOR_REG_CYPRESS_CFR3V_UNISECT))
+		nor->erase = s28hs512t_erase_non_uniform;
+
+	return spi_nor_default_setup(nor, info, params);
+}
+
+static void s28hs512t_default_init(struct spi_nor *nor)
+{
+	nor->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable;
+	nor->setup = s28hs512t_setup;
+}
+
+static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor,
+				      struct spi_nor_flash_parameter *params)
+{
+	/*
+	 * On older versions of the flash the xSPI Profile 1.0 table has the
+	 * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
+	 */
+	if (params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
+		params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
+			SPINOR_OP_CYPRESS_RD_FAST;
+
+	params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
+
+	/* This flash is also missing the 4-byte Page Program opcode bit. */
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
+				SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
+	/*
+	 * Since xSPI Page Program opcode is backward compatible with
+	 * Legacy SPI, use Legacy SPI opcode there as well.
+	 */
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
+				SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
+
+	/*
+	 * The xSPI Profile 1.0 table advertises the number of additional
+	 * address bytes needed for Read Status Register command as 0 but the
+	 * actual value for that is 4.
+	 */
+	params->rdsr_addr_nbytes = 4;
+}
+
+static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor,
+				     const struct sfdp_parameter_header *bfpt_header,
+				     const struct sfdp_bfpt *bfpt,
+				     struct spi_nor_flash_parameter *params)
+{
+	struct spi_mem_op op;
+	u8 buf;
+	u8 addr_width = 3;
+	int ret;
+
+	/*
+	 * The BFPT table advertises a 512B page size but the page size is
+	 * actually configurable (with the default being 256B). Read from
+	 * CFR3V[4] and set the correct size.
+	 */
+	op = (struct spi_mem_op)
+		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
+			   SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3V, 1),
+			   SPI_MEM_OP_NO_DUMMY,
+			   SPI_MEM_OP_DATA_IN(1, &buf, 1));
+	ret = spi_mem_exec_op(nor->spi, &op);
+	if (ret)
+		return ret;
+
+	if (buf & SPINOR_REG_CYPRESS_CFR3V_PGSZ)
+		params->page_size = 512;
+	else
+		params->page_size = 256;
+
+	/*
+	 * The BFPT advertises that it supports 4k erases, and the datasheet
+	 * says the same. But 4k erases did not work when testing. So, use 256k
+	 * erases for now.
+	 */
+	nor->erase_opcode = SPINOR_OP_SE_4B;
+	nor->mtd.erasesize = 0x40000;
+
+	return 0;
+}
+
+static struct spi_nor_fixups s28hs512t_fixups = {
+	.default_init = s28hs512t_default_init,
+	.post_sfdp = s28hs512t_post_sfdp_fixup,
+	.post_bfpt = s28hs512t_post_bfpt_fixup,
+};
+#endif /* CONFIG_SPI_FLASH_S28HS512T */
+
 /** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed
  * @nor:                 pointer to a 'struct spi_nor'
  *
@@ -3108,6 +3291,10 @@ int spi_nor_remove(struct spi_nor *nor)
 
 void spi_nor_set_fixups(struct spi_nor *nor)
 {
+#ifdef CONFIG_SPI_FLASH_S28HS512T
+	if (!strcmp(nor->info->name, "s28hs512t"))
+		nor->fixups = &s28hs512t_fixups;
+#endif
 }
 
 int spi_nor_scan(struct spi_nor *nor)
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 2b57797954..41d7b1dfc0 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -222,6 +222,9 @@ const struct flash_info spi_nor_ids[] = {
 	{ INFO("s25fl208k",  0x014014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
 	{ INFO("s25fl064l",  0x016017,      0,  64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
 	{ INFO("s25fl128l",  0x016018,      0,  64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+#ifdef CONFIG_SPI_FLASH_S28HS512T
+	{ INFO("s28hs512t",  0x345b1a,      0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) },
+#endif
 #endif
 #ifdef CONFIG_SPI_FLASH_SST		/* SST */
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 29ce175156..6ece401b37 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -157,6 +157,19 @@
 /* Status Register 2 bits. */
 #define SR2_QUAD_EN_BIT7	BIT(7)
 
+/* For Cypress flash. */
+#define SPINOR_OP_RD_ANY_REG			0x65	/* Read any register */
+#define SPINOR_OP_WR_ANY_REG			0x71	/* Write any register */
+#define SPINOR_OP_S28_SE_4K			0x21
+#define SPINOR_REG_CYPRESS_CFR2V		0x00800003
+#define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24	0xb
+#define SPINOR_REG_CYPRESS_CFR3V		0x00800004
+#define SPINOR_REG_CYPRESS_CFR3V_PGSZ		BIT(4) /* Page size. */
+#define SPINOR_REG_CYPRESS_CFR3V_UNISECT	BIT(3) /* Uniform sector mode */
+#define SPINOR_REG_CYPRESS_CFR5V		0x00800006
+#define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN	0x3
+#define SPINOR_OP_CYPRESS_RD_FAST		0xee
+
 /* Supported SPI protocols */
 #define SNOR_PROTO_INST_MASK	GENMASK(23, 16)
 #define SNOR_PROTO_INST_SHIFT	16
-- 
2.30.0

  parent reply	other threads:[~2021-04-01 19:31 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-01 19:31 [PATCH v8 00/28] mtd: spi-nor-core: add xSPI Octal DTR support Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 01/28] spi: spi-mem: allow specifying whether an op is DTR or not Pratyush Yadav
2021-04-02 22:21   ` Sean Anderson
2021-04-05  8:25     ` Pratyush Yadav
2021-04-05 11:47       ` Tom Rini
2021-04-05 13:12         ` Sean Anderson
2021-04-05 13:57           ` Pratyush Yadav
2021-04-05 14:58             ` Tom Rini
2021-04-01 19:31 ` [PATCH v8 02/28] spi: spi-mem: allow specifying a command's extension Pratyush Yadav
2021-04-02 22:29   ` Sean Anderson
2021-04-05  8:18     ` Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 03/28] spi: spi-mem: export spi_mem_default_supports_op() Pratyush Yadav
2021-04-02 22:09   ` Sean Anderson
2021-04-01 19:31 ` [PATCH v8 04/28] spi: spi-mem: add spi_mem_dtr_supports_op() Pratyush Yadav
2021-04-02 22:31   ` Sean Anderson
2021-04-05  7:40     ` Pratyush Yadav
2021-04-05 13:16       ` Sean Anderson
2021-04-01 19:31 ` [PATCH v8 05/28] spi: cadence-qspi: Do not calibrate when device tree sets read delay Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 06/28] spi: cadence-qspi: Add a small delay before indirect writes Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 07/28] spi: cadence-qspi: Add support for octal DTR flashes Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 08/28] arm: mvebu: x530: Use tiny SPI NOR Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 09/28] mtd: spi-nor-core: Fix address width on flash chips > 16MB Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 10/28] mtd: spi-nor-core: Add a ->setup() hook Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 11/28] mtd: spi-nor-core: Move SFDP related declarations to top Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 12/28] mtd: spi-nor-core: Introduce flash-specific fixup hooks Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 13/28] mtd: spi-nor-core: Rework hwcaps selection Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 14/28] mtd: spi-nor-core: Do not set data direction when there is no data Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 15/28] mtd: spi-nor-core: Add support for DTR protocol Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 16/28] mtd: spi-nor-core: prepare BFPT parsing for JESD216 rev D Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 17/28] mtd: spi-nor-core: Get command opcode extension type from BFPT Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 18/28] mtd: spi-nor-core: Parse xSPI Profile 1.0 table Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 19/28] mtd: spi-nor-core: Prepare Read SR and FSR for Octal DTR mode Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 20/28] mtd: spi-nor-core: Enable octal DTR mode when possible Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 21/28] mtd: spi-nor-core: Do not make invalid quad enable fatal Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 22/28] mtd: spi-nor-core: Detect Soft Reset sequence support from BFPT Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 23/28] mtd: spi-nor-core: Perform a Soft Reset on shutdown Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 24/28] mtd: spi-nor-core: Perform a Soft Reset on boot Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 25/28] mtd: spi-nor-core: allow truncated erases Pratyush Yadav
2021-04-01 19:31 ` [PATCH v8 26/28] mtd: spi-nor-core: Add non-uniform erase for Spansion/Cypress Pratyush Yadav
2021-04-06  1:48   ` Takahiro Kuwano
2021-04-06 10:46     ` Pratyush Yadav
2021-04-01 19:31 ` Pratyush Yadav [this message]
2021-04-01 19:31 ` [PATCH v8 28/28] mtd: spi-nor-core: Allow using Micron mt35xu512aba in Octal DTR mode Pratyush Yadav
2021-04-02 22:28 ` [PATCH v8 00/28] mtd: spi-nor-core: add xSPI Octal DTR support Sean Anderson
2021-04-05  7:43   ` Pratyush Yadav
2021-04-05 13:17     ` Sean Anderson

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=20210401193133.18129-28-p.yadav@ti.com \
    --to=p.yadav@ti.com \
    --cc=u-boot@lists.denx.de \
    /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.