serial_pl01x.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * (C) Copyright 2000
  3. * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
  4. *
  5. * (C) Copyright 2004
  6. * ARM Ltd.
  7. * Philippe Robin, <philippe.robin@arm.com>
  8. *
  9. * SPDX-License-Identifier: GPL-2.0+
  10. */
  11. /* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
  12. #include <common.h>
  13. #include <dm.h>
  14. #include <errno.h>
  15. #include <watchdog.h>
  16. #include <asm/io.h>
  17. #include <serial.h>
  18. #include <dm/platform_data/serial_pl01x.h>
  19. #include <linux/compiler.h>
  20. #include "serial_pl01x_internal.h"
  21. #ifndef CONFIG_DM_SERIAL
  22. static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
  23. static enum pl01x_type pl01x_type __attribute__ ((section(".data")));
  24. static struct pl01x_regs *base_regs __attribute__ ((section(".data")));
  25. #define NUM_PORTS (sizeof(port)/sizeof(port[0]))
  26. DECLARE_GLOBAL_DATA_PTR;
  27. #endif
  28. static int pl01x_putc(struct pl01x_regs *regs, char c)
  29. {
  30. /* Wait until there is space in the FIFO */
  31. if (readl(&regs->fr) & UART_PL01x_FR_TXFF)
  32. return -EAGAIN;
  33. /* Send the character */
  34. writel(c, &regs->dr);
  35. return 0;
  36. }
  37. static int pl01x_getc(struct pl01x_regs *regs)
  38. {
  39. unsigned int data;
  40. /* Wait until there is data in the FIFO */
  41. if (readl(&regs->fr) & UART_PL01x_FR_RXFE)
  42. return -EAGAIN;
  43. data = readl(&regs->dr);
  44. /* Check for an error flag */
  45. if (data & 0xFFFFFF00) {
  46. /* Clear the error */
  47. writel(0xFFFFFFFF, &regs->ecr);
  48. return -1;
  49. }
  50. return (int) data;
  51. }
  52. static int pl01x_tstc(struct pl01x_regs *regs)
  53. {
  54. WATCHDOG_RESET();
  55. return !(readl(&regs->fr) & UART_PL01x_FR_RXFE);
  56. }
  57. static int pl01x_generic_serial_init(struct pl01x_regs *regs,
  58. enum pl01x_type type)
  59. {
  60. #ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
  61. if (type == TYPE_PL011) {
  62. /* Empty RX fifo if necessary */
  63. if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
  64. while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
  65. readl(&regs->dr);
  66. }
  67. }
  68. #endif
  69. switch (type) {
  70. case TYPE_PL010:
  71. /* disable everything */
  72. writel(0, &regs->pl010_cr);
  73. break;
  74. case TYPE_PL011:
  75. /* disable everything */
  76. writel(0, &regs->pl011_cr);
  77. break;
  78. default:
  79. return -EINVAL;
  80. }
  81. return 0;
  82. }
  83. static int set_line_control(struct pl01x_regs *regs)
  84. {
  85. unsigned int lcr;
  86. /*
  87. * Internal update of baud rate register require line
  88. * control register write
  89. */
  90. lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
  91. #ifdef CONFIG_PL011_SERIAL_RLCR
  92. {
  93. int i;
  94. /*
  95. * Program receive line control register after waiting
  96. * 10 bus cycles. Delay be writing to readonly register
  97. * 10 times
  98. */
  99. for (i = 0; i < 10; i++)
  100. writel(lcr, &regs->fr);
  101. writel(lcr, &regs->pl011_rlcr);
  102. }
  103. #endif
  104. writel(lcr, &regs->pl011_lcrh);
  105. return 0;
  106. }
  107. static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type,
  108. int clock, int baudrate)
  109. {
  110. switch (type) {
  111. case TYPE_PL010: {
  112. unsigned int divisor;
  113. switch (baudrate) {
  114. case 9600:
  115. divisor = UART_PL010_BAUD_9600;
  116. break;
  117. case 19200:
  118. divisor = UART_PL010_BAUD_9600;
  119. break;
  120. case 38400:
  121. divisor = UART_PL010_BAUD_38400;
  122. break;
  123. case 57600:
  124. divisor = UART_PL010_BAUD_57600;
  125. break;
  126. case 115200:
  127. divisor = UART_PL010_BAUD_115200;
  128. break;
  129. default:
  130. divisor = UART_PL010_BAUD_38400;
  131. }
  132. writel((divisor & 0xf00) >> 8, &regs->pl010_lcrm);
  133. writel(divisor & 0xff, &regs->pl010_lcrl);
  134. /* Finally, enable the UART */
  135. writel(UART_PL010_CR_UARTEN, &regs->pl010_cr);
  136. break;
  137. }
  138. case TYPE_PL011: {
  139. unsigned int temp;
  140. unsigned int divider;
  141. unsigned int remainder;
  142. unsigned int fraction;
  143. /*
  144. * Set baud rate
  145. *
  146. * IBRD = UART_CLK / (16 * BAUD_RATE)
  147. * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE)))
  148. * / (16 * BAUD_RATE))
  149. */
  150. temp = 16 * baudrate;
  151. divider = clock / temp;
  152. remainder = clock % temp;
  153. temp = (8 * remainder) / baudrate;
  154. fraction = (temp >> 1) + (temp & 1);
  155. writel(divider, &regs->pl011_ibrd);
  156. writel(fraction, &regs->pl011_fbrd);
  157. set_line_control(regs);
  158. /* Finally, enable the UART */
  159. writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
  160. UART_PL011_CR_RXE | UART_PL011_CR_RTS, &regs->pl011_cr);
  161. break;
  162. }
  163. default:
  164. return -EINVAL;
  165. }
  166. return 0;
  167. }
  168. #ifndef CONFIG_DM_SERIAL
  169. static void pl01x_serial_init_baud(int baudrate)
  170. {
  171. int clock = 0;
  172. #if defined(CONFIG_PL010_SERIAL)
  173. pl01x_type = TYPE_PL010;
  174. #elif defined(CONFIG_PL011_SERIAL)
  175. pl01x_type = TYPE_PL011;
  176. clock = CONFIG_PL011_CLOCK;
  177. #endif
  178. base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX];
  179. pl01x_generic_serial_init(base_regs, pl01x_type);
  180. pl01x_generic_setbrg(base_regs, pl01x_type, clock, baudrate);
  181. }
  182. /*
  183. * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1
  184. * Integrator CP has two UARTs, use the first one, at 38400-8-N-1
  185. * Versatile PB has four UARTs.
  186. */
  187. int pl01x_serial_init(void)
  188. {
  189. pl01x_serial_init_baud(CONFIG_BAUDRATE);
  190. return 0;
  191. }
  192. static void pl01x_serial_putc(const char c)
  193. {
  194. if (c == '\n')
  195. while (pl01x_putc(base_regs, '\r') == -EAGAIN);
  196. while (pl01x_putc(base_regs, c) == -EAGAIN);
  197. }
  198. static int pl01x_serial_getc(void)
  199. {
  200. while (1) {
  201. int ch = pl01x_getc(base_regs);
  202. if (ch == -EAGAIN) {
  203. WATCHDOG_RESET();
  204. continue;
  205. }
  206. return ch;
  207. }
  208. }
  209. static int pl01x_serial_tstc(void)
  210. {
  211. return pl01x_tstc(base_regs);
  212. }
  213. static void pl01x_serial_setbrg(void)
  214. {
  215. /*
  216. * Flush FIFO and wait for non-busy before changing baudrate to avoid
  217. * crap in console
  218. */
  219. while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE))
  220. WATCHDOG_RESET();
  221. while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY)
  222. WATCHDOG_RESET();
  223. pl01x_serial_init_baud(gd->baudrate);
  224. }
  225. static struct serial_device pl01x_serial_drv = {
  226. .name = "pl01x_serial",
  227. .start = pl01x_serial_init,
  228. .stop = NULL,
  229. .setbrg = pl01x_serial_setbrg,
  230. .putc = pl01x_serial_putc,
  231. .puts = default_serial_puts,
  232. .getc = pl01x_serial_getc,
  233. .tstc = pl01x_serial_tstc,
  234. };
  235. void pl01x_serial_initialize(void)
  236. {
  237. serial_register(&pl01x_serial_drv);
  238. }
  239. __weak struct serial_device *default_serial_console(void)
  240. {
  241. return &pl01x_serial_drv;
  242. }
  243. #endif /* nCONFIG_DM_SERIAL */
  244. #ifdef CONFIG_DM_SERIAL
  245. struct pl01x_priv {
  246. struct pl01x_regs *regs;
  247. enum pl01x_type type;
  248. };
  249. static int pl01x_serial_setbrg(struct udevice *dev, int baudrate)
  250. {
  251. struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
  252. struct pl01x_priv *priv = dev_get_priv(dev);
  253. pl01x_generic_setbrg(priv->regs, priv->type, plat->clock, baudrate);
  254. return 0;
  255. }
  256. static int pl01x_serial_probe(struct udevice *dev)
  257. {
  258. struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
  259. struct pl01x_priv *priv = dev_get_priv(dev);
  260. priv->regs = (struct pl01x_regs *)plat->base;
  261. priv->type = plat->type;
  262. return pl01x_generic_serial_init(priv->regs, priv->type);
  263. }
  264. static int pl01x_serial_getc(struct udevice *dev)
  265. {
  266. struct pl01x_priv *priv = dev_get_priv(dev);
  267. return pl01x_getc(priv->regs);
  268. }
  269. static int pl01x_serial_putc(struct udevice *dev, const char ch)
  270. {
  271. struct pl01x_priv *priv = dev_get_priv(dev);
  272. return pl01x_putc(priv->regs, ch);
  273. }
  274. static int pl01x_serial_pending(struct udevice *dev, bool input)
  275. {
  276. struct pl01x_priv *priv = dev_get_priv(dev);
  277. unsigned int fr = readl(&priv->regs->fr);
  278. if (input)
  279. return pl01x_tstc(priv->regs);
  280. else
  281. return fr & UART_PL01x_FR_TXFF ? 0 : 1;
  282. }
  283. static const struct dm_serial_ops pl01x_serial_ops = {
  284. .putc = pl01x_serial_putc,
  285. .pending = pl01x_serial_pending,
  286. .getc = pl01x_serial_getc,
  287. .setbrg = pl01x_serial_setbrg,
  288. };
  289. U_BOOT_DRIVER(serial_pl01x) = {
  290. .name = "serial_pl01x",
  291. .id = UCLASS_SERIAL,
  292. .probe = pl01x_serial_probe,
  293. .ops = &pl01x_serial_ops,
  294. .flags = DM_FLAG_PRE_RELOC,
  295. };
  296. #endif