ath79_spi.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
  4. */
  5. #include <common.h>
  6. #include <clock_legacy.h>
  7. #include <spi.h>
  8. #include <dm.h>
  9. #include <div64.h>
  10. #include <errno.h>
  11. #include <time.h>
  12. #include <asm/io.h>
  13. #include <asm/addrspace.h>
  14. #include <asm/types.h>
  15. #include <dm/pinctrl.h>
  16. #include <mach/ar71xx_regs.h>
  17. /* CLOCK_DIVIDER = 3 (SPI clock = 200 / 8 ~ 25 MHz) */
  18. #define ATH79_SPI_CLK_DIV(x) (((x) >> 1) - 1)
  19. #define ATH79_SPI_RRW_DELAY_FACTOR 12000
  20. #define ATH79_SPI_MHZ (1000 * 1000)
  21. struct ath79_spi_priv {
  22. void __iomem *regs;
  23. u32 rrw_delay;
  24. };
  25. static void spi_cs_activate(struct udevice *dev)
  26. {
  27. struct udevice *bus = dev_get_parent(dev);
  28. struct ath79_spi_priv *priv = dev_get_priv(bus);
  29. writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
  30. writel(AR71XX_SPI_IOC_CS_ALL, priv->regs + AR71XX_SPI_REG_IOC);
  31. }
  32. static void spi_cs_deactivate(struct udevice *dev)
  33. {
  34. struct udevice *bus = dev_get_parent(dev);
  35. struct ath79_spi_priv *priv = dev_get_priv(bus);
  36. writel(AR71XX_SPI_IOC_CS_ALL, priv->regs + AR71XX_SPI_REG_IOC);
  37. writel(0, priv->regs + AR71XX_SPI_REG_FS);
  38. }
  39. static int ath79_spi_claim_bus(struct udevice *dev)
  40. {
  41. return 0;
  42. }
  43. static int ath79_spi_release_bus(struct udevice *dev)
  44. {
  45. return 0;
  46. }
  47. static int ath79_spi_xfer(struct udevice *dev, unsigned int bitlen,
  48. const void *dout, void *din, unsigned long flags)
  49. {
  50. struct udevice *bus = dev_get_parent(dev);
  51. struct ath79_spi_priv *priv = dev_get_priv(bus);
  52. struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
  53. u8 *rx = din;
  54. const u8 *tx = dout;
  55. u8 curbyte, curbitlen, restbits;
  56. u32 bytes = bitlen / 8;
  57. u32 out, in;
  58. u64 tick;
  59. if (flags & SPI_XFER_BEGIN)
  60. spi_cs_activate(dev);
  61. restbits = (bitlen % 8);
  62. if (restbits)
  63. bytes++;
  64. out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
  65. while (bytes > 0) {
  66. bytes--;
  67. curbyte = 0;
  68. if (tx)
  69. curbyte = *tx++;
  70. if (restbits && !bytes) {
  71. curbitlen = restbits;
  72. curbyte <<= 8 - restbits;
  73. } else {
  74. curbitlen = 8;
  75. }
  76. for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) {
  77. if (curbyte & 0x80)
  78. out |= AR71XX_SPI_IOC_DO;
  79. else
  80. out &= ~(AR71XX_SPI_IOC_DO);
  81. writel(out, priv->regs + AR71XX_SPI_REG_IOC);
  82. /* delay for low level */
  83. if (priv->rrw_delay) {
  84. tick = get_ticks() + priv->rrw_delay;
  85. while (get_ticks() < tick)
  86. /*NOP*/;
  87. }
  88. writel(out | AR71XX_SPI_IOC_CLK,
  89. priv->regs + AR71XX_SPI_REG_IOC);
  90. /* delay for high level */
  91. if (priv->rrw_delay) {
  92. tick = get_ticks() + priv->rrw_delay;
  93. while (get_ticks() < tick)
  94. /*NOP*/;
  95. }
  96. curbyte <<= 1;
  97. }
  98. if (!bytes)
  99. writel(out, priv->regs + AR71XX_SPI_REG_IOC);
  100. in = readl(priv->regs + AR71XX_SPI_REG_RDS);
  101. if (rx) {
  102. if (restbits && !bytes)
  103. *rx++ = (in << (8 - restbits));
  104. else
  105. *rx++ = in;
  106. }
  107. }
  108. if (flags & SPI_XFER_END)
  109. spi_cs_deactivate(dev);
  110. return 0;
  111. }
  112. static int ath79_spi_set_speed(struct udevice *bus, uint speed)
  113. {
  114. struct ath79_spi_priv *priv = dev_get_priv(bus);
  115. u32 val, div = 0;
  116. u64 time;
  117. if (speed)
  118. div = get_bus_freq(0) / speed;
  119. if (div > 63)
  120. div = 63;
  121. if (div < 5)
  122. div = 5;
  123. /* calculate delay */
  124. time = get_tbclk();
  125. do_div(time, speed / 2);
  126. val = get_bus_freq(0) / ATH79_SPI_MHZ;
  127. val = ATH79_SPI_RRW_DELAY_FACTOR / val;
  128. if (time > val)
  129. priv->rrw_delay = time - val + 1;
  130. else
  131. priv->rrw_delay = 0;
  132. writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
  133. clrsetbits_be32(priv->regs + AR71XX_SPI_REG_CTRL,
  134. AR71XX_SPI_CTRL_DIV_MASK,
  135. ATH79_SPI_CLK_DIV(div));
  136. writel(0, priv->regs + AR71XX_SPI_REG_FS);
  137. return 0;
  138. }
  139. static int ath79_spi_set_mode(struct udevice *bus, uint mode)
  140. {
  141. return 0;
  142. }
  143. static int ath79_spi_probe(struct udevice *bus)
  144. {
  145. struct ath79_spi_priv *priv = dev_get_priv(bus);
  146. fdt_addr_t addr;
  147. addr = devfdt_get_addr(bus);
  148. if (addr == FDT_ADDR_T_NONE)
  149. return -EINVAL;
  150. priv->regs = map_physmem(addr,
  151. AR71XX_SPI_SIZE,
  152. MAP_NOCACHE);
  153. /* Init SPI Hardware, disable remap, set clock */
  154. writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
  155. writel(AR71XX_SPI_CTRL_RD | ATH79_SPI_CLK_DIV(8),
  156. priv->regs + AR71XX_SPI_REG_CTRL);
  157. writel(0, priv->regs + AR71XX_SPI_REG_FS);
  158. return 0;
  159. }
  160. static int ath79_cs_info(struct udevice *bus, uint cs,
  161. struct spi_cs_info *info)
  162. {
  163. /* Always allow activity on CS 0/1/2 */
  164. if (cs >= 3)
  165. return -EINVAL;
  166. return 0;
  167. }
  168. static const struct dm_spi_ops ath79_spi_ops = {
  169. .claim_bus = ath79_spi_claim_bus,
  170. .release_bus = ath79_spi_release_bus,
  171. .xfer = ath79_spi_xfer,
  172. .set_speed = ath79_spi_set_speed,
  173. .set_mode = ath79_spi_set_mode,
  174. .cs_info = ath79_cs_info,
  175. };
  176. static const struct udevice_id ath79_spi_ids[] = {
  177. { .compatible = "qca,ar7100-spi" },
  178. {}
  179. };
  180. U_BOOT_DRIVER(ath79_spi) = {
  181. .name = "ath79_spi",
  182. .id = UCLASS_SPI,
  183. .of_match = ath79_spi_ids,
  184. .ops = &ath79_spi_ops,
  185. .priv_auto_alloc_size = sizeof(struct ath79_spi_priv),
  186. .probe = ath79_spi_probe,
  187. };