081-spi-bcm53xx-add-spi_flash_read-callback-for-MMIO-bas.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. From a7b221d8f0d75511c5f959584712a5dd35f88a86 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
  3. Date: Mon, 18 Apr 2016 14:39:30 +0200
  4. Subject: [PATCH] spi: bcm53xx: add spi_flash_read callback for MMIO-based
  5. reads
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. This implements more efficient reads of SPI-attached flash content.
  10. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
  11. Signed-off-by: Mark Brown <broonie@kernel.org>
  12. ---
  13. --- a/drivers/spi/spi-bcm53xx.c
  14. +++ b/drivers/spi/spi-bcm53xx.c
  15. @@ -10,6 +10,7 @@
  16. #include "spi-bcm53xx.h"
  17. #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
  18. +#define BCM53XXSPI_FLASH_WINDOW SZ_32M
  19. /* The longest observed required wait was 19 ms */
  20. #define BCM53XXSPI_SPE_TIMEOUT_MS 80
  21. @@ -17,8 +18,10 @@
  22. struct bcm53xxspi {
  23. struct bcma_device *core;
  24. struct spi_master *master;
  25. + void __iomem *mmio_base;
  26. size_t read_offset;
  27. + bool bspi; /* Boot SPI mode with memory mapping */
  28. };
  29. static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
  30. @@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(stru
  31. bcma_write32(b53spi->core, offset, value);
  32. }
  33. +static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi)
  34. +{
  35. + struct device *dev = &b53spi->core->dev;
  36. + unsigned long deadline;
  37. + u32 tmp;
  38. +
  39. + if (!b53spi->bspi)
  40. + return;
  41. +
  42. + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
  43. + if (tmp & 0x1)
  44. + return;
  45. +
  46. + deadline = jiffies + usecs_to_jiffies(200);
  47. + do {
  48. + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS);
  49. + if (!(tmp & 0x1)) {
  50. + bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL,
  51. + 0x1);
  52. + ndelay(200);
  53. + b53spi->bspi = false;
  54. + return;
  55. + }
  56. + udelay(1);
  57. + } while (!time_after_eq(jiffies, deadline));
  58. +
  59. + dev_warn(dev, "Timeout disabling BSPI\n");
  60. +}
  61. +
  62. +static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi)
  63. +{
  64. + u32 tmp;
  65. +
  66. + if (b53spi->bspi)
  67. + return;
  68. +
  69. + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
  70. + if (!(tmp & 0x1))
  71. + return;
  72. +
  73. + bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0);
  74. + b53spi->bspi = true;
  75. +}
  76. +
  77. static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
  78. {
  79. /* Do some magic calculation based on length and buad. Add 10% and 1. */
  80. @@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struc
  81. u8 *buf;
  82. size_t left;
  83. + bcm53xxspi_disable_bspi(b53spi);
  84. +
  85. if (t->tx_buf) {
  86. buf = (u8 *)t->tx_buf;
  87. left = t->len;
  88. @@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struc
  89. return 0;
  90. }
  91. +static int bcm53xxspi_flash_read(struct spi_device *spi,
  92. + struct spi_flash_read_message *msg)
  93. +{
  94. + struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master);
  95. + int ret = 0;
  96. +
  97. + if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW)
  98. + return -EINVAL;
  99. +
  100. + bcm53xxspi_enable_bspi(b53spi);
  101. + memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len);
  102. + msg->retlen = msg->len;
  103. +
  104. + return ret;
  105. +}
  106. +
  107. /**************************************************
  108. * BCMA
  109. **************************************************/
  110. @@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcm
  111. static int bcm53xxspi_bcma_probe(struct bcma_device *core)
  112. {
  113. + struct device *dev = &core->dev;
  114. struct bcm53xxspi *b53spi;
  115. struct spi_master *master;
  116. int err;
  117. @@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct
  118. return -ENOTSUPP;
  119. }
  120. - master = spi_alloc_master(&core->dev, sizeof(*b53spi));
  121. + master = spi_alloc_master(dev, sizeof(*b53spi));
  122. if (!master)
  123. return -ENOMEM;
  124. @@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct
  125. b53spi->master = master;
  126. b53spi->core = core;
  127. + if (core->addr_s[0])
  128. + b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0],
  129. + BCM53XXSPI_FLASH_WINDOW);
  130. + b53spi->bspi = true;
  131. + bcm53xxspi_disable_bspi(b53spi);
  132. +
  133. master->transfer_one = bcm53xxspi_transfer_one;
  134. + if (b53spi->mmio_base)
  135. + master->spi_flash_read = bcm53xxspi_flash_read;
  136. bcma_set_drvdata(core, b53spi);
  137. - err = devm_spi_register_master(&core->dev, master);
  138. + err = devm_spi_register_master(dev, master);
  139. if (err) {
  140. spi_master_put(master);
  141. bcma_set_drvdata(core, NULL);