serial.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* GRLIB APBUART Serial controller driver
  2. *
  3. * (C) Copyright 2007
  4. * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. *
  24. */
  25. #include <common.h>
  26. #include <asm/processor.h>
  27. #include <asm/leon.h>
  28. #include <ambapp.h>
  29. #include <serial.h>
  30. #include <linux/compiler.h>
  31. DECLARE_GLOBAL_DATA_PTR;
  32. ambapp_dev_apbuart *leon3_apbuart = NULL;
  33. static int leon3_serial_init(void)
  34. {
  35. ambapp_apbdev apbdev;
  36. unsigned int tmp;
  37. /* find UART */
  38. if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
  39. leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
  40. /* found apbuart, let's init...
  41. *
  42. * Set scaler / baud rate
  43. *
  44. * Receiver & transmitter enable
  45. */
  46. leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER;
  47. /* Let bit 11 be unchanged (debug bit for GRMON) */
  48. tmp = READ_WORD(leon3_apbuart->ctrl);
  49. leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
  50. LEON_REG_UART_CTRL_RE |
  51. LEON_REG_UART_CTRL_TE);
  52. return 0;
  53. }
  54. return -1; /* didn't find hardware */
  55. }
  56. static void leon3_serial_putc_raw(const char c)
  57. {
  58. if (!leon3_apbuart)
  59. return;
  60. /* Wait for last character to go. */
  61. while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
  62. /* Send data */
  63. leon3_apbuart->data = c;
  64. #ifdef LEON_DEBUG
  65. /* Wait for data to be sent */
  66. while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
  67. #endif
  68. }
  69. static void leon3_serial_putc(const char c)
  70. {
  71. if (c == '\n')
  72. leon3_serial_putc_raw('\r');
  73. leon3_serial_putc_raw(c);
  74. }
  75. static int leon3_serial_getc(void)
  76. {
  77. if (!leon3_apbuart)
  78. return 0;
  79. /* Wait for a character to arrive. */
  80. while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
  81. /* read data */
  82. return READ_WORD(leon3_apbuart->data);
  83. }
  84. static int leon3_serial_tstc(void)
  85. {
  86. if (leon3_apbuart)
  87. return (READ_WORD(leon3_apbuart->status) &
  88. LEON_REG_UART_STATUS_DR);
  89. return 0;
  90. }
  91. /* set baud rate for uart */
  92. static void leon3_serial_setbrg(void)
  93. {
  94. /* update baud rate settings, read it from gd->baudrate */
  95. unsigned int scaler;
  96. if (leon3_apbuart && (gd->baudrate > 0)) {
  97. scaler =
  98. (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
  99. 5) / 10;
  100. leon3_apbuart->scaler = scaler;
  101. }
  102. return;
  103. }
  104. static struct serial_device leon3_serial_drv = {
  105. .name = "leon3_serial",
  106. .start = leon3_serial_init,
  107. .stop = NULL,
  108. .setbrg = leon3_serial_setbrg,
  109. .putc = leon3_serial_putc,
  110. .puts = default_serial_puts,
  111. .getc = leon3_serial_getc,
  112. .tstc = leon3_serial_tstc,
  113. };
  114. void leon3_serial_initialize(void)
  115. {
  116. serial_register(&leon3_serial_drv);
  117. }
  118. __weak struct serial_device *default_serial_console(void)
  119. {
  120. return &leon3_serial_drv;
  121. }