serial_arc.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. DECLARE_GLOBAL_DATA_PTR;
  13. struct arc_serial_regs {
  14. unsigned int id0;
  15. unsigned int id1;
  16. unsigned int id2;
  17. unsigned int id3;
  18. unsigned int data;
  19. unsigned int status;
  20. unsigned int baudl;
  21. unsigned int baudh;
  22. };
  23. struct arc_serial_platdata {
  24. struct arc_serial_regs *reg;
  25. unsigned int uartclk;
  26. };
  27. /* Bit definitions of STATUS register */
  28. #define UART_RXEMPTY (1 << 5)
  29. #define UART_OVERFLOW_ERR (1 << 1)
  30. #define UART_TXEMPTY (1 << 7)
  31. static int arc_serial_setbrg(struct udevice *dev, int baudrate)
  32. {
  33. struct arc_serial_platdata *plat = dev->platdata;
  34. struct arc_serial_regs *const regs = plat->reg;
  35. int arc_console_baud = gd->cpu_clk / (baudrate * 4) - 1;
  36. writeb(arc_console_baud & 0xff, &regs->baudl);
  37. writeb((arc_console_baud & 0xff00) >> 8, &regs->baudh);
  38. return 0;
  39. }
  40. static int arc_serial_putc(struct udevice *dev, const char c)
  41. {
  42. struct arc_serial_platdata *plat = dev->platdata;
  43. struct arc_serial_regs *const regs = plat->reg;
  44. while (!(readb(&regs->status) & UART_TXEMPTY))
  45. ;
  46. writeb(c, &regs->data);
  47. return 0;
  48. }
  49. static int arc_serial_tstc(struct arc_serial_regs *const regs)
  50. {
  51. return !(readb(&regs->status) & UART_RXEMPTY);
  52. }
  53. static int arc_serial_pending(struct udevice *dev, bool input)
  54. {
  55. struct arc_serial_platdata *plat = dev->platdata;
  56. struct arc_serial_regs *const regs = plat->reg;
  57. uint32_t status = readb(&regs->status);
  58. if (input)
  59. return status & UART_RXEMPTY ? 0 : 1;
  60. else
  61. return status & UART_TXEMPTY ? 0 : 1;
  62. }
  63. static int arc_serial_getc(struct udevice *dev)
  64. {
  65. struct arc_serial_platdata *plat = dev->platdata;
  66. struct arc_serial_regs *const regs = plat->reg;
  67. while (!arc_serial_tstc(regs))
  68. ;
  69. /* Check for overflow errors */
  70. if (readb(&regs->status) & UART_OVERFLOW_ERR)
  71. return 0;
  72. return readb(&regs->data) & 0xFF;
  73. }
  74. static int arc_serial_probe(struct udevice *dev)
  75. {
  76. return 0;
  77. }
  78. static const struct dm_serial_ops arc_serial_ops = {
  79. .putc = arc_serial_putc,
  80. .pending = arc_serial_pending,
  81. .getc = arc_serial_getc,
  82. .setbrg = arc_serial_setbrg,
  83. };
  84. static const struct udevice_id arc_serial_ids[] = {
  85. { .compatible = "snps,arc-uart" },
  86. { }
  87. };
  88. static int arc_serial_ofdata_to_platdata(struct udevice *dev)
  89. {
  90. struct arc_serial_platdata *plat = dev_get_platdata(dev);
  91. DECLARE_GLOBAL_DATA_PTR;
  92. plat->reg = dev_read_addr_ptr(dev);
  93. plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  94. "clock-frequency", 0);
  95. return 0;
  96. }
  97. U_BOOT_DRIVER(serial_arc) = {
  98. .name = "serial_arc",
  99. .id = UCLASS_SERIAL,
  100. .of_match = arc_serial_ids,
  101. .ofdata_to_platdata = arc_serial_ofdata_to_platdata,
  102. .platdata_auto_alloc_size = sizeof(struct arc_serial_platdata),
  103. .probe = arc_serial_probe,
  104. .ops = &arc_serial_ops,
  105. };
  106. #ifdef CONFIG_DEBUG_ARC_SERIAL
  107. #include <debug_uart.h>
  108. static inline void _debug_uart_init(void)
  109. {
  110. struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_DEBUG_UART_BASE;
  111. int arc_console_baud = CONFIG_DEBUG_UART_CLOCK / (CONFIG_BAUDRATE * 4) - 1;
  112. writeb(arc_console_baud & 0xff, &regs->baudl);
  113. writeb((arc_console_baud & 0xff00) >> 8, &regs->baudh);
  114. }
  115. static inline void _debug_uart_putc(int c)
  116. {
  117. struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_DEBUG_UART_BASE;
  118. while (!(readb(&regs->status) & UART_TXEMPTY))
  119. ;
  120. writeb(c, &regs->data);
  121. }
  122. DEBUG_UART_FUNCS
  123. #endif