0024-mtd-spi-nor-configure-the-number-of-dummy-clock-cycl.patch 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. From 77fee227b15835d03517dc34675f72e8963ae882 Mon Sep 17 00:00:00 2001
  2. From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
  3. Date: Fri, 8 Jan 2016 17:02:21 +0100
  4. Subject: [PATCH 24/33] mtd: spi-nor: configure the number of dummy clock
  5. cycles on Micron memories
  6. The spi-nor framework currently expects all Fast Read operations to use 8
  7. dummy clock cycles. Especially some drivers like m25p80 can only support
  8. multiple of 8 dummy clock cycles.
  9. On Micron memories, the number of dummy clock cycles to be used by Fast
  10. Read commands can be safely set to 8 by updating the Volatile
  11. Configuration Register (VCR).
  12. Also the XIP bit is set at the same time when updating the VCR so the
  13. Continuous Read mode is disabled: this prevents us from entering it by
  14. mistake.
  15. Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
  16. ---
  17. drivers/mtd/spi-nor/spi-nor.c | 72 ++++++++++++++++++++++++++++++++++++++-----
  18. include/linux/mtd/spi-nor.h | 2 ++
  19. 2 files changed, 67 insertions(+), 7 deletions(-)
  20. diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
  21. index ae3e9d8..5232984 100644
  22. --- a/drivers/mtd/spi-nor/spi-nor.c
  23. +++ b/drivers/mtd/spi-nor/spi-nor.c
  24. @@ -1333,6 +1333,53 @@ static int winbond_set_single_mode(struct spi_nor *nor)
  25. return 0;
  26. }
  27. +static int micron_set_dummy_cycles(struct spi_nor *nor, u8 read_dummy)
  28. +{
  29. + u8 vcr, val, mask;
  30. + int ret;
  31. +
  32. + /* Set bit3 (XIP) to disable the Continuous Read mode */
  33. + mask = GENMASK(7, 4) | BIT(3);
  34. + val = ((read_dummy << 4) | BIT(3)) & mask;
  35. +
  36. + /* Read the Volatile Configuration Register (VCR). */
  37. + ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &vcr, 1);
  38. + if (ret < 0) {
  39. + dev_err(nor->dev, "error while reading VCR register\n");
  40. + return ret;
  41. + }
  42. +
  43. + /* Check whether we need to update the number of dummy cycles. */
  44. + if ((vcr & mask) == val) {
  45. + nor->read_dummy = read_dummy;
  46. + return 0;
  47. + }
  48. +
  49. + /* Update the number of dummy into the VCR. */
  50. + write_enable(nor);
  51. + vcr = (vcr & ~mask) | val;
  52. + ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &vcr, 1);
  53. + if (ret < 0) {
  54. + dev_err(nor->dev, "error while writing VCR register\n");
  55. + return ret;
  56. + }
  57. +
  58. + ret = spi_nor_wait_till_ready(nor);
  59. + if (ret)
  60. + return ret;
  61. +
  62. + /* Read VCR and check it. */
  63. + ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &vcr, 1);
  64. + if (ret < 0 || (vcr & mask) != val) {
  65. + dev_err(nor->dev, "Micron VCR dummy cycles not updated\n");
  66. + return -EINVAL;
  67. + }
  68. +
  69. + /* Save the number of dummy cycles to use with Fast Read commands */
  70. + nor->read_dummy = read_dummy;
  71. + return 0;
  72. +}
  73. +
  74. static int micron_set_protocol(struct spi_nor *nor, u8 mask, u8 val,
  75. enum spi_nor_protocol proto)
  76. {
  77. @@ -1417,12 +1464,15 @@ static int micron_set_quad_mode(struct spi_nor *nor)
  78. /*
  79. * Whatever the Quad mode is enabled or not, the
  80. * Fast Read Quad Output 1-1-4 (0x6b) op code is supported.
  81. + * Force the number of dummy cycles to 8 and disable the Continuous Read
  82. + * mode to prevent some drivers from using it by mistake (m25p80).
  83. + * We can change these settings safely as we write into a volatile
  84. + * register.
  85. */
  86. if (nor->read_proto != SNOR_PROTO_4_4_4)
  87. nor->read_proto = SNOR_PROTO_1_1_4;
  88. nor->read_opcode = SPINOR_OP_READ_1_1_4;
  89. - nor->read_dummy = 8;
  90. - return 0;
  91. + return micron_set_dummy_cycles(nor, 8);
  92. }
  93. static int micron_set_dual_mode(struct spi_nor *nor)
  94. @@ -1447,12 +1497,15 @@ static int micron_set_dual_mode(struct spi_nor *nor)
  95. /*
  96. * Whatever the Dual mode is enabled or not, the
  97. * Fast Read Dual Output 1-1-2 (0x3b) op code is supported.
  98. + * Force the number of dummy cycles to 8 and disable the Continuous Read
  99. + * mode to prevent some drivers from using it by mistake (m25p80).
  100. + * We can change these settings safely as we write into a volatile
  101. + * register.
  102. */
  103. if (nor->read_proto != SNOR_PROTO_2_2_2)
  104. nor->read_proto = SNOR_PROTO_1_1_2;
  105. nor->read_opcode = SPINOR_OP_READ_1_1_2;
  106. - nor->read_dummy = 8;
  107. - return 0;
  108. + return micron_set_dummy_cycles(nor, 8);
  109. }
  110. static int micron_set_single_mode(struct spi_nor *nor)
  111. @@ -1475,7 +1528,13 @@ static int micron_set_single_mode(struct spi_nor *nor)
  112. nor->read_proto = SNOR_PROTO_1_1_1;
  113. }
  114. - /* Force the number of dummy cycles to 8 for Fast Read, 0 for Read. */
  115. + /*
  116. + * Force the number of dummy cycles to 8 for Fast Read, 0 for Read
  117. + * and disable the Continuous Read mode to prevent some drivers from
  118. + * using it by mistake (m25p80).
  119. + * We can change these settings safely as we write into a volatile
  120. + * register.
  121. + */
  122. switch (nor->read_opcode) {
  123. case SPINOR_OP_READ:
  124. case SPINOR_OP_READ4:
  125. @@ -1486,8 +1545,7 @@ static int micron_set_single_mode(struct spi_nor *nor)
  126. read_dummy = 8;
  127. break;
  128. }
  129. - nor->read_dummy = read_dummy;
  130. - return 0;
  131. + return micron_set_dummy_cycles(nor, read_dummy);
  132. }
  133. static int spansion_set_quad_mode(struct spi_nor *nor)
  134. diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
  135. index d0a6f34..2dc0f8b 100644
  136. --- a/include/linux/mtd/spi-nor.h
  137. +++ b/include/linux/mtd/spi-nor.h
  138. @@ -86,6 +86,8 @@
  139. /* Used for Micron flashes only. */
  140. #define SPINOR_OP_MIO_RDID 0xaf /* Multiple I/O Read JEDEC ID */
  141. +#define SPINOR_OP_RD_VCR 0x85 /* Read VCR register */
  142. +#define SPINOR_OP_WR_VCR 0x81 /* Write VCR register */
  143. #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
  144. #define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
  145. --
  146. 2.8.1