serial_msm.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Qualcomm UART driver
  4. *
  5. * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
  6. *
  7. * UART will work in Data Mover mode.
  8. * Based on Linux driver.
  9. */
  10. #include <common.h>
  11. #include <clk.h>
  12. #include <dm.h>
  13. #include <errno.h>
  14. #include <serial.h>
  15. #include <watchdog.h>
  16. #include <asm/io.h>
  17. #include <linux/compiler.h>
  18. #include <dm/pinctrl.h>
  19. /* Serial registers - this driver works in uartdm mode*/
  20. #define UARTDM_DMRX 0x34 /* Max RX transfer length */
  21. #define UARTDM_NCF_TX 0x40 /* Number of chars to TX */
  22. #define UARTDM_RXFS 0x50 /* RX channel status register */
  23. #define UARTDM_RXFS_BUF_SHIFT 0x7 /* Number of bytes in the packing buffer */
  24. #define UARTDM_RXFS_BUF_MASK 0x7
  25. #define UARTDM_MR1 0x00
  26. #define UARTDM_MR2 0x04
  27. #define UARTDM_CSR 0xA0
  28. #define UARTDM_SR 0xA4 /* Status register */
  29. #define UARTDM_SR_RX_READY (1 << 0) /* Word is the receiver FIFO */
  30. #define UARTDM_SR_TX_EMPTY (1 << 3) /* Transmitter underrun */
  31. #define UARTDM_SR_UART_OVERRUN (1 << 4) /* Receive overrun */
  32. #define UARTDM_CR 0xA8 /* Command register */
  33. #define UARTDM_CR_CMD_RESET_ERR (3 << 4) /* Clear overrun error */
  34. #define UARTDM_CR_CMD_RESET_STALE_INT (8 << 4) /* Clears stale irq */
  35. #define UARTDM_CR_CMD_RESET_TX_READY (3 << 8) /* Clears TX Ready irq*/
  36. #define UARTDM_CR_CMD_FORCE_STALE (4 << 8) /* Causes stale event */
  37. #define UARTDM_CR_CMD_STALE_EVENT_DISABLE (6 << 8) /* Disable stale event */
  38. #define UARTDM_IMR 0xB0 /* Interrupt mask register */
  39. #define UARTDM_ISR 0xB4 /* Interrupt status register */
  40. #define UARTDM_ISR_TX_READY 0x80 /* TX FIFO empty */
  41. #define UARTDM_TF 0x100 /* UART Transmit FIFO register */
  42. #define UARTDM_RF 0x140 /* UART Receive FIFO register */
  43. #define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
  44. #define MSM_BOOT_UART_DM_8_N_1_MODE 0x34
  45. #define MSM_BOOT_UART_DM_CMD_RESET_RX 0x10
  46. #define MSM_BOOT_UART_DM_CMD_RESET_TX 0x20
  47. DECLARE_GLOBAL_DATA_PTR;
  48. struct msm_serial_data {
  49. phys_addr_t base;
  50. unsigned chars_cnt; /* number of buffered chars */
  51. uint32_t chars_buf; /* buffered chars */
  52. };
  53. static int msm_serial_fetch(struct udevice *dev)
  54. {
  55. struct msm_serial_data *priv = dev_get_priv(dev);
  56. unsigned sr;
  57. if (priv->chars_cnt)
  58. return priv->chars_cnt;
  59. /* Clear error in case of buffer overrun */
  60. if (readl(priv->base + UARTDM_SR) & UARTDM_SR_UART_OVERRUN)
  61. writel(UARTDM_CR_CMD_RESET_ERR, priv->base + UARTDM_CR);
  62. /* We need to fetch new character */
  63. sr = readl(priv->base + UARTDM_SR);
  64. if (sr & UARTDM_SR_RX_READY) {
  65. /* There are at least 4 bytes in fifo */
  66. priv->chars_buf = readl(priv->base + UARTDM_RF);
  67. priv->chars_cnt = 4;
  68. } else {
  69. /* Check if there is anything in fifo */
  70. priv->chars_cnt = readl(priv->base + UARTDM_RXFS);
  71. /* Extract number of characters in UART packing buffer*/
  72. priv->chars_cnt = (priv->chars_cnt >>
  73. UARTDM_RXFS_BUF_SHIFT) &
  74. UARTDM_RXFS_BUF_MASK;
  75. if (!priv->chars_cnt)
  76. return 0;
  77. /* There is at least one charcter, move it to fifo */
  78. writel(UARTDM_CR_CMD_FORCE_STALE,
  79. priv->base + UARTDM_CR);
  80. priv->chars_buf = readl(priv->base + UARTDM_RF);
  81. writel(UARTDM_CR_CMD_RESET_STALE_INT,
  82. priv->base + UARTDM_CR);
  83. writel(0x7, priv->base + UARTDM_DMRX);
  84. }
  85. return priv->chars_cnt;
  86. }
  87. static int msm_serial_getc(struct udevice *dev)
  88. {
  89. struct msm_serial_data *priv = dev_get_priv(dev);
  90. char c;
  91. if (!msm_serial_fetch(dev))
  92. return -EAGAIN;
  93. c = priv->chars_buf & 0xFF;
  94. priv->chars_buf >>= 8;
  95. priv->chars_cnt--;
  96. return c;
  97. }
  98. static int msm_serial_putc(struct udevice *dev, const char ch)
  99. {
  100. struct msm_serial_data *priv = dev_get_priv(dev);
  101. if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_EMPTY) &&
  102. !(readl(priv->base + UARTDM_ISR) & UARTDM_ISR_TX_READY))
  103. return -EAGAIN;
  104. writel(UARTDM_CR_CMD_RESET_TX_READY, priv->base + UARTDM_CR);
  105. writel(1, priv->base + UARTDM_NCF_TX);
  106. writel(ch, priv->base + UARTDM_TF);
  107. return 0;
  108. }
  109. static int msm_serial_pending(struct udevice *dev, bool input)
  110. {
  111. if (input) {
  112. if (msm_serial_fetch(dev))
  113. return 1;
  114. }
  115. return 0;
  116. }
  117. static const struct dm_serial_ops msm_serial_ops = {
  118. .putc = msm_serial_putc,
  119. .pending = msm_serial_pending,
  120. .getc = msm_serial_getc,
  121. };
  122. static int msm_uart_clk_init(struct udevice *dev)
  123. {
  124. uint clk_rate = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
  125. "clock-frequency", 115200);
  126. uint clkd[2]; /* clk_id and clk_no */
  127. int clk_offset;
  128. struct udevice *clk_dev;
  129. struct clk clk;
  130. int ret;
  131. ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "clock",
  132. clkd, 2);
  133. if (ret)
  134. return ret;
  135. clk_offset = fdt_node_offset_by_phandle(gd->fdt_blob, clkd[0]);
  136. if (clk_offset < 0)
  137. return clk_offset;
  138. ret = uclass_get_device_by_of_offset(UCLASS_CLK, clk_offset, &clk_dev);
  139. if (ret)
  140. return ret;
  141. clk.id = clkd[1];
  142. ret = clk_request(clk_dev, &clk);
  143. if (ret < 0)
  144. return ret;
  145. ret = clk_set_rate(&clk, clk_rate);
  146. clk_free(&clk);
  147. if (ret < 0)
  148. return ret;
  149. return 0;
  150. }
  151. static void uart_dm_init(struct msm_serial_data *priv)
  152. {
  153. writel(UART_DM_CLK_RX_TX_BIT_RATE, priv->base + UARTDM_CSR);
  154. writel(0x0, priv->base + UARTDM_MR1);
  155. writel(MSM_BOOT_UART_DM_8_N_1_MODE, priv->base + UARTDM_MR2);
  156. writel(MSM_BOOT_UART_DM_CMD_RESET_RX, priv->base + UARTDM_CR);
  157. writel(MSM_BOOT_UART_DM_CMD_RESET_TX, priv->base + UARTDM_CR);
  158. }
  159. static int msm_serial_probe(struct udevice *dev)
  160. {
  161. int ret;
  162. struct msm_serial_data *priv = dev_get_priv(dev);
  163. /* No need to reinitialize the UART after relocation */
  164. if (gd->flags & GD_FLG_RELOC)
  165. return 0;
  166. ret = msm_uart_clk_init(dev);
  167. if (ret)
  168. return ret;
  169. pinctrl_select_state(dev, "uart");
  170. uart_dm_init(priv);
  171. return 0;
  172. }
  173. static int msm_serial_ofdata_to_platdata(struct udevice *dev)
  174. {
  175. struct msm_serial_data *priv = dev_get_priv(dev);
  176. priv->base = devfdt_get_addr(dev);
  177. if (priv->base == FDT_ADDR_T_NONE)
  178. return -EINVAL;
  179. return 0;
  180. }
  181. static const struct udevice_id msm_serial_ids[] = {
  182. { .compatible = "qcom,msm-uartdm-v1.4" },
  183. { }
  184. };
  185. U_BOOT_DRIVER(serial_msm) = {
  186. .name = "serial_msm",
  187. .id = UCLASS_SERIAL,
  188. .of_match = msm_serial_ids,
  189. .ofdata_to_platdata = msm_serial_ofdata_to_platdata,
  190. .priv_auto_alloc_size = sizeof(struct msm_serial_data),
  191. .probe = msm_serial_probe,
  192. .ops = &msm_serial_ops,
  193. };