serial_arc.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <serial.h>
  12. #include <asm/global_data.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. struct arc_serial_regs {
  15. unsigned int id0;
  16. unsigned int id1;
  17. unsigned int id2;
  18. unsigned int id3;
  19. unsigned int data;
  20. unsigned int status;
  21. unsigned int baudl;
  22. unsigned int baudh;
  23. };
  24. struct arc_serial_plat {
  25. struct arc_serial_regs *reg;
  26. unsigned int uartclk;
  27. };
  28. /* Bit definitions of STATUS register */
  29. #define UART_RXEMPTY (1 << 5)
  30. #define UART_OVERFLOW_ERR (1 << 1)
  31. #define UART_TXEMPTY (1 << 7)
  32. static int arc_serial_setbrg(struct udevice *dev, int baudrate)
  33. {
  34. struct arc_serial_plat *plat = dev_get_plat(dev);
  35. struct arc_serial_regs *const regs = plat->reg;
  36. int arc_console_baud = gd->cpu_clk / (baudrate * 4) - 1;
  37. writeb(arc_console_baud & 0xff, &regs->baudl);
  38. writeb((arc_console_baud & 0xff00) >> 8, &regs->baudh);
  39. return 0;
  40. }
  41. static int arc_serial_putc(struct udevice *dev, const char c)
  42. {
  43. struct arc_serial_plat *plat = dev_get_plat(dev);
  44. struct arc_serial_regs *const regs = plat->reg;
  45. while (!(readb(&regs->status) & UART_TXEMPTY))
  46. ;
  47. writeb(c, &regs->data);
  48. return 0;
  49. }
  50. static int arc_serial_tstc(struct arc_serial_regs *const regs)
  51. {
  52. return !(readb(&regs->status) & UART_RXEMPTY);
  53. }
  54. static int arc_serial_pending(struct udevice *dev, bool input)
  55. {
  56. struct arc_serial_plat *plat = dev_get_plat(dev);
  57. struct arc_serial_regs *const regs = plat->reg;
  58. uint32_t status = readb(&regs->status);
  59. if (input)
  60. return status & UART_RXEMPTY ? 0 : 1;
  61. else
  62. return status & UART_TXEMPTY ? 0 : 1;
  63. }
  64. static int arc_serial_getc(struct udevice *dev)
  65. {
  66. struct arc_serial_plat *plat = dev_get_plat(dev);
  67. struct arc_serial_regs *const regs = plat->reg;
  68. while (!arc_serial_tstc(regs))
  69. ;
  70. /* Check for overflow errors */
  71. if (readb(&regs->status) & UART_OVERFLOW_ERR)
  72. return 0;
  73. return readb(&regs->data) & 0xFF;
  74. }
  75. static int arc_serial_probe(struct udevice *dev)
  76. {
  77. return 0;
  78. }
  79. static const struct dm_serial_ops arc_serial_ops = {
  80. .putc = arc_serial_putc,
  81. .pending = arc_serial_pending,
  82. .getc = arc_serial_getc,
  83. .setbrg = arc_serial_setbrg,
  84. };
  85. static const struct udevice_id arc_serial_ids[] = {
  86. { .compatible = "snps,arc-uart" },
  87. { }
  88. };
  89. static int arc_serial_of_to_plat(struct udevice *dev)
  90. {
  91. struct arc_serial_plat *plat = dev_get_plat(dev);
  92. DECLARE_GLOBAL_DATA_PTR;
  93. plat->reg = dev_read_addr_ptr(dev);
  94. plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  95. "clock-frequency", 0);
  96. return 0;
  97. }
  98. U_BOOT_DRIVER(serial_arc) = {
  99. .name = "serial_arc",
  100. .id = UCLASS_SERIAL,
  101. .of_match = arc_serial_ids,
  102. .of_to_plat = arc_serial_of_to_plat,
  103. .plat_auto = sizeof(struct arc_serial_plat),
  104. .probe = arc_serial_probe,
  105. .ops = &arc_serial_ops,
  106. };
  107. #ifdef CONFIG_DEBUG_ARC_SERIAL
  108. #include <debug_uart.h>
  109. static inline void _debug_uart_init(void)
  110. {
  111. struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_DEBUG_UART_BASE;
  112. int arc_console_baud = CONFIG_DEBUG_UART_CLOCK / (CONFIG_BAUDRATE * 4) - 1;
  113. writeb(arc_console_baud & 0xff, &regs->baudl);
  114. writeb((arc_console_baud & 0xff00) >> 8, &regs->baudh);
  115. }
  116. static inline void _debug_uart_putc(int c)
  117. {
  118. struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_DEBUG_UART_BASE;
  119. while (!(readb(&regs->status) & UART_TXEMPTY))
  120. ;
  121. writeb(c, &regs->data);
  122. }
  123. DEBUG_UART_FUNCS
  124. #endif