[PATCH v3 09/12] mtd: spi-nor: enable octal DTR mode when possible

From: Pratyush Yadav
Date: Fri Mar 13 2020 - 11:47:47 EST


Allow flashes to specify a hook to enable octal DTR mode. Use this hook
whenever possible to get optimal transfer speeds.

Signed-off-by: Pratyush Yadav <p.yadav@xxxxxx>
---
drivers/mtd/spi-nor/spi-nor.c | 35 +++++++++++++++++++++++++++++++++++
include/linux/mtd/spi-nor.h | 2 ++
2 files changed, 37 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 16d7516f2470..5e225d1b29f7 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -5232,6 +5232,35 @@ static void spi_nor_init_params(struct spi_nor *nor)
spi_nor_late_init_params(nor);
}

+/** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed
+ * @nor: pointer to a 'struct spi_nor'
+ * @enable: whether to enable or disable Octal DTR
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
+{
+ int ret;
+
+ if (!nor->params.octal_dtr_enable)
+ return 0;
+
+ if (!(spi_nor_get_protocol_width(nor->read_proto) == 8 ||
+ spi_nor_get_protocol_width(nor->write_proto) == 8))
+ return 0;
+
+ ret = nor->params.octal_dtr_enable(nor, enable);
+ if (ret)
+ return ret;
+
+ if (enable)
+ nor->reg_proto = SNOR_PROTO_8_8_8_DTR;
+ else
+ nor->reg_proto = SNOR_PROTO_1_1_1;
+
+ return 0;
+}
+
/**
* spi_nor_quad_enable() - enable Quad I/O if needed.
* @nor: pointer to a 'struct spi_nor'
@@ -5271,6 +5300,12 @@ static int spi_nor_init(struct spi_nor *nor)
{
int err;

+ err = spi_nor_octal_dtr_enable(nor, true);
+ if (err) {
+ dev_dbg(nor->dev, "octal mode not supported\n");
+ return err;
+ }
+
err = spi_nor_quad_enable(nor);
if (err) {
dev_dbg(nor->dev, "quad mode not supported\n");
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f1db613e0320..923bd34ced84 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -544,6 +544,7 @@ struct spi_nor_locking_ops {
* higher index in the array, the higher priority.
* @erase_map: the erase map parsed from the SFDP Sector Map Parameter
* Table.
+ * @octal_dtr_enable: enables SPI NOR octal DTR mode.
* @quad_enable: enables SPI NOR quad mode.
* @set_4byte: puts the SPI NOR in 4 byte addressing mode.
* @convert_addr: converts an absolute address into something the flash
@@ -567,6 +568,7 @@ struct spi_nor_flash_parameter {

struct spi_nor_erase_map erase_map;

+ int (*octal_dtr_enable)(struct spi_nor *nor, bool enable);
int (*quad_enable)(struct spi_nor *nor);
int (*set_4byte)(struct spi_nor *nor, bool enable);
u32 (*convert_addr)(struct spi_nor *nor, u32 addr);
--
2.25.0