aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllen Xu <b45815@freescale.com>2014-03-14 16:18:25 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:58:00 -0400
commit2f73dd368a1cfdb9f33ead5a115907e16c253670 (patch)
tree5b21e77a1eb82c86028b58d158ea782a1268f728
parenta49ce1475f2a9943ec435cd5bc9e2d9606f5bf36 (diff)
ENGR00303629-2 qspi: support SF25FL128S by enabling DDR Quad IO mode
Enalbe DDR Quad IO mode to support Spansion SF25FL128S NOR flash. Signed-off-by: Allen Xu <b45815@freescale.com>
-rw-r--r--drivers/mtd/spi-nor/fsl-quadspi.c65
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c1
2 files changed, 53 insertions, 13 deletions
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 3904de65807b..4f8bc62761d6 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -193,6 +193,9 @@
193#define SEQID_DDR_QUAD_READ 12 193#define SEQID_DDR_QUAD_READ 12
194 194
195#define OPCODE_DDR_QUAD_READ 0x6d 195#define OPCODE_DDR_QUAD_READ 0x6d
196#define OPCODE_DDR_QUAD_IO_READ 0xed /*DDR IO read data bytes*/
197
198#define MFR_SPAN 0x01
196 199
197enum fsl_qspi_devtype { 200enum fsl_qspi_devtype {
198 FSL_QUADSPI_VYBRID, 201 FSL_QUADSPI_VYBRID,
@@ -235,6 +238,7 @@ struct fsl_qspi {
235 u32 nor_num; 238 u32 nor_num;
236 u32 clk_rate; 239 u32 clk_rate;
237 unsigned int chip_base_addr; /* We may support two chips. */ 240 unsigned int chip_base_addr; /* We may support two chips. */
241 bool ddr_io_mode;
238}; 242};
239 243
240static inline int is_vybrid_qspi(struct fsl_qspi *q) 244static inline int is_vybrid_qspi(struct fsl_qspi *q)
@@ -392,23 +396,47 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
392 /* DDR QUAD read */ 396 /* DDR QUAD read */
393 lut_base = SEQID_DDR_QUAD_READ * 4; 397 lut_base = SEQID_DDR_QUAD_READ * 4;
394 398
395 if (q->nor_size <= SZ_16M) { 399 /*DDR QUAD IO read mode*/
396 cmd = OPCODE_DDR_QUAD_READ; 400 if (q->ddr_io_mode) {
397 addrlen = ADDR24BIT; 401
398 dummy = 8; 402 if (q->nor_size <= SZ_16M) {
399 } else { 403 cmd = OPCODE_DDR_QUAD_IO_READ;
400 cmd = OPCODE_DDR_QUAD_READ; 404 addrlen = ADDR24BIT;
401 addrlen = ADDR32BIT; 405 dummy = 3;
402 dummy = 6; 406 } else {
403 } 407 cmd = OPCODE_DDR_QUAD_IO_READ;
408 addrlen = ADDR32BIT;
409 dummy = 7;
410 }
404 411
405 writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR_DDR, PAD1, addrlen), 412 writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR_DDR, PAD4, addrlen),
406 base + QUADSPI_LUT(lut_base)); 413 base + QUADSPI_LUT(lut_base));
407 writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ_DDR, PAD4, rxfifo), 414 writel(LUT0(MODE_DDR, PAD1, 4) | LUT1(DUMMY, PAD1, dummy),
408 base + QUADSPI_LUT(lut_base + 1)); 415 base + QUADSPI_LUT(lut_base + 1));
409 writel(LUT0(JMP_ON_CS, PAD1, 0), 416 writel(LUT0(READ_DDR, PAD4, rxfifo) | LUT1(JMP_ON_CS, PAD1, 0),
410 base + QUADSPI_LUT(lut_base + 2)); 417 base + QUADSPI_LUT(lut_base + 2));
411 418
419 /*Extended DDR QUAD read mode*/
420 } else {
421
422 if (q->nor_size <= SZ_16M) {
423 cmd = OPCODE_DDR_QUAD_READ;
424 addrlen = ADDR24BIT;
425 dummy = 8;
426 } else {
427 cmd = OPCODE_DDR_QUAD_READ;
428 addrlen = ADDR32BIT;
429 dummy = 6;
430 }
431
432 writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR_DDR, PAD1, addrlen),
433 base + QUADSPI_LUT(lut_base));
434 writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ_DDR, PAD4, rxfifo),
435 base + QUADSPI_LUT(lut_base + 1));
436 writel(LUT0(JMP_ON_CS, PAD1, 0),
437 base + QUADSPI_LUT(lut_base + 2));
438 }
439
412 fsl_qspi_lock_lut(q); 440 fsl_qspi_lock_lut(q);
413} 441}
414 442
@@ -441,7 +469,9 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
441 case OPCODE_BRWR: 469 case OPCODE_BRWR:
442 return SEQID_BRWR; 470 return SEQID_BRWR;
443 case OPCODE_DDR_QUAD_READ: 471 case OPCODE_DDR_QUAD_READ:
472 case OPCODE_DDR_QUAD_IO_READ:
444 return SEQID_DDR_QUAD_READ; 473 return SEQID_DDR_QUAD_READ;
474
445 default: 475 default:
446 dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd); 476 dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
447 break; 477 break;
@@ -865,6 +895,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
865 bool has_second_chip = false; 895 bool has_second_chip = false;
866 const struct of_device_id *of_id = 896 const struct of_device_id *of_id =
867 of_match_device(fsl_qspi_dt_ids, &pdev->dev); 897 of_match_device(fsl_qspi_dt_ids, &pdev->dev);
898 u8 jedec_mfr_id;
868 899
869 q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL); 900 q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
870 if (!q) 901 if (!q)
@@ -976,6 +1007,11 @@ static int fsl_qspi_probe(struct platform_device *pdev)
976 if (!id) 1007 if (!id)
977 goto map_failed; 1008 goto map_failed;
978 1009
1010 /*get the NOR chip manufacture id*/
1011 jedec_mfr_id = (*(u32 *)(id->driver_data)) >> 16;
1012 if (MFR_SPAN == jedec_mfr_id)
1013 q->ddr_io_mode = true;
1014
979 ret = of_property_read_u32(np, "spi-max-frequency", 1015 ret = of_property_read_u32(np, "spi-max-frequency",
980 &q->clk_rate); 1016 &q->clk_rate);
981 if (ret < 0) 1017 if (ret < 0)
@@ -1014,7 +1050,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
1014 nor->page_size = q->devtype_data->txfifo; 1050 nor->page_size = q->devtype_data->txfifo;
1015 1051
1016 /* Set DDR QUAD READ, we will remove the hardcode in future.*/ 1052 /* Set DDR QUAD READ, we will remove the hardcode in future.*/
1017 nor->read_opcode = OPCODE_DDR_QUAD_READ; 1053 if (q->ddr_io_mode)
1054 nor->read_opcode = OPCODE_DDR_QUAD_IO_READ;
1055 else
1056 nor->read_opcode = OPCODE_DDR_QUAD_READ;
1018 1057
1019 i++; 1058 i++;
1020 } 1059 }
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 84330077b4c0..1353cffc68b4 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -500,6 +500,7 @@ const struct spi_device_id spi_nor_ids[] = {
500 { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 500 { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
501 { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 501 { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
502 { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, 502 { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
503 { "s25fl128s", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
503 { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, 504 { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
504 { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, 505 { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
505 { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) }, 506 { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) },