1afc405f7759e8a8f5823d4a3c21f46926368be2
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.4 / 1105-mtd-spi-nor-add-DDR-quad-read-support.patch
1 From 924f021c0344554a4b61746e5c4dcfc91d618ce2 Mon Sep 17 00:00:00 2001
2 From: Yunhui Cui <yunhui.cui@nxp.com>
3 Date: Thu, 18 Feb 2016 16:41:53 +0800
4 Subject: [PATCH 105/113] mtd: spi-nor: add DDR quad read support
5
6 This patch adds the DDR quad read support by the following:
7
8 [1] add SPI_NOR_DDR_QUAD read mode.
9
10 [2] add DDR Quad read opcodes:
11 SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
12
13 [3] add set_ddr_quad_mode() to initialize for the DDR quad read.
14 Currently it only works for Spansion NOR.
15
16 [4] set dummy with 6 for Spansion family
17 Test this patch for Spansion s25fl128s NOR flash.
18
19 Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
20 ---
21 drivers/mtd/spi-nor/spi-nor.c | 53 ++++++++++++++++++++++++++++++++++++-----
22 include/linux/mtd/spi-nor.h | 8 +++++--
23 2 files changed, 53 insertions(+), 8 deletions(-)
24
25 --- a/drivers/mtd/spi-nor/spi-nor.c
26 +++ b/drivers/mtd/spi-nor/spi-nor.c
27 @@ -73,7 +73,8 @@ struct flash_info {
28 #define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */
29 #define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */
30 #define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */
31 -#define USE_FSR 0x80 /* use flag status register */
32 +#define SPI_NOR_DDR_QUAD_READ 0x80 /* Flash supports DDR Quad Read */
33 +#define USE_FSR 0x100 /* use flag status register */
34 };
35
36 #define JEDEC_MFR(info) ((info)->id[0])
37 @@ -144,13 +145,17 @@ static int read_cr(struct spi_nor *nor)
38 * It can be used to support more commands with
39 * different dummy cycle requirements.
40 */
41 -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
42 +static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor,
43 + const struct flash_info *info)
44 {
45 switch (nor->flash_read) {
46 case SPI_NOR_FAST:
47 case SPI_NOR_DUAL:
48 case SPI_NOR_QUAD:
49 return 8;
50 + case SPI_NOR_DDR_QUAD:
51 + if (JEDEC_MFR(info) == SNOR_MFR_SPANSION)
52 + return 6;
53 case SPI_NOR_NORMAL:
54 return 0;
55 }
56 @@ -798,7 +803,8 @@ static const struct flash_info spi_nor_i
57 { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
58 { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
59 { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
60 - { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
61 + { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ
62 + | SPI_NOR_DDR_QUAD_READ) },
63 { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
64 { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
65 { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
66 @@ -1187,6 +1193,23 @@ static int spansion_quad_enable(struct s
67 return 0;
68 }
69
70 +static int set_ddr_quad_mode(struct spi_nor *nor, const struct flash_info *info)
71 +{
72 + int status;
73 +
74 + switch (JEDEC_MFR(info)) {
75 + case SNOR_MFR_SPANSION:
76 + status = spansion_quad_enable(nor);
77 + if (status) {
78 + dev_err(nor->dev, "Spansion DDR quad-read not enabled\n");
79 + return status;
80 + }
81 + return status;
82 + default:
83 + return -EINVAL;
84 + }
85 +}
86 +
87 static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
88 {
89 int status;
90 @@ -1376,8 +1399,15 @@ int spi_nor_scan(struct spi_nor *nor, co
91 if (info->flags & SPI_NOR_NO_FR)
92 nor->flash_read = SPI_NOR_NORMAL;
93
94 - /* Quad/Dual-read mode takes precedence over fast/normal */
95 - if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
96 + /* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */
97 + if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) {
98 + ret = set_ddr_quad_mode(nor, info);
99 + if (ret) {
100 + dev_err(dev, "DDR quad mode not supported\n");
101 + return ret;
102 + }
103 + nor->flash_read = SPI_NOR_DDR_QUAD;
104 + } else if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
105 ret = set_quad_mode(nor, info);
106 if (ret) {
107 dev_err(dev, "quad mode not supported\n");
108 @@ -1390,6 +1420,14 @@ int spi_nor_scan(struct spi_nor *nor, co
109
110 /* Default commands */
111 switch (nor->flash_read) {
112 + case SPI_NOR_DDR_QUAD:
113 + if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) { /* Spansion */
114 + nor->read_opcode = SPINOR_OP_READ_1_4_4_D;
115 + } else {
116 + dev_err(dev, "DDR Quad Read is not supported.\n");
117 + return -EINVAL;
118 + }
119 + break;
120 case SPI_NOR_QUAD:
121 nor->read_opcode = SPINOR_OP_READ_1_1_4;
122 break;
123 @@ -1417,6 +1455,9 @@ int spi_nor_scan(struct spi_nor *nor, co
124 if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) {
125 /* Dedicated 4-byte command set */
126 switch (nor->flash_read) {
127 + case SPI_NOR_DDR_QUAD:
128 + nor->read_opcode = SPINOR_OP_READ4_1_4_4_D;
129 + break;
130 case SPI_NOR_QUAD:
131 nor->read_opcode = SPINOR_OP_READ4_1_1_4;
132 break;
133 @@ -1446,7 +1487,7 @@ int spi_nor_scan(struct spi_nor *nor, co
134 return -EINVAL;
135 }
136
137 - nor->read_dummy = spi_nor_read_dummy_cycles(nor);
138 + nor->read_dummy = spi_nor_read_dummy_cycles(nor, info);
139
140 dev_info(dev, "%s (%lld Kbytes)\n", info->name,
141 (long long)mtd->size >> 10);
142 --- a/include/linux/mtd/spi-nor.h
143 +++ b/include/linux/mtd/spi-nor.h
144 @@ -30,10 +30,11 @@
145
146 /*
147 * Note on opcode nomenclature: some opcodes have a format like
148 - * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
149 + * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. The numbers x, y,and z stand for the number
150 * of I/O lines used for the opcode, address, and data (respectively). The
151 * FUNCTION has an optional suffix of '4', to represent an opcode which
152 - * requires a 4-byte (32-bit) address.
153 + * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the
154 + * DDR mode.
155 */
156
157 /* Flash opcodes. */
158 @@ -44,6 +45,7 @@
159 #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
160 #define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */
161 #define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */
162 +#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */
163 #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
164 #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */
165 #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
166 @@ -59,6 +61,7 @@
167 #define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
168 #define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */
169 #define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
170 +#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */
171 #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
172 #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */
173
174 @@ -107,6 +110,7 @@ enum read_mode {
175 SPI_NOR_FAST,
176 SPI_NOR_DUAL,
177 SPI_NOR_QUAD,
178 + SPI_NOR_DDR_QUAD,
179 };
180
181 #define SPI_NOR_MAX_CMD_SIZE 8