spi-octeon.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2011, 2012 Cavium, Inc.
  7. */
  8. #include <linux/platform_device.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/spi/spi.h>
  11. #include <linux/module.h>
  12. #include <linux/delay.h>
  13. #include <linux/io.h>
  14. #include <linux/of.h>
  15. #include <asm/octeon/octeon.h>
  16. #include <asm/octeon/cvmx-mpi-defs.h>
  17. #define OCTEON_SPI_CFG 0
  18. #define OCTEON_SPI_STS 0x08
  19. #define OCTEON_SPI_TX 0x10
  20. #define OCTEON_SPI_DAT0 0x80
  21. #define OCTEON_SPI_MAX_BYTES 9
  22. #define OCTEON_SPI_MAX_CLOCK_HZ 16000000
  23. struct octeon_spi {
  24. u64 register_base;
  25. u64 last_cfg;
  26. u64 cs_enax;
  27. };
  28. static void octeon_spi_wait_ready(struct octeon_spi *p)
  29. {
  30. union cvmx_mpi_sts mpi_sts;
  31. unsigned int loops = 0;
  32. do {
  33. if (loops++)
  34. __delay(500);
  35. mpi_sts.u64 = cvmx_read_csr(p->register_base + OCTEON_SPI_STS);
  36. } while (mpi_sts.s.busy);
  37. }
  38. static int octeon_spi_do_transfer(struct octeon_spi *p,
  39. struct spi_message *msg,
  40. struct spi_transfer *xfer,
  41. bool last_xfer)
  42. {
  43. struct spi_device *spi = msg->spi;
  44. union cvmx_mpi_cfg mpi_cfg;
  45. union cvmx_mpi_tx mpi_tx;
  46. unsigned int clkdiv;
  47. unsigned int speed_hz;
  48. int mode;
  49. bool cpha, cpol;
  50. const u8 *tx_buf;
  51. u8 *rx_buf;
  52. int len;
  53. int i;
  54. mode = spi->mode;
  55. cpha = mode & SPI_CPHA;
  56. cpol = mode & SPI_CPOL;
  57. speed_hz = xfer->speed_hz;
  58. clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz);
  59. mpi_cfg.u64 = 0;
  60. mpi_cfg.s.clkdiv = clkdiv;
  61. mpi_cfg.s.cshi = (mode & SPI_CS_HIGH) ? 1 : 0;
  62. mpi_cfg.s.lsbfirst = (mode & SPI_LSB_FIRST) ? 1 : 0;
  63. mpi_cfg.s.wireor = (mode & SPI_3WIRE) ? 1 : 0;
  64. mpi_cfg.s.idlelo = cpha != cpol;
  65. mpi_cfg.s.cslate = cpha ? 1 : 0;
  66. mpi_cfg.s.enable = 1;
  67. if (spi->chip_select < 4)
  68. p->cs_enax |= 1ull << (12 + spi->chip_select);
  69. mpi_cfg.u64 |= p->cs_enax;
  70. if (mpi_cfg.u64 != p->last_cfg) {
  71. p->last_cfg = mpi_cfg.u64;
  72. cvmx_write_csr(p->register_base + OCTEON_SPI_CFG, mpi_cfg.u64);
  73. }
  74. tx_buf = xfer->tx_buf;
  75. rx_buf = xfer->rx_buf;
  76. len = xfer->len;
  77. while (len > OCTEON_SPI_MAX_BYTES) {
  78. for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
  79. u8 d;
  80. if (tx_buf)
  81. d = *tx_buf++;
  82. else
  83. d = 0;
  84. cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
  85. }
  86. mpi_tx.u64 = 0;
  87. mpi_tx.s.csid = spi->chip_select;
  88. mpi_tx.s.leavecs = 1;
  89. mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
  90. mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
  91. cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
  92. octeon_spi_wait_ready(p);
  93. if (rx_buf)
  94. for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
  95. u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
  96. *rx_buf++ = (u8)v;
  97. }
  98. len -= OCTEON_SPI_MAX_BYTES;
  99. }
  100. for (i = 0; i < len; i++) {
  101. u8 d;
  102. if (tx_buf)
  103. d = *tx_buf++;
  104. else
  105. d = 0;
  106. cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
  107. }
  108. mpi_tx.u64 = 0;
  109. mpi_tx.s.csid = spi->chip_select;
  110. if (last_xfer)
  111. mpi_tx.s.leavecs = xfer->cs_change;
  112. else
  113. mpi_tx.s.leavecs = !xfer->cs_change;
  114. mpi_tx.s.txnum = tx_buf ? len : 0;
  115. mpi_tx.s.totnum = len;
  116. cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
  117. octeon_spi_wait_ready(p);
  118. if (rx_buf)
  119. for (i = 0; i < len; i++) {
  120. u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
  121. *rx_buf++ = (u8)v;
  122. }
  123. if (xfer->delay_usecs)
  124. udelay(xfer->delay_usecs);
  125. return xfer->len;
  126. }
  127. static int octeon_spi_transfer_one_message(struct spi_master *master,
  128. struct spi_message *msg)
  129. {
  130. struct octeon_spi *p = spi_master_get_devdata(master);
  131. unsigned int total_len = 0;
  132. int status = 0;
  133. struct spi_transfer *xfer;
  134. list_for_each_entry(xfer, &msg->transfers, transfer_list) {
  135. bool last_xfer = list_is_last(&xfer->transfer_list,
  136. &msg->transfers);
  137. int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer);
  138. if (r < 0) {
  139. status = r;
  140. goto err;
  141. }
  142. total_len += r;
  143. }
  144. err:
  145. msg->status = status;
  146. msg->actual_length = total_len;
  147. spi_finalize_current_message(master);
  148. return status;
  149. }
  150. static int octeon_spi_probe(struct platform_device *pdev)
  151. {
  152. struct resource *res_mem;
  153. struct spi_master *master;
  154. struct octeon_spi *p;
  155. int err = -ENOENT;
  156. master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
  157. if (!master)
  158. return -ENOMEM;
  159. p = spi_master_get_devdata(master);
  160. platform_set_drvdata(pdev, master);
  161. res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  162. if (res_mem == NULL) {
  163. dev_err(&pdev->dev, "found no memory resource\n");
  164. err = -ENXIO;
  165. goto fail;
  166. }
  167. if (!devm_request_mem_region(&pdev->dev, res_mem->start,
  168. resource_size(res_mem), res_mem->name)) {
  169. dev_err(&pdev->dev, "request_mem_region failed\n");
  170. goto fail;
  171. }
  172. p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start,
  173. resource_size(res_mem));
  174. master->num_chipselect = 4;
  175. master->mode_bits = SPI_CPHA |
  176. SPI_CPOL |
  177. SPI_CS_HIGH |
  178. SPI_LSB_FIRST |
  179. SPI_3WIRE;
  180. master->transfer_one_message = octeon_spi_transfer_one_message;
  181. master->bits_per_word_mask = SPI_BPW_MASK(8);
  182. master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
  183. master->dev.of_node = pdev->dev.of_node;
  184. err = devm_spi_register_master(&pdev->dev, master);
  185. if (err) {
  186. dev_err(&pdev->dev, "register master failed: %d\n", err);
  187. goto fail;
  188. }
  189. dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
  190. return 0;
  191. fail:
  192. spi_master_put(master);
  193. return err;
  194. }
  195. static int octeon_spi_remove(struct platform_device *pdev)
  196. {
  197. struct spi_master *master = platform_get_drvdata(pdev);
  198. struct octeon_spi *p = spi_master_get_devdata(master);
  199. u64 register_base = p->register_base;
  200. /* Clear the CSENA* and put everything in a known state. */
  201. cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
  202. return 0;
  203. }
  204. static const struct of_device_id octeon_spi_match[] = {
  205. { .compatible = "cavium,octeon-3010-spi", },
  206. {},
  207. };
  208. MODULE_DEVICE_TABLE(of, octeon_spi_match);
  209. static struct platform_driver octeon_spi_driver = {
  210. .driver = {
  211. .name = "spi-octeon",
  212. .of_match_table = octeon_spi_match,
  213. },
  214. .probe = octeon_spi_probe,
  215. .remove = octeon_spi_remove,
  216. };
  217. module_platform_driver(octeon_spi_driver);
  218. MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
  219. MODULE_AUTHOR("David Daney");
  220. MODULE_LICENSE("GPL");