serial_sti_asc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Support for Serial I/O using STMicroelectronics' on-chip ASC.
  4. *
  5. * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
  6. * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <log.h>
  11. #include <serial.h>
  12. #include <asm/global_data.h>
  13. #include <asm/io.h>
  14. #include <linux/bitops.h>
  15. DECLARE_GLOBAL_DATA_PTR;
  16. #define BAUDMODE 0x00001000
  17. #define RXENABLE 0x00000100
  18. #define RUN 0x00000080
  19. #define MODE 0x00000001
  20. #define MODE_8BIT 0x0001
  21. #define STOP_1BIT 0x0008
  22. #define PARITYODD 0x0020
  23. #define STA_TF BIT(9)
  24. #define STA_RBF BIT(0)
  25. struct sti_asc_uart {
  26. u32 baudrate;
  27. u32 txbuf;
  28. u32 rxbuf;
  29. u32 control;
  30. u32 inten;
  31. u32 status;
  32. u32 guardtime;
  33. u32 timeout;
  34. u32 txreset;
  35. u32 rxreset;
  36. };
  37. struct sti_asc_serial {
  38. /* address of registers in physical memory */
  39. struct sti_asc_uart *regs;
  40. };
  41. /* Values for the BAUDRATE Register */
  42. #define PCLK (200ul * 1000000ul)
  43. #define BAUDRATE_VAL_M0(bps) (PCLK / (16 * (bps)))
  44. #define BAUDRATE_VAL_M1(bps) ((bps * (1 << 14)) + (1<<13)) / (PCLK/(1 << 6))
  45. /*
  46. * MODE 0
  47. * ICCLK
  48. * ASCBaudRate = ----------------
  49. * baudrate * 16
  50. *
  51. * MODE 1
  52. * baudrate * 16 * 2^16
  53. * ASCBaudRate = ------------------------
  54. * ICCLK
  55. *
  56. * NOTE:
  57. * Mode 1 should be used for baudrates of 19200, and above, as it
  58. * has a lower deviation error than Mode 0 for higher frequencies.
  59. * Mode 0 should be used for all baudrates below 19200.
  60. */
  61. static int sti_asc_pending(struct udevice *dev, bool input)
  62. {
  63. struct sti_asc_serial *priv = dev_get_priv(dev);
  64. struct sti_asc_uart *const uart = priv->regs;
  65. unsigned long status;
  66. status = readl(&uart->status);
  67. if (input)
  68. return status & STA_RBF;
  69. else
  70. return status & STA_TF;
  71. }
  72. static int _sti_asc_serial_setbrg(struct sti_asc_uart *uart, int baudrate)
  73. {
  74. unsigned long val;
  75. int t, mode = 1;
  76. switch (baudrate) {
  77. case 9600:
  78. t = BAUDRATE_VAL_M0(9600);
  79. mode = 0;
  80. break;
  81. case 19200:
  82. t = BAUDRATE_VAL_M1(19200);
  83. break;
  84. case 38400:
  85. t = BAUDRATE_VAL_M1(38400);
  86. break;
  87. case 57600:
  88. t = BAUDRATE_VAL_M1(57600);
  89. break;
  90. default:
  91. debug("ASC: unsupported baud rate: %d, using 115200 instead.\n",
  92. baudrate);
  93. case 115200:
  94. t = BAUDRATE_VAL_M1(115200);
  95. break;
  96. }
  97. /* disable the baudrate generator */
  98. val = readl(&uart->control);
  99. writel(val & ~RUN, &uart->control);
  100. /* set baud generator reload value */
  101. writel(t, &uart->baudrate);
  102. /* reset the RX & TX buffers */
  103. writel(1, &uart->txreset);
  104. writel(1, &uart->rxreset);
  105. /* set baud generator mode */
  106. if (mode)
  107. val |= BAUDMODE;
  108. /* finally, write value and enable ASC */
  109. writel(val, &uart->control);
  110. return 0;
  111. }
  112. /* called to adjust baud-rate */
  113. static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate)
  114. {
  115. struct sti_asc_serial *priv = dev_get_priv(dev);
  116. struct sti_asc_uart *const uart = priv->regs;
  117. return _sti_asc_serial_setbrg(uart, baudrate);
  118. }
  119. /* blocking function, that returns next char */
  120. static int sti_asc_serial_getc(struct udevice *dev)
  121. {
  122. struct sti_asc_serial *priv = dev_get_priv(dev);
  123. struct sti_asc_uart *const uart = priv->regs;
  124. /* polling wait: for a char to be read */
  125. if (!sti_asc_pending(dev, true))
  126. return -EAGAIN;
  127. return readl(&uart->rxbuf);
  128. }
  129. /* write write out a single char */
  130. static int sti_asc_serial_putc(struct udevice *dev, const char c)
  131. {
  132. struct sti_asc_serial *priv = dev_get_priv(dev);
  133. struct sti_asc_uart *const uart = priv->regs;
  134. /* wait till safe to write next char */
  135. if (sti_asc_pending(dev, false))
  136. return -EAGAIN;
  137. /* finally, write next char */
  138. writel(c, &uart->txbuf);
  139. return 0;
  140. }
  141. /* initialize the ASC */
  142. static int sti_asc_serial_probe(struct udevice *dev)
  143. {
  144. struct sti_asc_serial *priv = dev_get_priv(dev);
  145. unsigned long val;
  146. fdt_addr_t base;
  147. base = dev_read_addr(dev);
  148. if (base == FDT_ADDR_T_NONE)
  149. return -EINVAL;
  150. priv->regs = (struct sti_asc_uart *)base;
  151. sti_asc_serial_setbrg(dev, gd->baudrate);
  152. /*
  153. * build up the value to be written to CONTROL
  154. * set character length, bit stop number, odd parity
  155. */
  156. val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD;
  157. writel(val, &priv->regs->control);
  158. return 0;
  159. }
  160. static const struct dm_serial_ops sti_asc_serial_ops = {
  161. .putc = sti_asc_serial_putc,
  162. .pending = sti_asc_pending,
  163. .getc = sti_asc_serial_getc,
  164. .setbrg = sti_asc_serial_setbrg,
  165. };
  166. static const struct udevice_id sti_serial_of_match[] = {
  167. { .compatible = "st,asc" },
  168. { }
  169. };
  170. U_BOOT_DRIVER(serial_sti_asc) = {
  171. .name = "serial_sti_asc",
  172. .id = UCLASS_SERIAL,
  173. .of_match = sti_serial_of_match,
  174. .ops = &sti_asc_serial_ops,
  175. .probe = sti_asc_serial_probe,
  176. .priv_auto = sizeof(struct sti_asc_serial),
  177. };