1106-mtd-fsl-quadspi-add-DDR-quad-read-for-Spansion.patch 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. From 16eb35ceea5b43e6f64c1a869721ea86c0da5260 Mon Sep 17 00:00:00 2001
  2. From: Yunhui Cui <yunhui.cui@nxp.com>
  3. Date: Thu, 25 Feb 2016 10:19:15 +0800
  4. Subject: [PATCH 106/113] mtd: fsl-quadspi: add DDR quad read for Spansion
  5. Add the DDR quad read support for the fsl-quadspi driver.
  6. And, add the Spansion s25fl128s NOR flash ddr quad mode
  7. support.
  8. Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
  9. ---
  10. drivers/mtd/spi-nor/fsl-quadspi.c | 57 +++++++++++++++++++++++++++++++++++++
  11. 1 file changed, 57 insertions(+)
  12. --- a/drivers/mtd/spi-nor/fsl-quadspi.c
  13. +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
  14. @@ -296,6 +296,7 @@ struct fsl_qspi {
  15. u32 nor_size;
  16. u32 nor_num;
  17. u32 clk_rate;
  18. + u32 ddr_smp;
  19. unsigned int chip_base_addr; /* We may support two chips. */
  20. bool has_second_chip;
  21. bool big_endian;
  22. @@ -423,6 +424,19 @@ static void fsl_qspi_init_lut(struct fsl
  23. qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
  24. LUT1(FSL_READ, PAD4, rxfifo),
  25. base + QUADSPI_LUT(lut_base + 1));
  26. + } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
  27. + /* read mode : 1-4-4, such as Spansion s25fl128s. */
  28. + qspi_writel(q, LUT0(CMD, PAD1, read_op)
  29. + | LUT1(ADDR_DDR, PAD4, addrlen),
  30. + base + QUADSPI_LUT(lut_base));
  31. +
  32. + qspi_writel(q, LUT0(MODE_DDR, PAD4, 0xff)
  33. + | LUT1(DUMMY, PAD1, read_dm),
  34. + base + QUADSPI_LUT(lut_base + 1));
  35. +
  36. + qspi_writel(q, LUT0(FSL_READ_DDR, PAD4, rxfifo)
  37. + | LUT1(JMP_ON_CS, PAD1, 0),
  38. + base + QUADSPI_LUT(lut_base + 2));
  39. }
  40. /* Write enable */
  41. @@ -534,6 +548,8 @@ static void fsl_qspi_init_lut(struct fsl
  42. static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
  43. {
  44. switch (cmd) {
  45. + case SPINOR_OP_READ_1_4_4_D:
  46. + case SPINOR_OP_READ4_1_4_4_D:
  47. case SPINOR_OP_READ4_1_1_4:
  48. case SPINOR_OP_READ_1_1_4:
  49. case SPINOR_OP_READ_FAST:
  50. @@ -736,6 +752,32 @@ static void fsl_qspi_set_map_addr(struct
  51. }
  52. /*
  53. + * enable controller ddr quad mode to support different
  54. + * vender flashes ddr quad mode.
  55. + */
  56. +static void set_ddr_quad_mode(struct fsl_qspi *q)
  57. +{
  58. + u32 reg, reg2;
  59. +
  60. + reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
  61. +
  62. + /* Firstly, disable the module */
  63. + qspi_writel(q, reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
  64. +
  65. + /* Set the Sampling Register for DDR */
  66. + reg2 = qspi_readl(q, q->iobase + QUADSPI_SMPR);
  67. + reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
  68. + reg2 |= (((q->ddr_smp) << QUADSPI_SMPR_DDRSMP_SHIFT) &
  69. + QUADSPI_SMPR_DDRSMP_MASK);
  70. + qspi_writel(q, reg2, q->iobase + QUADSPI_SMPR);
  71. +
  72. + /* Enable the module again (enable the DDR too) */
  73. + reg |= QUADSPI_MCR_DDR_EN_MASK;
  74. + qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
  75. +
  76. +}
  77. +
  78. +/*
  79. * There are two different ways to read out the data from the flash:
  80. * the "IP Command Read" and the "AHB Command Read".
  81. *
  82. @@ -775,6 +817,11 @@ static void fsl_qspi_init_abh_read(struc
  83. seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
  84. qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
  85. q->iobase + QUADSPI_BFGENCR);
  86. +
  87. + /* enable the DDR quad read */
  88. + if (q->nor->flash_read == SPI_NOR_DDR_QUAD)
  89. + set_ddr_quad_mode(q);
  90. +
  91. }
  92. /* This function was used to prepare and enable QSPI clock */
  93. @@ -1108,6 +1155,12 @@ static int fsl_qspi_probe(struct platfor
  94. goto clk_failed;
  95. }
  96. + /* find ddrsmp value */
  97. + ret = of_property_read_u32(dev->of_node, "fsl,ddr-sampling-point",
  98. + &q->ddr_smp);
  99. + if (ret)
  100. + q->ddr_smp = 0;
  101. +
  102. /* find the irq */
  103. ret = platform_get_irq(pdev, 0);
  104. if (ret < 0) {
  105. @@ -1164,6 +1217,10 @@ static int fsl_qspi_probe(struct platfor
  106. ret = of_property_read_bool(np, "m25p,fast-read");
  107. mode = (ret) ? SPI_NOR_FAST : SPI_NOR_QUAD;
  108. + /* Can we enable the DDR Quad Read? */
  109. + ret = of_property_read_bool(np, "ddr-quad-read");
  110. + if (ret)
  111. + mode = SPI_NOR_DDR_QUAD;
  112. ret = spi_nor_scan(nor, NULL, mode);
  113. if (ret)