sun4i_spi.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * (C) Copyright 2017 Whitebox Systems / Northend Systems B.V.
  3. * S.J.R. van Schaik <stephan@whiteboxsystems.nl>
  4. * M.B.W. Wajer <merlijn@whiteboxsystems.nl>
  5. *
  6. * (C) Copyright 2017 Olimex Ltd..
  7. * Stefan Mavrodiev <stefan@olimex.com>
  8. *
  9. * Based on linux spi driver. Original copyright follows:
  10. * linux/drivers/spi/spi-sun4i.c
  11. *
  12. * Copyright (C) 2012 - 2014 Allwinner Tech
  13. * Pan Nan <pannan@allwinnertech.com>
  14. *
  15. * Copyright (C) 2014 Maxime Ripard
  16. * Maxime Ripard <maxime.ripard@free-electrons.com>
  17. *
  18. * SPDX-License-Identifier: GPL-2.0+
  19. */
  20. #include <common.h>
  21. #include <dm.h>
  22. #include <spi.h>
  23. #include <errno.h>
  24. #include <fdt_support.h>
  25. #include <wait_bit.h>
  26. #include <asm/bitops.h>
  27. #include <asm/gpio.h>
  28. #include <asm/io.h>
  29. #include <asm/arch/clock.h>
  30. #define SUN4I_FIFO_DEPTH 64
  31. #define SUN4I_RXDATA_REG 0x00
  32. #define SUN4I_TXDATA_REG 0x04
  33. #define SUN4I_CTL_REG 0x08
  34. #define SUN4I_CTL_ENABLE BIT(0)
  35. #define SUN4I_CTL_MASTER BIT(1)
  36. #define SUN4I_CTL_CPHA BIT(2)
  37. #define SUN4I_CTL_CPOL BIT(3)
  38. #define SUN4I_CTL_CS_ACTIVE_LOW BIT(4)
  39. #define SUN4I_CTL_LMTF BIT(6)
  40. #define SUN4I_CTL_TF_RST BIT(8)
  41. #define SUN4I_CTL_RF_RST BIT(9)
  42. #define SUN4I_CTL_XCH_MASK 0x0400
  43. #define SUN4I_CTL_XCH BIT(10)
  44. #define SUN4I_CTL_CS_MASK 0x3000
  45. #define SUN4I_CTL_CS(cs) (((cs) << 12) & SUN4I_CTL_CS_MASK)
  46. #define SUN4I_CTL_DHB BIT(15)
  47. #define SUN4I_CTL_CS_MANUAL BIT(16)
  48. #define SUN4I_CTL_CS_LEVEL BIT(17)
  49. #define SUN4I_CTL_TP BIT(18)
  50. #define SUN4I_INT_CTL_REG 0x0c
  51. #define SUN4I_INT_CTL_RF_F34 BIT(4)
  52. #define SUN4I_INT_CTL_TF_E34 BIT(12)
  53. #define SUN4I_INT_CTL_TC BIT(16)
  54. #define SUN4I_INT_STA_REG 0x10
  55. #define SUN4I_DMA_CTL_REG 0x14
  56. #define SUN4I_WAIT_REG 0x18
  57. #define SUN4I_CLK_CTL_REG 0x1c
  58. #define SUN4I_CLK_CTL_CDR2_MASK 0xff
  59. #define SUN4I_CLK_CTL_CDR2(div) ((div) & SUN4I_CLK_CTL_CDR2_MASK)
  60. #define SUN4I_CLK_CTL_CDR1_MASK 0xf
  61. #define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
  62. #define SUN4I_CLK_CTL_DRS BIT(12)
  63. #define SUN4I_MAX_XFER_SIZE 0xffffff
  64. #define SUN4I_BURST_CNT_REG 0x20
  65. #define SUN4I_BURST_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE)
  66. #define SUN4I_XMIT_CNT_REG 0x24
  67. #define SUN4I_XMIT_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE)
  68. #define SUN4I_FIFO_STA_REG 0x28
  69. #define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f
  70. #define SUN4I_FIFO_STA_RF_CNT_BITS 0
  71. #define SUN4I_FIFO_STA_TF_CNT_MASK 0x7f
  72. #define SUN4I_FIFO_STA_TF_CNT_BITS 16
  73. #define SUN4I_SPI_MAX_RATE 24000000
  74. #define SUN4I_SPI_MIN_RATE 3000
  75. #define SUN4I_SPI_DEFAULT_RATE 1000000
  76. #define SUN4I_SPI_TIMEOUT_US 1000000
  77. /* sun4i spi register set */
  78. struct sun4i_spi_regs {
  79. u32 rxdata;
  80. u32 txdata;
  81. u32 ctl;
  82. u32 intctl;
  83. u32 st;
  84. u32 dmactl;
  85. u32 wait;
  86. u32 cctl;
  87. u32 bc;
  88. u32 tc;
  89. u32 fifo_sta;
  90. };
  91. struct sun4i_spi_platdata {
  92. u32 base_addr;
  93. u32 max_hz;
  94. };
  95. struct sun4i_spi_priv {
  96. struct sun4i_spi_regs *regs;
  97. u32 freq;
  98. u32 mode;
  99. const u8 *tx_buf;
  100. u8 *rx_buf;
  101. };
  102. DECLARE_GLOBAL_DATA_PTR;
  103. static inline void sun4i_spi_drain_fifo(struct sun4i_spi_priv *priv, int len)
  104. {
  105. u8 byte;
  106. while (len--) {
  107. byte = readb(&priv->regs->rxdata);
  108. *priv->rx_buf++ = byte;
  109. }
  110. }
  111. static inline void sun4i_spi_fill_fifo(struct sun4i_spi_priv *priv, int len)
  112. {
  113. u8 byte;
  114. while (len--) {
  115. byte = priv->tx_buf ? *priv->tx_buf++ : 0;
  116. writeb(byte, &priv->regs->txdata);
  117. }
  118. }
  119. static void sun4i_spi_set_cs(struct udevice *bus, u8 cs, bool enable)
  120. {
  121. struct sun4i_spi_priv *priv = dev_get_priv(bus);
  122. u32 reg;
  123. reg = readl(&priv->regs->ctl);
  124. reg &= ~SUN4I_CTL_CS_MASK;
  125. reg |= SUN4I_CTL_CS(cs);
  126. if (enable)
  127. reg &= ~SUN4I_CTL_CS_LEVEL;
  128. else
  129. reg |= SUN4I_CTL_CS_LEVEL;
  130. writel(reg, &priv->regs->ctl);
  131. }
  132. static int sun4i_spi_parse_pins(struct udevice *dev)
  133. {
  134. const void *fdt = gd->fdt_blob;
  135. const char *pin_name;
  136. const fdt32_t *list;
  137. u32 phandle;
  138. int drive, pull = 0, pin, i;
  139. int offset;
  140. int size;
  141. list = fdt_getprop(fdt, dev_of_offset(dev), "pinctrl-0", &size);
  142. if (!list) {
  143. printf("WARNING: sun4i_spi: cannot find pinctrl-0 node\n");
  144. return -EINVAL;
  145. }
  146. while (size) {
  147. phandle = fdt32_to_cpu(*list++);
  148. size -= sizeof(*list);
  149. offset = fdt_node_offset_by_phandle(fdt, phandle);
  150. if (offset < 0)
  151. return offset;
  152. drive = fdt_getprop_u32_default_node(fdt, offset, 0,
  153. "drive-strength", 0);
  154. if (drive) {
  155. if (drive <= 10)
  156. drive = 0;
  157. else if (drive <= 20)
  158. drive = 1;
  159. else if (drive <= 30)
  160. drive = 2;
  161. else
  162. drive = 3;
  163. } else {
  164. drive = fdt_getprop_u32_default_node(fdt, offset, 0,
  165. "allwinner,drive",
  166. 0);
  167. drive = min(drive, 3);
  168. }
  169. if (fdt_get_property(fdt, offset, "bias-disable", NULL))
  170. pull = 0;
  171. else if (fdt_get_property(fdt, offset, "bias-pull-up", NULL))
  172. pull = 1;
  173. else if (fdt_get_property(fdt, offset, "bias-pull-down", NULL))
  174. pull = 2;
  175. else
  176. pull = fdt_getprop_u32_default_node(fdt, offset, 0,
  177. "allwinner,pull",
  178. 0);
  179. pull = min(pull, 2);
  180. for (i = 0; ; i++) {
  181. pin_name = fdt_stringlist_get(fdt, offset,
  182. "pins", i, NULL);
  183. if (!pin_name) {
  184. pin_name = fdt_stringlist_get(fdt, offset,
  185. "allwinner,pins",
  186. i, NULL);
  187. if (!pin_name)
  188. break;
  189. }
  190. pin = name_to_gpio(pin_name);
  191. if (pin < 0)
  192. break;
  193. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0);
  194. sunxi_gpio_set_drv(pin, drive);
  195. sunxi_gpio_set_pull(pin, pull);
  196. }
  197. }
  198. return 0;
  199. }
  200. static inline void sun4i_spi_enable_clock(void)
  201. {
  202. struct sunxi_ccm_reg *const ccm =
  203. (struct sunxi_ccm_reg *const)SUNXI_CCM_BASE;
  204. setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0));
  205. writel((1 << 31), &ccm->spi0_clk_cfg);
  206. }
  207. static int sun4i_spi_ofdata_to_platdata(struct udevice *bus)
  208. {
  209. struct sun4i_spi_platdata *plat = dev_get_platdata(bus);
  210. int node = dev_of_offset(bus);
  211. plat->base_addr = devfdt_get_addr(bus);
  212. plat->max_hz = fdtdec_get_int(gd->fdt_blob, node,
  213. "spi-max-frequency",
  214. SUN4I_SPI_DEFAULT_RATE);
  215. if (plat->max_hz > SUN4I_SPI_MAX_RATE)
  216. plat->max_hz = SUN4I_SPI_MAX_RATE;
  217. return 0;
  218. }
  219. static int sun4i_spi_probe(struct udevice *bus)
  220. {
  221. struct sun4i_spi_platdata *plat = dev_get_platdata(bus);
  222. struct sun4i_spi_priv *priv = dev_get_priv(bus);
  223. sun4i_spi_enable_clock();
  224. sun4i_spi_parse_pins(bus);
  225. priv->regs = (struct sun4i_spi_regs *)(uintptr_t)plat->base_addr;
  226. priv->freq = plat->max_hz;
  227. return 0;
  228. }
  229. static int sun4i_spi_claim_bus(struct udevice *dev)
  230. {
  231. struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
  232. writel(SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP |
  233. SUN4I_CTL_CS_MANUAL | SUN4I_CTL_CS_ACTIVE_LOW,
  234. &priv->regs->ctl);
  235. return 0;
  236. }
  237. static int sun4i_spi_release_bus(struct udevice *dev)
  238. {
  239. struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
  240. u32 reg;
  241. reg = readl(&priv->regs->ctl);
  242. reg &= ~SUN4I_CTL_ENABLE;
  243. writel(reg, &priv->regs->ctl);
  244. return 0;
  245. }
  246. static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
  247. const void *dout, void *din, unsigned long flags)
  248. {
  249. struct udevice *bus = dev->parent;
  250. struct sun4i_spi_priv *priv = dev_get_priv(bus);
  251. struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
  252. u32 len = bitlen / 8;
  253. u32 reg;
  254. u8 nbytes;
  255. int ret;
  256. priv->tx_buf = dout;
  257. priv->rx_buf = din;
  258. if (bitlen % 8) {
  259. debug("%s: non byte-aligned SPI transfer.\n", __func__);
  260. return -ENAVAIL;
  261. }
  262. if (flags & SPI_XFER_BEGIN)
  263. sun4i_spi_set_cs(bus, slave_plat->cs, true);
  264. reg = readl(&priv->regs->ctl);
  265. /* Reset FIFOs */
  266. writel(reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST, &priv->regs->ctl);
  267. while (len) {
  268. /* Setup the transfer now... */
  269. nbytes = min(len, (u32)(SUN4I_FIFO_DEPTH - 1));
  270. /* Setup the counters */
  271. writel(SUN4I_BURST_CNT(nbytes), &priv->regs->bc);
  272. writel(SUN4I_XMIT_CNT(nbytes), &priv->regs->tc);
  273. /* Fill the TX FIFO */
  274. sun4i_spi_fill_fifo(priv, nbytes);
  275. /* Start the transfer */
  276. reg = readl(&priv->regs->ctl);
  277. writel(reg | SUN4I_CTL_XCH, &priv->regs->ctl);
  278. /* Wait transfer to complete */
  279. ret = wait_for_bit_le32(&priv->regs->ctl, SUN4I_CTL_XCH_MASK,
  280. false, SUN4I_SPI_TIMEOUT_US, false);
  281. if (ret) {
  282. printf("ERROR: sun4i_spi: Timeout transferring data\n");
  283. sun4i_spi_set_cs(bus, slave_plat->cs, false);
  284. return ret;
  285. }
  286. /* Drain the RX FIFO */
  287. sun4i_spi_drain_fifo(priv, nbytes);
  288. len -= nbytes;
  289. }
  290. if (flags & SPI_XFER_END)
  291. sun4i_spi_set_cs(bus, slave_plat->cs, false);
  292. return 0;
  293. }
  294. static int sun4i_spi_set_speed(struct udevice *dev, uint speed)
  295. {
  296. struct sun4i_spi_platdata *plat = dev_get_platdata(dev);
  297. struct sun4i_spi_priv *priv = dev_get_priv(dev);
  298. unsigned int div;
  299. u32 reg;
  300. if (speed > plat->max_hz)
  301. speed = plat->max_hz;
  302. if (speed < SUN4I_SPI_MIN_RATE)
  303. speed = SUN4I_SPI_MIN_RATE;
  304. /*
  305. * Setup clock divider.
  306. *
  307. * We have two choices there. Either we can use the clock
  308. * divide rate 1, which is calculated thanks to this formula:
  309. * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1))
  310. * Or we can use CDR2, which is calculated with the formula:
  311. * SPI_CLK = MOD_CLK / (2 * (cdr + 1))
  312. * Whether we use the former or the latter is set through the
  313. * DRS bit.
  314. *
  315. * First try CDR2, and if we can't reach the expected
  316. * frequency, fall back to CDR1.
  317. */
  318. div = SUN4I_SPI_MAX_RATE / (2 * speed);
  319. reg = readl(&priv->regs->cctl);
  320. if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  321. if (div > 0)
  322. div--;
  323. reg &= ~(SUN4I_CLK_CTL_CDR2_MASK | SUN4I_CLK_CTL_DRS);
  324. reg |= SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  325. } else {
  326. div = __ilog2(SUN4I_SPI_MAX_RATE) - __ilog2(speed);
  327. reg &= ~((SUN4I_CLK_CTL_CDR1_MASK << 8) | SUN4I_CLK_CTL_DRS);
  328. reg |= SUN4I_CLK_CTL_CDR1(div);
  329. }
  330. priv->freq = speed;
  331. writel(reg, &priv->regs->cctl);
  332. return 0;
  333. }
  334. static int sun4i_spi_set_mode(struct udevice *dev, uint mode)
  335. {
  336. struct sun4i_spi_priv *priv = dev_get_priv(dev);
  337. u32 reg;
  338. reg = readl(&priv->regs->ctl);
  339. reg &= ~(SUN4I_CTL_CPOL | SUN4I_CTL_CPHA);
  340. if (mode & SPI_CPOL)
  341. reg |= SUN4I_CTL_CPOL;
  342. if (mode & SPI_CPHA)
  343. reg |= SUN4I_CTL_CPHA;
  344. priv->mode = mode;
  345. writel(reg, &priv->regs->ctl);
  346. return 0;
  347. }
  348. static const struct dm_spi_ops sun4i_spi_ops = {
  349. .claim_bus = sun4i_spi_claim_bus,
  350. .release_bus = sun4i_spi_release_bus,
  351. .xfer = sun4i_spi_xfer,
  352. .set_speed = sun4i_spi_set_speed,
  353. .set_mode = sun4i_spi_set_mode,
  354. };
  355. static const struct udevice_id sun4i_spi_ids[] = {
  356. { .compatible = "allwinner,sun4i-a10-spi" },
  357. { }
  358. };
  359. U_BOOT_DRIVER(sun4i_spi) = {
  360. .name = "sun4i_spi",
  361. .id = UCLASS_SPI,
  362. .of_match = sun4i_spi_ids,
  363. .ops = &sun4i_spi_ops,
  364. .ofdata_to_platdata = sun4i_spi_ofdata_to_platdata,
  365. .platdata_auto_alloc_size = sizeof(struct sun4i_spi_platdata),
  366. .priv_auto_alloc_size = sizeof(struct sun4i_spi_priv),
  367. .probe = sun4i_spi_probe,
  368. };