serial_lpuart.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright 2013 Freescale Semiconductor, Inc.
  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 as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. */
  19. #include <common.h>
  20. #include <watchdog.h>
  21. #include <asm/io.h>
  22. #include <serial.h>
  23. #include <linux/compiler.h>
  24. #include <asm/arch/imx-regs.h>
  25. #include <asm/arch/clock.h>
  26. #define US1_TDRE (1 << 7)
  27. #define US1_RDRF (1 << 5)
  28. #define UC2_TE (1 << 3)
  29. #define UC2_RE (1 << 2)
  30. DECLARE_GLOBAL_DATA_PTR;
  31. struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE;
  32. static void lpuart_serial_setbrg(void)
  33. {
  34. u32 clk = mxc_get_clock(MXC_UART_CLK);
  35. u16 sbr;
  36. if (!gd->baudrate)
  37. gd->baudrate = CONFIG_BAUDRATE;
  38. sbr = (u16)(clk / (16 * gd->baudrate));
  39. /* place adjustment later - n/32 BRFA */
  40. __raw_writeb(sbr >> 8, &base->ubdh);
  41. __raw_writeb(sbr & 0xff, &base->ubdl);
  42. }
  43. static int lpuart_serial_getc(void)
  44. {
  45. u8 status;
  46. while (!(__raw_readb(&base->us1) & US1_RDRF))
  47. WATCHDOG_RESET();
  48. status = __raw_readb(&base->us1);
  49. status |= US1_RDRF;
  50. __raw_writeb(status, &base->us1);
  51. return __raw_readb(&base->ud);
  52. }
  53. static void lpuart_serial_putc(const char c)
  54. {
  55. if (c == '\n')
  56. serial_putc('\r');
  57. while (!(__raw_readb(&base->us1) & US1_TDRE))
  58. WATCHDOG_RESET();
  59. __raw_writeb(c, &base->ud);
  60. }
  61. /*
  62. * Test whether a character is in the RX buffer
  63. */
  64. static int lpuart_serial_tstc(void)
  65. {
  66. if (__raw_readb(&base->urcfifo) == 0)
  67. return 0;
  68. return 1;
  69. }
  70. /*
  71. * Initialise the serial port with the given baudrate. The settings
  72. * are always 8 data bits, no parity, 1 stop bit, no start bits.
  73. */
  74. static int lpuart_serial_init(void)
  75. {
  76. u8 ctrl;
  77. ctrl = __raw_readb(&base->uc2);
  78. ctrl &= ~UC2_RE;
  79. ctrl &= ~UC2_TE;
  80. __raw_writeb(ctrl, &base->uc2);
  81. __raw_writeb(0, &base->umodem);
  82. __raw_writeb(0, &base->uc1);
  83. /* provide data bits, parity, stop bit, etc */
  84. serial_setbrg();
  85. __raw_writeb(UC2_RE | UC2_TE, &base->uc2);
  86. return 0;
  87. }
  88. static struct serial_device lpuart_serial_drv = {
  89. .name = "lpuart_serial",
  90. .start = lpuart_serial_init,
  91. .stop = NULL,
  92. .setbrg = lpuart_serial_setbrg,
  93. .putc = lpuart_serial_putc,
  94. .puts = default_serial_puts,
  95. .getc = lpuart_serial_getc,
  96. .tstc = lpuart_serial_tstc,
  97. };
  98. void lpuart_serial_initialize(void)
  99. {
  100. serial_register(&lpuart_serial_drv);
  101. }
  102. __weak struct serial_device *default_serial_console(void)
  103. {
  104. return &lpuart_serial_drv;
  105. }