jz_serial.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Jz4740 UART support
  3. * Copyright (c) 2011
  4. * Qi Hardware, Xiangfu Liu <xiangfu@sharism.cc>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  19. * MA 02111-1307 USA
  20. */
  21. #include <config.h>
  22. #include <common.h>
  23. #include <asm/io.h>
  24. #include <asm/jz4740.h>
  25. /*
  26. * serial_init - initialize a channel
  27. *
  28. * This routine initializes the number of data bits, parity
  29. * and set the selected baud rate. Interrupts are disabled.
  30. * Set the modem control signals if the option is selected.
  31. *
  32. * RETURNS: N/A
  33. */
  34. struct jz4740_uart *uart = (struct jz4740_uart *)CONFIG_SYS_UART_BASE;
  35. int serial_init(void)
  36. {
  37. /* Disable port interrupts while changing hardware */
  38. writeb(0, &uart->dlhr_ier);
  39. /* Disable UART unit function */
  40. writeb(~UART_FCR_UUE, &uart->iir_fcr);
  41. /* Set both receiver and transmitter in UART mode (not SIR) */
  42. writeb(~(SIRCR_RSIRE | SIRCR_TSIRE), &uart->isr);
  43. /*
  44. * Set databits, stopbits and parity.
  45. * (8-bit data, 1 stopbit, no parity)
  46. */
  47. writeb(UART_LCR_WLEN_8 | UART_LCR_STOP_1, &uart->lcr);
  48. /* Set baud rate */
  49. serial_setbrg();
  50. /* Enable UART unit, enable and clear FIFO */
  51. writeb(UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS,
  52. &uart->iir_fcr);
  53. return 0;
  54. }
  55. void serial_setbrg(void)
  56. {
  57. u32 baud_div, tmp;
  58. baud_div = CONFIG_SYS_EXTAL / 16 / CONFIG_BAUDRATE;
  59. tmp = readb(&uart->lcr);
  60. tmp |= UART_LCR_DLAB;
  61. writeb(tmp, &uart->lcr);
  62. writeb((baud_div >> 8) & 0xff, &uart->dlhr_ier);
  63. writeb(baud_div & 0xff, &uart->rbr_thr_dllr);
  64. tmp &= ~UART_LCR_DLAB;
  65. writeb(tmp, &uart->lcr);
  66. }
  67. int serial_tstc(void)
  68. {
  69. if (readb(&uart->lsr) & UART_LSR_DR)
  70. return 1;
  71. return 0;
  72. }
  73. void serial_putc(const char c)
  74. {
  75. if (c == '\n')
  76. serial_putc('\r');
  77. /* Wait for fifo to shift out some bytes */
  78. while (!((readb(&uart->lsr) & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60))
  79. ;
  80. writeb((u8)c, &uart->rbr_thr_dllr);
  81. }
  82. int serial_getc(void)
  83. {
  84. while (!serial_tstc())
  85. ;
  86. return readb(&uart->rbr_thr_dllr);
  87. }
  88. void serial_puts(const char *s)
  89. {
  90. while (*s)
  91. serial_putc(*s++);
  92. }