aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2016-06-20 15:28:36 +0200
committerZoltan HERPAI <wigyori@uid0.hu>2016-06-20 15:28:36 +0200
commit870678baa7f8b9a65945237704d84d7724f42459 (patch)
tree29dba8a076d9e53752b02f768dcdbe15fa9271cd /target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch
parent8864b97350bde1fffe614df3c0bfc0cb34fb40d4 (diff)
downloadmaster-187ad058-870678baa7f8b9a65945237704d84d7724f42459.tar.gz
master-187ad058-870678baa7f8b9a65945237704d84d7724f42459.tar.bz2
master-187ad058-870678baa7f8b9a65945237704d84d7724f42459.zip
target: socfpga: Add support for QSPI NOR boot
Add necessary kernel backports to support the Cadence QSPI controller present on the Altera SoCFPGA SoC. Signed-off-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch')
-rw-r--r--target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch264
1 files changed, 264 insertions, 0 deletions
diff --git a/target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch b/target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch
new file mode 100644
index 0000000000..7153a9f171
--- /dev/null
+++ b/target/linux/socfpga/patches-4.4/0023-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch
@@ -0,0 +1,264 @@
+From 16410a33d6655d6c85c8c522bc6f2cfebf7c06a4 Mon Sep 17 00:00:00 2001
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Date: Fri, 8 Jan 2016 17:02:20 +0100
+Subject: [PATCH 23/33] mtd: spi-nor: configure the number of dummy clock
+ cycles by manufacturer
+
+This is a transitional patch which let us set the number of dummy clock
+cycles by manufacturer.
+
+More patches will follow by manufacturer to actually configure the
+relevant number of dummy clock cycles following the dedicated procedure.
+
+For instance, some manufacturers like Spansion configure the number of
+dummy clock cycles to be used by Fast Read command through some
+non-volatile register. In such a case, we should avoid updating its value
+but instead read it then set the nor->read_dummy accordingly.
+
+On the other hand, some manufacturers like Micron use some volatile
+register. In this case, we'd rather update this register to use a number
+of dummy clock cycles, which is a multiple of 8.
+Indeed some drivers, like m25p80, only support writing bytes, hence
+multiples of 8 bits.
+
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 99 ++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 74 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
+index 8a042ab..ae3e9d8 100644
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -139,24 +139,6 @@ static int read_cr(struct spi_nor *nor)
+ }
+
+ /*
+- * Dummy Cycle calculation for different type of read.
+- * It can be used to support more commands with
+- * different dummy cycle requirements.
+- */
+-static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
+-{
+- switch (nor->flash_read) {
+- case SPI_NOR_FAST:
+- case SPI_NOR_DUAL:
+- case SPI_NOR_QUAD:
+- return 8;
+- case SPI_NOR_NORMAL:
+- return 0;
+- }
+- return 0;
+-}
+-
+-/*
+ * Write status register 1 byte
+ * Returns negative if error occurred.
+ */
+@@ -1217,6 +1199,7 @@ static int macronix_set_quad_mode(struct spi_nor *nor)
+ * read (performance enhance) mode by mistake!
+ */
+ nor->read_opcode = SPINOR_OP_READ_1_4_4;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+@@ -1238,6 +1221,7 @@ static int macronix_set_quad_mode(struct spi_nor *nor)
+ }
+ nor->read_proto = SNOR_PROTO_1_1_4;
+ nor->read_opcode = SPINOR_OP_READ_1_1_4;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+@@ -1251,12 +1235,27 @@ 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;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+ static int macronix_set_single_mode(struct spi_nor *nor)
+ {
++ u8 read_dummy;
++
++ switch (nor->read_opcode) {
++ case SPINOR_OP_READ:
++ case SPINOR_OP_READ4:
++ read_dummy = 0;
++ break;
++
++ default:
++ read_dummy = 8;
++ break;
++ }
++
+ nor->read_proto = SNOR_PROTO_1_1_1;
++ nor->read_dummy = read_dummy;
+ return 0;
+ }
+
+@@ -1277,6 +1276,7 @@ static int winbond_set_quad_mode(struct spi_nor *nor)
+ * Hence the Fast Read 1-1-1 (0x0b) op code is chosen.
+ */
+ nor->read_opcode = SPINOR_OP_READ_FAST;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+@@ -1295,6 +1295,7 @@ static int winbond_set_quad_mode(struct spi_nor *nor)
+ }
+ nor->read_proto = SNOR_PROTO_1_1_4;
+ nor->read_opcode = SPINOR_OP_READ_1_1_4;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+@@ -1308,12 +1309,27 @@ static int winbond_set_dual_mode(struct spi_nor *nor)
+ {
+ nor->read_proto = SNOR_PROTO_1_1_2;
+ nor->read_opcode = SPINOR_OP_READ_1_1_2;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+ static int winbond_set_single_mode(struct spi_nor *nor)
+ {
++ u8 read_dummy;
++
++ switch (nor->read_opcode) {
++ case SPINOR_OP_READ:
++ case SPINOR_OP_READ4:
++ read_dummy = 0;
++ break;
++
++ default:
++ read_dummy = 8;
++ break;
++ }
++
+ nor->read_proto = SNOR_PROTO_1_1_1;
++ nor->read_dummy = read_dummy;
+ return 0;
+ }
+
+@@ -1405,6 +1421,7 @@ static int micron_set_quad_mode(struct spi_nor *nor)
+ if (nor->read_proto != SNOR_PROTO_4_4_4)
+ nor->read_proto = SNOR_PROTO_1_1_4;
+ nor->read_opcode = SPINOR_OP_READ_1_1_4;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+@@ -1434,11 +1451,14 @@ static int micron_set_dual_mode(struct spi_nor *nor)
+ if (nor->read_proto != SNOR_PROTO_2_2_2)
+ nor->read_proto = SNOR_PROTO_1_1_2;
+ nor->read_opcode = SPINOR_OP_READ_1_1_2;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+ static int micron_set_single_mode(struct spi_nor *nor)
+ {
++ u8 read_dummy;
++
+ /* Check whether either the Dual or Quad mode is enabled. */
+ if (unlikely(nor->read_proto != SNOR_PROTO_1_1_1)) {
+ int ret;
+@@ -1455,6 +1475,18 @@ static int micron_set_single_mode(struct spi_nor *nor)
+ nor->read_proto = SNOR_PROTO_1_1_1;
+ }
+
++ /* Force the number of dummy cycles to 8 for Fast Read, 0 for Read. */
++ switch (nor->read_opcode) {
++ case SPINOR_OP_READ:
++ case SPINOR_OP_READ4:
++ read_dummy = 0;
++ break;
++
++ default:
++ read_dummy = 8;
++ break;
++ }
++ nor->read_dummy = read_dummy;
+ return 0;
+ }
+
+@@ -1469,6 +1501,7 @@ static int spansion_set_quad_mode(struct spi_nor *nor)
+ }
+ nor->read_proto = SNOR_PROTO_1_1_4;
+ nor->read_opcode = SPINOR_OP_READ_1_1_4;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+@@ -1476,12 +1509,27 @@ static int spansion_set_dual_mode(struct spi_nor *nor)
+ {
+ nor->read_proto = SNOR_PROTO_1_1_2;
+ nor->read_opcode = SPINOR_OP_READ_1_1_2;
++ nor->read_dummy = 8;
+ return 0;
+ }
+
+ static int spansion_set_single_mode(struct spi_nor *nor)
+ {
++ u8 read_dummy;
++
++ switch (nor->read_opcode) {
++ case SPINOR_OP_READ:
++ case SPINOR_OP_READ4:
++ read_dummy = 0;
++ break;
++
++ default:
++ read_dummy = 8;
++ break;
++ }
++
+ nor->read_proto = SNOR_PROTO_1_1_1;
++ nor->read_dummy = read_dummy;
+ return 0;
+ }
+
+@@ -1696,11 +1744,14 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+ if (info->flags & SPI_NOR_NO_FR)
+ nor->flash_read = SPI_NOR_NORMAL;
+
+- /* Default commands */
+- if (nor->flash_read == SPI_NOR_NORMAL)
++ /* Default commands and number of dummy cycles */
++ if (nor->flash_read == SPI_NOR_NORMAL) {
+ nor->read_opcode = SPINOR_OP_READ;
+- else
++ nor->read_dummy = 0;
++ } else {
+ nor->read_opcode = SPINOR_OP_READ_FAST;
++ nor->read_dummy = 8;
++ }
+
+ nor->program_opcode = SPINOR_OP_PP;
+
+@@ -1715,8 +1766,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+ * - SNOR_PROTO_2_2_2 is either:
+ * + Micron Dual mode enabled
+ *
+- * The opcodes and the protocols are updated depending on the
+- * manufacturer.
++ * The opcodes, the protocols and the number of dummy cycles are updated
++ * depending on the manufacturer.
+ * The read opcode and protocol should be updated by the relevant
+ * function when entering Quad or Dual mode.
+ */
+@@ -1780,8 +1831,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+ return -EINVAL;
+ }
+
+- nor->read_dummy = spi_nor_read_dummy_cycles(nor);
+-
+ dev_info(dev, "%s (%lld Kbytes)\n", info->name,
+ (long long)mtd->size >> 10);
+
+--
+2.8.1
+