From: Alexander Stein <alexander.stein@ew.tq-group.com>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
Richard Weinberger <richard@nod.at>,
Vignesh Raghavendra <vigneshr@ti.com>,
Rob Herring <robh+dt@kernel.org>, Pratyush Yadav <p.yadav@ti.com>,
Michael Walle <michael@walle.cc>,
Tudor Ambarus <tudor.ambarus@microchip.com>
Cc: Alexander Stein <alexander.stein@ew.tq-group.com>,
linux-mtd@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 2/2] mtd: spi-nor: micron-st: Add support for output-driver-strength for MT25Q
Date: Tue, 12 Oct 2021 08:17:04 +0200 [thread overview]
Message-ID: <20211012061704.284214-2-alexander.stein@ew.tq-group.com> (raw)
In-Reply-To: <20211012061704.284214-1-alexander.stein@ew.tq-group.com>
MT25Q[UL] Micron flashes support this by the Bits [2:0] in the Enhanced
Volatile Configuration Register.
Checked datasheet:
- mt25t-qljs-L512-xBA-xxT.pdf
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
Changes in v2:
* Various format fixes
* Apply property only to MT25Q devices (e.g. N25Q devices support a
different set of impedances)
* Use spi_nor_spimem_setup_op() before issuing a command
* Add more return code checking
* Add a warning if setting drive strength fails at some point
* Use GENMASK()
drivers/mtd/spi-nor/micron-st.c | 152 ++++++++++++++++++++++++++++++--
1 file changed, 146 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index c224e59820a1..492805a5a278 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -16,6 +16,11 @@
#define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR. */
#define SPINOR_MT_EXSPI 0xff /* Enable Extended SPI (default) */
+struct micron_drive_strength {
+ u32 ohms;
+ u8 val;
+};
+
static int spi_nor_micron_octal_dtr_enable(struct spi_nor *nor, bool enable)
{
struct spi_mem_op op;
@@ -118,6 +123,135 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
.post_sfdp = mt35xu512aba_post_sfdp_fixup,
};
+/*
+ * Read Micron enhanced volatile configuration register
+ * Return negative if error occurred or configuration register value
+ */
+static int micron_read_evcr(struct spi_nor *nor)
+{
+ int ret;
+
+ if (nor->spimem) {
+ struct spi_mem_op op =
+ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_EVCR, 1),
+ SPI_MEM_OP_NO_ADDR,
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+
+ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+ ret = spi_mem_exec_op(nor->spimem, &op);
+ } else {
+ ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RD_EVCR,
+ nor->bouncebuf, 1);
+ }
+
+ if (ret < 0) {
+ dev_err(nor->dev, "error %d reading EVCR\n", ret);
+ return ret;
+ }
+
+ return nor->bouncebuf[0];
+}
+
+/*
+ * Write Micron enhanced volatile configuration register
+ * Return negative if error occurred or configuration register value
+ */
+static int micron_write_evcr(struct spi_nor *nor, u8 evcr)
+{
+ int ret;
+
+ nor->bouncebuf[0] = evcr;
+
+ ret = spi_nor_write_enable(nor);
+ if (ret)
+ return ret;
+
+ if (nor->spimem) {
+ struct spi_mem_op op =
+ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WD_EVCR, 1),
+ SPI_MEM_OP_NO_ADDR,
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));
+
+ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+ return spi_mem_exec_op(nor->spimem, &op);
+ }
+
+ return nor->controller_ops->write_reg(nor, SPINOR_OP_WD_EVCR,
+ nor->bouncebuf, 1);
+}
+
+/*
+ * Supported values from Enahanced Volatile COnfiguration Register (Bits 2:0)
+ */
+static const struct micron_drive_strength drive_strength_data[] = {
+ { .ohms = 90, .val = 1 },
+ { .ohms = 45, .val = 3 },
+ { .ohms = 20, .val = 5 },
+ { .ohms = 30, .val = 7 },
+};
+
+static const struct micron_drive_strength *micron_st_find_drive_strength_entry(u32 ohms)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(drive_strength_data); i++) {
+ if (ohms == drive_strength_data[i].ohms)
+ return &drive_strength_data[i];
+ }
+ return NULL;
+}
+
+static void mt25q_post_sfdp(struct spi_nor *nor)
+{
+ struct device_node *np = spi_nor_get_flash_node(nor);
+ u32 ohms;
+
+ if (!np)
+ return;
+
+ if (!of_property_read_u32(np, "output-driver-strength", &ohms)) {
+ struct micron_drive_strength const *entry =
+ micron_st_find_drive_strength_entry(ohms);
+
+ if (entry) {
+ int evcrr;
+ int ret;
+ u8 evcr;
+
+ evcrr = micron_read_evcr(nor);
+ if (evcrr < 0) {
+ dev_warn(nor->dev,
+ "Reading EVCR failed: %d\n",
+ evcrr);
+ return;
+ }
+
+ evcr = (u8)(evcrr & GENMASK(7, 3)) | entry->val;
+
+ ret = micron_write_evcr(nor, evcr);
+ if (ret)
+ dev_warn(nor->dev,
+ "Setting EVCR failed: %d\n",
+ ret);
+
+ dev_dbg(nor->dev, "%s: EVCR 0x%x\n", __func__,
+ (u32)micron_read_evcr(nor));
+ } else {
+ dev_warn(nor->dev,
+ "Invalid output-driver-strength property specified: %u",
+ ohms);
+ }
+ }
+}
+
+static struct spi_nor_fixups mt25q_fixups = {
+ .post_sfdp = mt25q_post_sfdp,
+};
+
static const struct flash_info micron_parts[] = {
{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
@@ -149,25 +283,29 @@ static const struct flash_info st_parts[] = {
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "mt25ql256a", INFO6(0x20ba19, 0x104400, 64 * 1024, 512,
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES)
+ .fixups = &mt25q_fixups },
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K |
USE_FSR | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512,
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES)
+ .fixups = &mt25q_fixups },
{ "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "mt25ql512a", INFO6(0x20ba20, 0x104400, 64 * 1024, 1024,
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES)
+ .fixups = &mt25q_fixups },
{ "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
{ "mt25qu512a", INFO6(0x20bb20, 0x104400, 64 * 1024, 1024,
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES)
+ .fixups = &mt25q_fixups },
{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
@@ -182,10 +320,12 @@ static const struct flash_info st_parts[] = {
NO_CHIP_ERASE) },
{ "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
- NO_CHIP_ERASE) },
+ NO_CHIP_ERASE)
+ .fixups = &mt25q_fixups },
{ "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096,
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
- SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
+ SPI_NOR_QUAD_READ | NO_CHIP_ERASE)
+ .fixups = &mt25q_fixups },
{ "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) },
{ "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) },
--
2.25.1
next prev parent reply other threads:[~2021-10-12 6:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-12 6:17 [PATCH v2 1/2] dt-bindings: mtd: spi-nor: Add output-driver-strength property Alexander Stein
2021-10-12 6:17 ` Alexander Stein [this message]
2021-10-12 7:48 ` Michael Walle
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=20211012061704.284214-2-alexander.stein@ew.tq-group.com \
--to=alexander.stein@ew.tq-group.com \
--cc=devicetree@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=michael@walle.cc \
--cc=miquel.raynal@bootlin.com \
--cc=p.yadav@ti.com \
--cc=richard@nod.at \
--cc=robh+dt@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®