serial_xuartlite.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2008 - 2015 Michal Simek <monstr@monstr.eu>
  4. * Clean driver and add xilinx constant from header file
  5. *
  6. * (C) Copyright 2004 Atmark Techno, Inc.
  7. * Yasushi SHOJI <yashi@atmark-techno.com>
  8. */
  9. #include <config.h>
  10. #include <common.h>
  11. #include <dm.h>
  12. #include <asm/io.h>
  13. #include <linux/bitops.h>
  14. #include <linux/compiler.h>
  15. #include <serial.h>
  16. #define SR_TX_FIFO_FULL BIT(3) /* transmit FIFO full */
  17. #define SR_TX_FIFO_EMPTY BIT(2) /* transmit FIFO empty */
  18. #define SR_RX_FIFO_VALID_DATA BIT(0) /* data in receive FIFO */
  19. #define SR_RX_FIFO_FULL BIT(1) /* receive FIFO full */
  20. #define ULITE_CONTROL_RST_TX 0x01
  21. #define ULITE_CONTROL_RST_RX 0x02
  22. static bool little_endian;
  23. struct uartlite {
  24. unsigned int rx_fifo;
  25. unsigned int tx_fifo;
  26. unsigned int status;
  27. unsigned int control;
  28. };
  29. struct uartlite_platdata {
  30. struct uartlite *regs;
  31. };
  32. static u32 uart_in32(void __iomem *addr)
  33. {
  34. if (little_endian)
  35. return in_le32(addr);
  36. else
  37. return in_be32(addr);
  38. }
  39. static void uart_out32(void __iomem *addr, u32 val)
  40. {
  41. if (little_endian)
  42. out_le32(addr, val);
  43. else
  44. out_be32(addr, val);
  45. }
  46. static int uartlite_serial_putc(struct udevice *dev, const char ch)
  47. {
  48. struct uartlite_platdata *plat = dev_get_platdata(dev);
  49. struct uartlite *regs = plat->regs;
  50. if (uart_in32(&regs->status) & SR_TX_FIFO_FULL)
  51. return -EAGAIN;
  52. uart_out32(&regs->tx_fifo, ch & 0xff);
  53. return 0;
  54. }
  55. static int uartlite_serial_getc(struct udevice *dev)
  56. {
  57. struct uartlite_platdata *plat = dev_get_platdata(dev);
  58. struct uartlite *regs = plat->regs;
  59. if (!(uart_in32(&regs->status) & SR_RX_FIFO_VALID_DATA))
  60. return -EAGAIN;
  61. return uart_in32(&regs->rx_fifo) & 0xff;
  62. }
  63. static int uartlite_serial_pending(struct udevice *dev, bool input)
  64. {
  65. struct uartlite_platdata *plat = dev_get_platdata(dev);
  66. struct uartlite *regs = plat->regs;
  67. if (input)
  68. return uart_in32(&regs->status) & SR_RX_FIFO_VALID_DATA;
  69. return !(uart_in32(&regs->status) & SR_TX_FIFO_EMPTY);
  70. }
  71. static int uartlite_serial_probe(struct udevice *dev)
  72. {
  73. struct uartlite_platdata *plat = dev_get_platdata(dev);
  74. struct uartlite *regs = plat->regs;
  75. int ret;
  76. uart_out32(&regs->control, 0);
  77. uart_out32(&regs->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
  78. ret = uart_in32(&regs->status);
  79. /* Endianness detection */
  80. if ((ret & SR_TX_FIFO_EMPTY) != SR_TX_FIFO_EMPTY) {
  81. little_endian = true;
  82. uart_out32(&regs->control, ULITE_CONTROL_RST_RX |
  83. ULITE_CONTROL_RST_TX);
  84. }
  85. return 0;
  86. }
  87. static int uartlite_serial_ofdata_to_platdata(struct udevice *dev)
  88. {
  89. struct uartlite_platdata *plat = dev_get_platdata(dev);
  90. plat->regs = dev_read_addr_ptr(dev);
  91. return 0;
  92. }
  93. static const struct dm_serial_ops uartlite_serial_ops = {
  94. .putc = uartlite_serial_putc,
  95. .pending = uartlite_serial_pending,
  96. .getc = uartlite_serial_getc,
  97. };
  98. static const struct udevice_id uartlite_serial_ids[] = {
  99. { .compatible = "xlnx,opb-uartlite-1.00.b", },
  100. { .compatible = "xlnx,xps-uartlite-1.00.a" },
  101. { }
  102. };
  103. U_BOOT_DRIVER(serial_uartlite) = {
  104. .name = "serial_uartlite",
  105. .id = UCLASS_SERIAL,
  106. .of_match = uartlite_serial_ids,
  107. .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata,
  108. .platdata_auto_alloc_size = sizeof(struct uartlite_platdata),
  109. .probe = uartlite_serial_probe,
  110. .ops = &uartlite_serial_ops,
  111. };
  112. #ifdef CONFIG_DEBUG_UART_UARTLITE
  113. #include <debug_uart.h>
  114. static inline void _debug_uart_init(void)
  115. {
  116. struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE;
  117. int ret;
  118. uart_out32(&regs->control, 0);
  119. uart_out32(&regs->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
  120. uart_in32(&regs->status);
  121. /* Endianness detection */
  122. if ((ret & SR_TX_FIFO_EMPTY) != SR_TX_FIFO_EMPTY) {
  123. little_endian = true;
  124. uart_out32(&regs->control, ULITE_CONTROL_RST_RX |
  125. ULITE_CONTROL_RST_TX);
  126. }
  127. }
  128. static inline void _debug_uart_putc(int ch)
  129. {
  130. struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE;
  131. while (uart_in32(&regs->status) & SR_TX_FIFO_FULL)
  132. ;
  133. uart_out32(&regs->tx_fifo, ch & 0xff);
  134. }
  135. DEBUG_UART_FUNCS
  136. #endif