aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSourav Poddar <sourav.poddar@ti.com>2013-11-06 09:35:35 -0500
committerBrian Norris <computersforpeace@gmail.com>2014-01-03 14:22:07 -0500
commit3487a63955c34ea508bcf4ca5131ddd953876e2d (patch)
treecc97a964acf1ef342cad455250784e624d87bfc6
parent8552b439aba7f32063755d23f79ca27b4d0a3115 (diff)
drivers: mtd: m25p80: add quad read support
Some flash also support quad read mode. Adding support for quad read mode in m25p80 for Spansion and Macronix flash. [Tweaked by Brian] With this patch, quad-read support will override fast-read and normal-read, if the SPI controller and flash chip both support it. Signed-off-by: Sourav Poddar <sourav.poddar@ti.com> Tested-by: Sourav Poddar <sourav.poddar@ti.com> Reviewed-by: Marek Vasut <marex@denx.de> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/devices/m25p80.c139
1 files changed, 137 insertions, 2 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 04f8a245ffef..7dc2c147720a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -41,6 +41,7 @@
41#define OPCODE_WRSR 0x01 /* Write status register 1 byte */ 41#define OPCODE_WRSR 0x01 /* Write status register 1 byte */
42#define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ 42#define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */
43#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ 43#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
44#define OPCODE_QUAD_READ 0x6b /* Read data bytes */
44#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ 45#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
45#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ 46#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
46#define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ 47#define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
@@ -48,10 +49,12 @@
48#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ 49#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
49#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ 50#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
50#define OPCODE_RDID 0x9f /* Read JEDEC ID */ 51#define OPCODE_RDID 0x9f /* Read JEDEC ID */
52#define OPCODE_RDCR 0x35 /* Read configuration register */
51 53
52/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ 54/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
53#define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */ 55#define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */
54#define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */ 56#define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */
57#define OPCODE_QUAD_READ_4B 0x6c /* Read data bytes */
55#define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */ 58#define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */
56#define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */ 59#define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */
57 60
@@ -76,6 +79,11 @@
76#define SR_BP2 0x10 /* Block protect 2 */ 79#define SR_BP2 0x10 /* Block protect 2 */
77#define SR_SRWD 0x80 /* SR write protect */ 80#define SR_SRWD 0x80 /* SR write protect */
78 81
82#define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */
83
84/* Configuration Register bits. */
85#define CR_QUAD_EN_SPAN 0x2 /* Spansion Quad I/O */
86
79/* Define max times to check status register before we give up. */ 87/* Define max times to check status register before we give up. */
80#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ 88#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
81#define MAX_CMD_SIZE 6 89#define MAX_CMD_SIZE 6
@@ -87,6 +95,7 @@
87enum read_type { 95enum read_type {
88 M25P80_NORMAL = 0, 96 M25P80_NORMAL = 0,
89 M25P80_FAST, 97 M25P80_FAST,
98 M25P80_QUAD,
90}; 99};
91 100
92struct m25p { 101struct m25p {
@@ -136,6 +145,26 @@ static int read_sr(struct m25p *flash)
136} 145}
137 146
138/* 147/*
148 * Read configuration register, returning its value in the
149 * location. Return the configuration register value.
150 * Returns negative if error occured.
151 */
152static int read_cr(struct m25p *flash)
153{
154 u8 code = OPCODE_RDCR;
155 int ret;
156 u8 val;
157
158 ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
159 if (ret < 0) {
160 dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
161 return ret;
162 }
163
164 return val;
165}
166
167/*
139 * Write status register 1 byte 168 * Write status register 1 byte
140 * Returns negative if error occurred. 169 * Returns negative if error occurred.
141 */ 170 */
@@ -225,6 +254,93 @@ static int wait_till_ready(struct m25p *flash)
225} 254}
226 255
227/* 256/*
257 * Write status Register and configuration register with 2 bytes
258 * The first byte will be written to the status register, while the
259 * second byte will be written to the configuration register.
260 * Return negative if error occured.
261 */
262static int write_sr_cr(struct m25p *flash, u16 val)
263{
264 flash->command[0] = OPCODE_WRSR;
265 flash->command[1] = val & 0xff;
266 flash->command[2] = (val >> 8);
267
268 return spi_write(flash->spi, flash->command, 3);
269}
270
271static int macronix_quad_enable(struct m25p *flash)
272{
273 int ret, val;
274 u8 cmd[2];
275 cmd[0] = OPCODE_WRSR;
276
277 val = read_sr(flash);
278 cmd[1] = val | SR_QUAD_EN_MX;
279 write_enable(flash);
280
281 spi_write(flash->spi, &cmd, 2);
282
283 if (wait_till_ready(flash))
284 return 1;
285
286 ret = read_sr(flash);
287 if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
288 dev_err(&flash->spi->dev, "Macronix Quad bit not set\n");
289 return -EINVAL;
290 }
291
292 return 0;
293}
294
295static int spansion_quad_enable(struct m25p *flash)
296{
297 int ret;
298 int quad_en = CR_QUAD_EN_SPAN << 8;
299
300 write_enable(flash);
301
302 ret = write_sr_cr(flash, quad_en);
303 if (ret < 0) {
304 dev_err(&flash->spi->dev,
305 "error while writing configuration register\n");
306 return -EINVAL;
307 }
308
309 /* read back and check it */
310 ret = read_cr(flash);
311 if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
312 dev_err(&flash->spi->dev, "Spansion Quad bit not set\n");
313 return -EINVAL;
314 }
315
316 return 0;
317}
318
319static int set_quad_mode(struct m25p *flash, u32 jedec_id)
320{
321 int status;
322
323 switch (JEDEC_MFR(jedec_id)) {
324 case CFI_MFR_MACRONIX:
325 status = macronix_quad_enable(flash);
326 if (status) {
327 dev_err(&flash->spi->dev,
328 "Macronix quad-read not enabled\n");
329 return -EINVAL;
330 }
331 return status;
332 default:
333 status = spansion_quad_enable(flash);
334 if (status) {
335 dev_err(&flash->spi->dev,
336 "Spansion quad-read not enabled\n");
337 return -EINVAL;
338 }
339 return status;
340 }
341}
342
343/*
228 * Erase the whole flash memory 344 * Erase the whole flash memory
229 * 345 *
230 * Returns 0 if successful, non-zero otherwise. 346 * Returns 0 if successful, non-zero otherwise.
@@ -363,6 +479,7 @@ static inline int m25p80_dummy_cycles_read(struct m25p *flash)
363{ 479{
364 switch (flash->flash_read) { 480 switch (flash->flash_read) {
365 case M25P80_FAST: 481 case M25P80_FAST:
482 case M25P80_QUAD:
366 return 1; 483 return 1;
367 case M25P80_NORMAL: 484 case M25P80_NORMAL:
368 return 0; 485 return 0;
@@ -727,6 +844,7 @@ struct flash_info {
727#define SST_WRITE 0x04 /* use SST byte programming */ 844#define SST_WRITE 0x04 /* use SST byte programming */
728#define M25P_NO_FR 0x08 /* Can't do fastread */ 845#define M25P_NO_FR 0x08 /* Can't do fastread */
729#define SECT_4K_PMC 0x10 /* OPCODE_BE_4K_PMC works uniformly */ 846#define SECT_4K_PMC 0x10 /* OPCODE_BE_4K_PMC works uniformly */
847#define M25P80_QUAD_READ 0x20 /* Flash supports Quad Read */
730}; 848};
731 849
732#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ 850#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
@@ -804,7 +922,7 @@ static const struct spi_device_id m25p_ids[] = {
804 { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, 922 { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
805 { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, 923 { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
806 { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, 924 { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
807 { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) }, 925 { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
808 926
809 /* Micron */ 927 /* Micron */
810 { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, 928 { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
@@ -824,7 +942,7 @@ static const struct spi_device_id m25p_ids[] = {
824 { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 0) }, 942 { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 0) },
825 { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) }, 943 { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) },
826 { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, 944 { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
827 { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) }, 945 { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, M25P80_QUAD_READ) },
828 { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) }, 946 { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
829 { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, 947 { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
830 { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, 948 { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
@@ -966,6 +1084,7 @@ static int m25p_probe(struct spi_device *spi)
966 unsigned i; 1084 unsigned i;
967 struct mtd_part_parser_data ppdata; 1085 struct mtd_part_parser_data ppdata;
968 struct device_node *np = spi->dev.of_node; 1086 struct device_node *np = spi->dev.of_node;
1087 int ret;
969 1088
970 /* Platform data helps sort out which chip type we have, as 1089 /* Platform data helps sort out which chip type we have, as
971 * well as how this board partitions it. If we don't have 1090 * well as how this board partitions it. If we don't have
@@ -1093,8 +1212,21 @@ static int m25p_probe(struct spi_device *spi)
1093 if (info->flags & M25P_NO_FR) 1212 if (info->flags & M25P_NO_FR)
1094 flash->flash_read = M25P80_NORMAL; 1213 flash->flash_read = M25P80_NORMAL;
1095 1214
1215 /* Quad-read mode takes precedence over fast/normal */
1216 if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
1217 ret = set_quad_mode(flash, info->jedec_id);
1218 if (ret) {
1219 dev_err(&flash->spi->dev, "quad mode not supported\n");
1220 return ret;
1221 }
1222 flash->flash_read = M25P80_QUAD;
1223 }
1224
1096 /* Default commands */ 1225 /* Default commands */
1097 switch (flash->flash_read) { 1226 switch (flash->flash_read) {
1227 case M25P80_QUAD:
1228 flash->read_opcode = OPCODE_QUAD_READ;
1229 break;
1098 case M25P80_FAST: 1230 case M25P80_FAST:
1099 flash->read_opcode = OPCODE_FAST_READ; 1231 flash->read_opcode = OPCODE_FAST_READ;
1100 break; 1232 break;
@@ -1116,6 +1248,9 @@ static int m25p_probe(struct spi_device *spi)
1116 if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { 1248 if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
1117 /* Dedicated 4-byte command set */ 1249 /* Dedicated 4-byte command set */
1118 switch (flash->flash_read) { 1250 switch (flash->flash_read) {
1251 case M25P80_QUAD:
1252 flash->read_opcode = OPCODE_QUAD_READ;
1253 break;
1119 case M25P80_FAST: 1254 case M25P80_FAST:
1120 flash->read_opcode = OPCODE_FAST_READ_4B; 1255 flash->read_opcode = OPCODE_FAST_READ_4B;
1121 break; 1256 break;