aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch')
-rw-r--r--target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch139
1 files changed, 139 insertions, 0 deletions
diff --git a/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch b/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch
new file mode 100644
index 0000000000..087b6715d0
--- /dev/null
+++ b/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch
@@ -0,0 +1,139 @@
+From 4e094634d1995e279f8bc5eb92463295cb894c76 Mon Sep 17 00:00:00 2001
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Date: Fri, 8 Jan 2016 17:02:16 +0100
+Subject: [PATCH 19/33] mtd: spi-nor: fix support of Macronix memories
+
+This patch fixes the support of Macronix memories. Especially we avoid
+updating the Status Register when not needed as the Quad Enable (QE) bit
+is a non-volatile bit.
+
+Also we add comments to explain why we use some Fast Read op codes rather
+than others.
+
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 81 ++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 72 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
+index 889af12..1b1f5a6 100644
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -1107,6 +1107,11 @@ static int macronix_quad_enable(struct spi_nor *nor)
+ val = read_sr(nor);
+ if (val < 0)
+ return val;
++
++ if (likely(val & SR_QUAD_EN_MX))
++ return 0;
++ dev_warn(nor->dev, "Macronix Quad mode disabled, enable it\n");
++
+ write_enable(nor);
+
+ write_sr(nor, val | SR_QUAD_EN_MX);
+@@ -1161,21 +1166,73 @@ static int spansion_quad_enable(struct spi_nor *nor)
+ return 0;
+ }
+
++static int macronix_set_quad_mode(struct spi_nor *nor)
++{
++ int status;
++
++ /* Check whether the QPI mode is enabled. */
++ if (nor->read_proto == SNOR_PROTO_4_4_4) {
++ /*
++ * Since the QPI mode is enabled, the Quad Enabled (QE)
++ * non-volatile bit is already set.
++ * However in QPI mode, only the Fast Read 1-4-4 (0xeb)
++ * op code is supported.
++ * WARNING: we should take care about the performance
++ * enhance toggling bits P0-P7 written during the
++ * dummy/mode cycles to avoid entering the continuous
++ * read (performance enhance) mode by mistake!
++ */
++ nor->read_opcode = SPINOR_OP_READ_1_4_4;
++ return 0;
++ }
++
++ /*
++ * The QPI mode is disabled but we still need to set the QE bit:
++ * this disables the reset and write protect features and
++ * frees the associated pins so they can be used as the 3rd
++ * and 4th I/O lines required by Quad SPI commands.
++ * Also we'd rather use the Fast Read 1-1-4 (0x6b) op code than
++ * the Fast Read 1-4-4 (0xeb) op code so we don't care about
++ * entering the continuous read mode by mistake if some
++ * performance enhance toggling bits P0-P7 were written during
++ * dummy/mode cycles.
++ */
++ status = macronix_quad_enable(nor);
++ if (status) {
++ dev_err(nor->dev, "Macronix quad-read not enabled\n");
++ return status;
++ }
++ nor->read_proto = SNOR_PROTO_1_1_4;
++ nor->read_opcode = SPINOR_OP_READ_1_1_4;
++ return 0;
++}
++
++/*
++ * For both Macronix Dual and Single modes, we don't care about the value of
++ * the Quad Enabled (QE) bit since the memory still replies to Dual or Single
++ * SPI commands.
++ */
++
++static int macronix_set_dual_mode(struct spi_nor *nor)
++{
++ nor->read_proto = SNOR_PROTO_1_1_2;
++ nor->read_opcode = SPINOR_OP_READ_1_1_2;
++ return 0;
++}
++
++static int macronix_set_single_mode(struct spi_nor *nor)
++{
++ nor->read_proto = SNOR_PROTO_1_1_1;
++ return 0;
++}
++
+ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
+ {
+ int status;
+
+ switch (JEDEC_MFR(info)) {
+ case SNOR_MFR_MACRONIX:
+- status = macronix_quad_enable(nor);
+- if (status) {
+- dev_err(nor->dev, "Macronix quad-read not enabled\n");
+- return -EINVAL;
+- }
+- /* Check whether Macronix QPI mode is enabled. */
+- if (nor->read_proto != SNOR_PROTO_4_4_4)
+- nor->read_proto = SNOR_PROTO_1_1_4;
+- break;
++ return macronix_set_quad_mode(nor);
+
+ case SNOR_MFR_MICRON:
+ /* Check whether Micron Quad mode is enabled. */
+@@ -1203,6 +1260,9 @@ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
+ static int set_dual_mode(struct spi_nor *nor, const struct flash_info *info)
+ {
+ switch (JEDEC_MFR(info)) {
++ case SNOR_MFR_MACRONIX:
++ return macronix_set_dual_mode(nor);
++
+ case SNOR_MFR_MICRON:
+ /* Check whether Micron Dual mode is enabled. */
+ if (nor->read_proto != SNOR_PROTO_2_2_2)
+@@ -1221,6 +1281,9 @@ static int set_dual_mode(struct spi_nor *nor, const struct flash_info *info)
+ static int set_single_mode(struct spi_nor *nor, const struct flash_info *info)
+ {
+ switch (JEDEC_MFR(info)) {
++ case SNOR_MFR_MACRONIX:
++ return macronix_set_single_mode(nor);
++
+ default:
+ nor->read_proto = SNOR_PROTO_1_1_1;
+ break;
+--
+2.8.1
+