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