0020-spi-ath79-add-fast-flash-read-support.patch 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. From c4388a57860440e23c9654f4de2f515433e685a1 Mon Sep 17 00:00:00 2001
  2. From: Phil Sutter <phil@nwl.cc>
  3. Date: Tue, 13 May 2014 04:12:35 +0200
  4. Subject: [PATCH] spi-ath79: add fast flash read support
  5. ---
  6. .../include/asm/mach-ath79/ath79_spi_platform.h | 1 +
  7. drivers/spi/spi-ath79.c | 124 ++++++++++++++++++++-
  8. 2 files changed, 120 insertions(+), 5 deletions(-)
  9. diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
  10. index aa2283e..65369fe 100644
  11. --- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
  12. +++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
  13. @@ -18,6 +18,7 @@ struct ath79_spi_platform_data {
  14. struct ath79_spi_controller_data {
  15. unsigned gpio;
  16. + bool is_flash;
  17. };
  18. #endif /* _ATH79_SPI_PLATFORM_H */
  19. diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
  20. index c3b2fb9..a26a6a4 100644
  21. --- a/drivers/spi/spi-ath79.c
  22. +++ b/drivers/spi/spi-ath79.c
  23. @@ -35,6 +35,11 @@
  24. #define ATH79_SPI_RRW_DELAY_FACTOR 12000
  25. #define MHZ (1000 * 1000)
  26. +enum ath79_spi_state {
  27. + ATH79_SPI_STATE_WAIT_CMD = 0,
  28. + ATH79_SPI_STATE_WAIT_READ,
  29. +};
  30. +
  31. struct ath79_spi {
  32. struct spi_bitbang bitbang;
  33. u32 ioc_base;
  34. @@ -42,6 +47,11 @@ struct ath79_spi {
  35. void __iomem *base;
  36. struct clk *clk;
  37. unsigned rrw_delay;
  38. +
  39. + enum ath79_spi_state state;
  40. + u32 clk_div;
  41. + unsigned long read_addr;
  42. + unsigned long ahb_rate;
  43. };
  44. static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
  45. @@ -104,9 +114,6 @@ static void ath79_spi_enable(struct ath79_spi *sp)
  46. /* save CTRL register */
  47. sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
  48. sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
  49. -
  50. - /* TODO: setup speed? */
  51. - ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
  52. }
  53. static void ath79_spi_disable(struct ath79_spi *sp)
  54. @@ -203,6 +210,110 @@ static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
  55. return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
  56. }
  57. +static int ath79_spi_do_read_flash_data(struct spi_device *spi,
  58. + struct spi_transfer *t)
  59. +{
  60. + struct ath79_spi *sp = ath79_spidev_to_sp(spi);
  61. +
  62. + /* disable GPIO mode */
  63. + ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
  64. +
  65. + memcpy_fromio(t->rx_buf, sp->base + sp->read_addr, t->len);
  66. +
  67. + /* enable GPIO mode */
  68. + ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
  69. +
  70. + /* restore IOC register */
  71. + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
  72. +
  73. + return t->len;
  74. +}
  75. +
  76. +static int ath79_spi_do_read_flash_cmd(struct spi_device *spi,
  77. + struct spi_transfer *t)
  78. +{
  79. + struct ath79_spi *sp = ath79_spidev_to_sp(spi);
  80. + int len;
  81. + const u8 *p;
  82. +
  83. + sp->read_addr = 0;
  84. +
  85. + len = t->len - 1;
  86. + p = t->tx_buf;
  87. +
  88. + while (len--) {
  89. + p++;
  90. + sp->read_addr <<= 8;
  91. + sp->read_addr |= *p;
  92. + }
  93. +
  94. + return t->len;
  95. +}
  96. +
  97. +static bool ath79_spi_is_read_cmd(struct spi_device *spi,
  98. + struct spi_transfer *t)
  99. +{
  100. + return t->type == SPI_TRANSFER_FLASH_READ_CMD;
  101. +}
  102. +
  103. +static bool ath79_spi_is_data_read(struct spi_device *spi,
  104. + struct spi_transfer *t)
  105. +{
  106. + return t->type == SPI_TRANSFER_FLASH_READ_DATA;
  107. +}
  108. +
  109. +static int ath79_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
  110. +{
  111. + struct ath79_spi *sp = ath79_spidev_to_sp(spi);
  112. + int ret;
  113. +
  114. + switch (sp->state) {
  115. + case ATH79_SPI_STATE_WAIT_CMD:
  116. + if (ath79_spi_is_read_cmd(spi, t)) {
  117. + ret = ath79_spi_do_read_flash_cmd(spi, t);
  118. + sp->state = ATH79_SPI_STATE_WAIT_READ;
  119. + } else {
  120. + ret = spi_bitbang_bufs(spi, t);
  121. + }
  122. + break;
  123. +
  124. + case ATH79_SPI_STATE_WAIT_READ:
  125. + if (ath79_spi_is_data_read(spi, t)) {
  126. + ret = ath79_spi_do_read_flash_data(spi, t);
  127. + } else {
  128. + dev_warn(&spi->dev, "flash data read expected\n");
  129. + ret = -EIO;
  130. + }
  131. + sp->state = ATH79_SPI_STATE_WAIT_CMD;
  132. + break;
  133. +
  134. + default:
  135. + BUG();
  136. + }
  137. +
  138. + return ret;
  139. +}
  140. +
  141. +static int ath79_spi_setup_transfer(struct spi_device *spi,
  142. + struct spi_transfer *t)
  143. +{
  144. + struct ath79_spi *sp = ath79_spidev_to_sp(spi);
  145. + struct ath79_spi_controller_data *cdata;
  146. + int ret;
  147. +
  148. + ret = spi_bitbang_setup_transfer(spi, t);
  149. + if (ret)
  150. + return ret;
  151. +
  152. + cdata = spi->controller_data;
  153. + if (cdata->is_flash)
  154. + sp->bitbang.txrx_bufs = ath79_spi_txrx_bufs;
  155. + else
  156. + sp->bitbang.txrx_bufs = spi_bitbang_bufs;
  157. +
  158. + return ret;
  159. +}
  160. +
  161. static int ath79_spi_probe(struct platform_device *pdev)
  162. {
  163. struct spi_master *master;
  164. @@ -223,6 +334,8 @@ static int ath79_spi_probe(struct platform_device *pdev)
  165. pdata = dev_get_platdata(&pdev->dev);
  166. + sp->state = ATH79_SPI_STATE_WAIT_CMD;
  167. +
  168. master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
  169. master->setup = ath79_spi_setup;
  170. master->cleanup = ath79_spi_cleanup;
  171. @@ -234,7 +347,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
  172. sp->bitbang.master = master;
  173. sp->bitbang.chipselect = ath79_spi_chipselect;
  174. sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
  175. - sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
  176. + sp->bitbang.setup_transfer = ath79_spi_setup_transfer;
  177. sp->bitbang.flags = SPI_CS_HIGH;
  178. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  179. @@ -259,7 +372,8 @@ static int ath79_spi_probe(struct platform_device *pdev)
  180. if (ret)
  181. goto err_put_master;
  182. - rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
  183. + sp->ahb_rate = clk_get_rate(sp->clk);
  184. + rate = DIV_ROUND_UP(sp->ahb_rate, MHZ);
  185. if (!rate) {
  186. ret = -EINVAL;
  187. goto err_clk_disable;
  188. --
  189. 1.8.5.3