mt7621_spi.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018 Stefan Roese <sr@denx.de>
  4. *
  5. * Derived from the Linux driver version drivers/spi/spi-mt7621.c
  6. * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
  7. * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
  8. * Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
  9. */
  10. #include <common.h>
  11. #include <clk.h>
  12. #include <dm.h>
  13. #include <log.h>
  14. #include <spi.h>
  15. #include <wait_bit.h>
  16. #include <linux/bitops.h>
  17. #include <linux/io.h>
  18. #define MT7621_RX_FIFO_LEN 32
  19. #define MT7621_TX_FIFO_LEN 36
  20. #define MT7621_SPI_TRANS 0x00
  21. #define MT7621_SPI_TRANS_START BIT(8)
  22. #define MT7621_SPI_TRANS_BUSY BIT(16)
  23. #define TRANS_ADDR_SZ GENMASK(20, 19)
  24. #define TRANS_ADDR_SZ_SHIFT 19
  25. #define TRANS_MOSI_BCNT GENMASK(3, 0)
  26. #define TRANS_MOSI_BCNT_SHIFT 0
  27. #define MT7621_SPI_OPCODE 0x04
  28. #define MT7621_SPI_DATA0 0x08
  29. #define MT7621_SPI_DATA4 0x18
  30. #define MT7621_SPI_MASTER 0x28
  31. #define MT7621_SPI_MOREBUF 0x2c
  32. #define MT7621_SPI_POLAR 0x38
  33. #define MT7621_LSB_FIRST BIT(3)
  34. #define MT7621_CPOL BIT(4)
  35. #define MT7621_CPHA BIT(5)
  36. #define MASTER_MORE_BUFMODE BIT(2)
  37. #define MASTER_RS_CLK_SEL GENMASK(27, 16)
  38. #define MASTER_RS_CLK_SEL_SHIFT 16
  39. #define MASTER_RS_SLAVE_SEL GENMASK(31, 29)
  40. #define MOREBUF_CMD_CNT GENMASK(29, 24)
  41. #define MOREBUF_CMD_CNT_SHIFT 24
  42. #define MOREBUF_MISO_CNT GENMASK(20, 12)
  43. #define MOREBUF_MISO_CNT_SHIFT 12
  44. #define MOREBUF_MOSI_CNT GENMASK(8, 0)
  45. #define MOREBUF_MOSI_CNT_SHIFT 0
  46. struct mt7621_spi {
  47. void __iomem *base;
  48. unsigned int sys_freq;
  49. };
  50. static void mt7621_spi_set_cs(struct mt7621_spi *rs, int cs, int enable)
  51. {
  52. debug("%s: cs#%d -> %s\n", __func__, cs, enable ? "enable" : "disable");
  53. if (enable) {
  54. setbits_le32(rs->base + MT7621_SPI_MASTER,
  55. MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
  56. iowrite32(BIT(cs), rs->base + MT7621_SPI_POLAR);
  57. } else {
  58. iowrite32(0, rs->base + MT7621_SPI_POLAR);
  59. iowrite32((2 << TRANS_ADDR_SZ_SHIFT) |
  60. (1 << TRANS_MOSI_BCNT_SHIFT),
  61. rs->base + MT7621_SPI_TRANS);
  62. clrbits_le32(rs->base + MT7621_SPI_MASTER,
  63. MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
  64. }
  65. }
  66. static int mt7621_spi_set_mode(struct udevice *bus, uint mode)
  67. {
  68. struct mt7621_spi *rs = dev_get_priv(bus);
  69. u32 reg;
  70. debug("%s: mode=0x%08x\n", __func__, mode);
  71. reg = ioread32(rs->base + MT7621_SPI_MASTER);
  72. reg &= ~MT7621_LSB_FIRST;
  73. if (mode & SPI_LSB_FIRST)
  74. reg |= MT7621_LSB_FIRST;
  75. reg &= ~(MT7621_CPHA | MT7621_CPOL);
  76. switch (mode & (SPI_CPOL | SPI_CPHA)) {
  77. case SPI_MODE_0:
  78. break;
  79. case SPI_MODE_1:
  80. reg |= MT7621_CPHA;
  81. break;
  82. case SPI_MODE_2:
  83. reg |= MT7621_CPOL;
  84. break;
  85. case SPI_MODE_3:
  86. reg |= MT7621_CPOL | MT7621_CPHA;
  87. break;
  88. }
  89. iowrite32(reg, rs->base + MT7621_SPI_MASTER);
  90. return 0;
  91. }
  92. static int mt7621_spi_set_speed(struct udevice *bus, uint speed)
  93. {
  94. struct mt7621_spi *rs = dev_get_priv(bus);
  95. u32 rate;
  96. u32 reg;
  97. debug("%s: speed=%d\n", __func__, speed);
  98. rate = DIV_ROUND_UP(rs->sys_freq, speed);
  99. debug("rate:%u\n", rate);
  100. if (rate > 4097)
  101. return -EINVAL;
  102. if (rate < 2)
  103. rate = 2;
  104. reg = ioread32(rs->base + MT7621_SPI_MASTER);
  105. reg &= ~MASTER_RS_CLK_SEL;
  106. reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT;
  107. iowrite32(reg, rs->base + MT7621_SPI_MASTER);
  108. return 0;
  109. }
  110. static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs)
  111. {
  112. int ret;
  113. ret = wait_for_bit_le32(rs->base + MT7621_SPI_TRANS,
  114. MT7621_SPI_TRANS_BUSY, 0, 10, 0);
  115. if (ret)
  116. pr_err("Timeout in %s!\n", __func__);
  117. return ret;
  118. }
  119. static int mt7621_spi_read(struct mt7621_spi *rs, u8 *buf, size_t len)
  120. {
  121. size_t rx_len;
  122. int i, ret;
  123. u32 val = 0;
  124. while (len) {
  125. rx_len = min_t(size_t, len, MT7621_RX_FIFO_LEN);
  126. iowrite32((rx_len * 8) << MOREBUF_MISO_CNT_SHIFT,
  127. rs->base + MT7621_SPI_MOREBUF);
  128. iowrite32(MT7621_SPI_TRANS_START, rs->base + MT7621_SPI_TRANS);
  129. ret = mt7621_spi_wait_till_ready(rs);
  130. if (ret)
  131. return ret;
  132. for (i = 0; i < rx_len; i++) {
  133. if ((i % 4) == 0)
  134. val = ioread32(rs->base + MT7621_SPI_DATA0 + i);
  135. *buf++ = val & 0xff;
  136. val >>= 8;
  137. }
  138. len -= rx_len;
  139. }
  140. return ret;
  141. }
  142. static int mt7621_spi_write(struct mt7621_spi *rs, const u8 *buf, size_t len)
  143. {
  144. size_t tx_len, opcode_len, dido_len;
  145. int i, ret;
  146. u32 val;
  147. while (len) {
  148. tx_len = min_t(size_t, len, MT7621_TX_FIFO_LEN);
  149. opcode_len = min_t(size_t, tx_len, 4);
  150. dido_len = tx_len - opcode_len;
  151. val = 0;
  152. for (i = 0; i < opcode_len; i++) {
  153. val <<= 8;
  154. val |= *buf++;
  155. }
  156. iowrite32(val, rs->base + MT7621_SPI_OPCODE);
  157. val = 0;
  158. for (i = 0; i < dido_len; i++) {
  159. val |= (*buf++) << ((i % 4) * 8);
  160. if ((i % 4 == 3) || (i == dido_len - 1)) {
  161. iowrite32(val, rs->base + MT7621_SPI_DATA0 +
  162. (i & ~3));
  163. val = 0;
  164. }
  165. }
  166. iowrite32(((opcode_len * 8) << MOREBUF_CMD_CNT_SHIFT) |
  167. ((dido_len * 8) << MOREBUF_MOSI_CNT_SHIFT),
  168. rs->base + MT7621_SPI_MOREBUF);
  169. iowrite32(MT7621_SPI_TRANS_START, rs->base + MT7621_SPI_TRANS);
  170. ret = mt7621_spi_wait_till_ready(rs);
  171. if (ret)
  172. return ret;
  173. len -= tx_len;
  174. }
  175. return 0;
  176. }
  177. static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen,
  178. const void *dout, void *din, unsigned long flags)
  179. {
  180. struct udevice *bus = dev->parent;
  181. struct mt7621_spi *rs = dev_get_priv(bus);
  182. int total_size = bitlen >> 3;
  183. int ret = 0;
  184. debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
  185. total_size, flags);
  186. /*
  187. * This driver only supports half-duplex, so complain and bail out
  188. * upon full-duplex messages
  189. */
  190. if (dout && din) {
  191. printf("Only half-duplex SPI transfer supported\n");
  192. return -EIO;
  193. }
  194. mt7621_spi_wait_till_ready(rs);
  195. /*
  196. * Set CS active upon start of SPI message. This message can
  197. * be split upon multiple calls to this xfer function
  198. */
  199. if (flags & SPI_XFER_BEGIN)
  200. mt7621_spi_set_cs(rs, spi_chip_select(dev), 1);
  201. if (din)
  202. ret = mt7621_spi_read(rs, din, total_size);
  203. else if (dout)
  204. ret = mt7621_spi_write(rs, dout, total_size);
  205. if (flags & SPI_XFER_END)
  206. mt7621_spi_set_cs(rs, spi_chip_select(dev), 0);
  207. return ret;
  208. }
  209. static int mt7621_spi_probe(struct udevice *dev)
  210. {
  211. struct mt7621_spi *rs = dev_get_priv(dev);
  212. struct clk clk;
  213. int ret;
  214. rs->base = dev_remap_addr(dev);
  215. if (!rs->base)
  216. return -EINVAL;
  217. ret = clk_get_by_index(dev, 0, &clk);
  218. if (ret < 0) {
  219. printf("Please provide a clock!\n");
  220. return ret;
  221. }
  222. clk_enable(&clk);
  223. rs->sys_freq = clk_get_rate(&clk);
  224. if (!rs->sys_freq) {
  225. printf("Please provide a valid clock!\n");
  226. return -EINVAL;
  227. }
  228. return 0;
  229. }
  230. static const struct dm_spi_ops mt7621_spi_ops = {
  231. .set_mode = mt7621_spi_set_mode,
  232. .set_speed = mt7621_spi_set_speed,
  233. .xfer = mt7621_spi_xfer,
  234. /*
  235. * cs_info is not needed, since we require all chip selects to be
  236. * in the device tree explicitly
  237. */
  238. };
  239. static const struct udevice_id mt7621_spi_ids[] = {
  240. { .compatible = "ralink,mt7621-spi" },
  241. { }
  242. };
  243. U_BOOT_DRIVER(mt7621_spi) = {
  244. .name = "mt7621_spi",
  245. .id = UCLASS_SPI,
  246. .of_match = mt7621_spi_ids,
  247. .ops = &mt7621_spi_ops,
  248. .priv_auto = sizeof(struct mt7621_spi),
  249. .probe = mt7621_spi_probe,
  250. };