serial.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. DECLARE_GLOBAL_DATA_PTR;
  30. /* Force cache miss each time a serial controller reg is read */
  31. #define CACHE_BYPASS 1
  32. #ifdef CACHE_BYPASS
  33. #define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
  34. #define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
  35. #define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)&(var))
  36. #define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
  37. #endif
  38. ambapp_dev_apbuart *leon3_apbuart = NULL;
  39. int serial_init(void)
  40. {
  41. ambapp_apbdev apbdev;
  42. unsigned int tmp;
  43. /* find UART */
  44. if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
  45. leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
  46. /* found apbuart, let's init...
  47. *
  48. * Set scaler / baud rate
  49. *
  50. * Receiver & transmitter enable
  51. */
  52. leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER;
  53. /* Let bit 11 be unchanged (debug bit for GRMON) */
  54. tmp = READ_WORD(leon3_apbuart->ctrl);
  55. leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
  56. LEON_REG_UART_CTRL_RE |
  57. LEON_REG_UART_CTRL_TE);
  58. return 0;
  59. }
  60. return -1; /* didn't find hardware */
  61. }
  62. void serial_putc(const char c)
  63. {
  64. if (c == '\n')
  65. serial_putc_raw('\r');
  66. serial_putc_raw(c);
  67. }
  68. void serial_putc_raw(const char c)
  69. {
  70. if (!leon3_apbuart)
  71. return;
  72. /* Wait for last character to go. */
  73. while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
  74. /* Send data */
  75. leon3_apbuart->data = c;
  76. #ifdef LEON_DEBUG
  77. /* Wait for data to be sent */
  78. while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
  79. #endif
  80. }
  81. void serial_puts(const char *s)
  82. {
  83. while (*s) {
  84. serial_putc(*s++);
  85. }
  86. }
  87. int serial_getc(void)
  88. {
  89. if (!leon3_apbuart)
  90. return 0;
  91. /* Wait for a character to arrive. */
  92. while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
  93. /* read data */
  94. return READ_WORD(leon3_apbuart->data);
  95. }
  96. int serial_tstc(void)
  97. {
  98. if (leon3_apbuart)
  99. return (READ_WORD(leon3_apbuart->status) &
  100. LEON_REG_UART_STATUS_DR);
  101. return 0;
  102. }
  103. /* set baud rate for uart */
  104. void serial_setbrg(void)
  105. {
  106. /* update baud rate settings, read it from gd->baudrate */
  107. unsigned int scaler;
  108. if (leon3_apbuart && (gd->baudrate > 0)) {
  109. scaler =
  110. (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
  111. 5) / 10;
  112. leon3_apbuart->scaler = scaler;
  113. }
  114. return;
  115. }