709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. From 16d2871830ff3fe12a6bff582549a9264adff278 Mon Sep 17 00:00:00 2001
  2. From: Ram Chandra Jangir <rjangi@codeaurora.org>
  3. Date: Tue, 10 May 2016 20:19:31 +0530
  4. Subject: [PATCH] spi: qup: Fix fifo and dma support for IPQ806x
  5. Signed-off-by: Ram Chandra Jangir <rjangi@codeaurora.org>
  6. ---
  7. drivers/spi/spi-qup.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--
  8. 1 file changed, 52 insertions(+), 2 deletions(-)
  9. --- a/drivers/spi/spi-qup.c
  10. +++ b/drivers/spi/spi-qup.c
  11. @@ -24,6 +24,7 @@
  12. #include <linux/spi/spi.h>
  13. #include <linux/dmaengine.h>
  14. #include <linux/dma-mapping.h>
  15. +#include <linux/gpio.h>
  16. #define QUP_CONFIG 0x0000
  17. #define QUP_STATE 0x0004
  18. @@ -152,6 +153,7 @@ struct spi_qup {
  19. int use_dma;
  20. struct dma_slave_config rx_conf;
  21. struct dma_slave_config tx_conf;
  22. + int mode;
  23. };
  24. @@ -370,7 +372,8 @@ static int spi_qup_do_pio(struct spi_mas
  25. return ret;
  26. }
  27. - spi_qup_fifo_write(qup, xfer);
  28. + if (qup->mode == QUP_IO_M_MODE_FIFO)
  29. + spi_qup_fifo_write(qup, xfer);
  30. return 0;
  31. }
  32. @@ -448,6 +451,7 @@ spi_qup_get_mode(struct spi_master *mast
  33. {
  34. struct spi_qup *qup = spi_master_get_devdata(master);
  35. u32 mode;
  36. + size_t dma_align = dma_get_cache_alignment();
  37. qup->w_size = 4;
  38. @@ -458,6 +462,14 @@ spi_qup_get_mode(struct spi_master *mast
  39. qup->n_words = xfer->len / qup->w_size;
  40. + if (!IS_ERR_OR_NULL(master->dma_rx) &&
  41. + IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
  42. + IS_ALIGNED((size_t)xfer->rx_buf, dma_align) &&
  43. + !is_vmalloc_addr(xfer->tx_buf) &&
  44. + !is_vmalloc_addr(xfer->rx_buf) &&
  45. + (xfer->len > 3*qup->in_blk_sz))
  46. + qup->use_dma = 1;
  47. +
  48. if (qup->n_words <= (qup->in_fifo_sz / sizeof(u32)))
  49. mode = QUP_IO_M_MODE_FIFO;
  50. else
  51. @@ -491,7 +503,7 @@ static int spi_qup_io_config(struct spi_
  52. return -EIO;
  53. }
  54. - mode = spi_qup_get_mode(spi->master, xfer);
  55. + controller->mode = mode = spi_qup_get_mode(spi->master, xfer);
  56. n_words = controller->n_words;
  57. if (mode == QUP_IO_M_MODE_FIFO) {
  58. @@ -500,6 +512,7 @@ static int spi_qup_io_config(struct spi_
  59. /* must be zero for FIFO */
  60. writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
  61. writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
  62. + controller->use_dma = 0;
  63. } else if (!controller->use_dma) {
  64. writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
  65. writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
  66. @@ -750,6 +763,38 @@ err_tx:
  67. return ret;
  68. }
  69. +static void spi_qup_set_cs(struct spi_device *spi, bool val)
  70. +{
  71. + struct spi_qup *controller;
  72. + u32 spi_ioc;
  73. + u32 spi_ioc_orig;
  74. +
  75. + controller = spi_master_get_devdata(spi->master);
  76. + spi_ioc = readl_relaxed(controller->base + SPI_IO_CONTROL);
  77. + spi_ioc_orig = spi_ioc;
  78. + if (!val)
  79. + spi_ioc |= SPI_IO_C_FORCE_CS;
  80. + else
  81. + spi_ioc &= ~SPI_IO_C_FORCE_CS;
  82. +
  83. + if (spi_ioc != spi_ioc_orig)
  84. + writel_relaxed(spi_ioc, controller->base + SPI_IO_CONTROL);
  85. +}
  86. +
  87. +static int spi_qup_setup(struct spi_device *spi)
  88. +{
  89. + if (spi->cs_gpio >= 0) {
  90. + if (spi->mode & SPI_CS_HIGH)
  91. + gpio_set_value(spi->cs_gpio, 0);
  92. + else
  93. + gpio_set_value(spi->cs_gpio, 1);
  94. +
  95. + udelay(10);
  96. + }
  97. +
  98. + return 0;
  99. +}
  100. +
  101. static int spi_qup_probe(struct platform_device *pdev)
  102. {
  103. struct spi_master *master;
  104. @@ -846,6 +891,11 @@ static int spi_qup_probe(struct platform
  105. if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
  106. controller->qup_v1 = 1;
  107. + if (!controller->qup_v1)
  108. + master->set_cs = spi_qup_set_cs;
  109. + else
  110. + master->setup = spi_qup_setup;
  111. +
  112. spin_lock_init(&controller->lock);
  113. init_completion(&controller->done);