serial.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* GRLIB APBUART Serial controller driver
  2. *
  3. * (C) Copyright 2008, 2015
  4. * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <asm/io.h>
  10. #include <serial.h>
  11. #include <watchdog.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. static unsigned leon2_serial_calc_scaler(unsigned freq, unsigned baud)
  14. {
  15. return (((freq*10) / (baud*8)) - 5) / 10;
  16. }
  17. static int leon2_serial_init(void)
  18. {
  19. LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS;
  20. LEON2_Uart_regs *regs;
  21. unsigned int tmp;
  22. #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
  23. regs = (LEON2_Uart_regs *)&leon2->UART_Channel_1;
  24. #else
  25. regs = (LEON2_Uart_regs *)&leon2->UART_Channel_2;
  26. #endif
  27. /* Set scaler / baud rate */
  28. tmp = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE);
  29. writel(tmp, &regs->UART_Scaler);
  30. /* Let bit 11 be unchanged (debug bit for GRMON) */
  31. tmp = readl(&regs->UART_Control) & LEON2_UART_CTRL_DBG;
  32. tmp |= (LEON2_UART1_LOOPBACK_ENABLE << 7);
  33. tmp |= (LEON2_UART1_FLOWCTRL_ENABLE << 6);
  34. tmp |= (LEON2_UART1_PARITY_ENABLE << 5);
  35. tmp |= (LEON2_UART1_ODDPAR_ENABLE << 4);
  36. /* Receiver & transmitter enable */
  37. tmp |= (LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
  38. writel(tmp, &regs->UART_Control);
  39. gd->arch.uart = regs;
  40. return 0;
  41. }
  42. static inline LEON2_Uart_regs *leon2_get_uart_regs(void)
  43. {
  44. LEON2_Uart_regs *uart = gd->arch.uart;
  45. return uart;
  46. }
  47. static void leon2_serial_putc_raw(const char c)
  48. {
  49. LEON2_Uart_regs *uart = leon2_get_uart_regs();
  50. if (!uart)
  51. return;
  52. /* Wait for last character to go. */
  53. while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_THE))
  54. WATCHDOG_RESET();
  55. /* Send data */
  56. writel(c, &uart->UART_Channel);
  57. #ifdef LEON_DEBUG
  58. /* Wait for data to be sent */
  59. while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_TSE))
  60. WATCHDOG_RESET();
  61. #endif
  62. }
  63. static void leon2_serial_putc(const char c)
  64. {
  65. if (c == '\n')
  66. leon2_serial_putc_raw('\r');
  67. leon2_serial_putc_raw(c);
  68. }
  69. static int leon2_serial_getc(void)
  70. {
  71. LEON2_Uart_regs *uart = leon2_get_uart_regs();
  72. if (!uart)
  73. return 0;
  74. /* Wait for a character to arrive. */
  75. while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_DR))
  76. WATCHDOG_RESET();
  77. /* Read character data */
  78. return readl(&uart->UART_Channel);
  79. }
  80. static int leon2_serial_tstc(void)
  81. {
  82. LEON2_Uart_regs *uart = leon2_get_uart_regs();
  83. if (!uart)
  84. return 0;
  85. return readl(&uart->UART_Status) & LEON2_UART_STAT_DR;
  86. }
  87. static void leon2_serial_setbrg(void)
  88. {
  89. LEON2_Uart_regs *uart = leon2_get_uart_regs();
  90. unsigned int scaler;
  91. if (!uart)
  92. return;
  93. if (!gd->baudrate)
  94. gd->baudrate = CONFIG_BAUDRATE;
  95. scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, gd->baudrate);
  96. writel(scaler, &uart->UART_Scaler);
  97. }
  98. static struct serial_device leon2_serial_drv = {
  99. .name = "leon2_serial",
  100. .start = leon2_serial_init,
  101. .stop = NULL,
  102. .setbrg = leon2_serial_setbrg,
  103. .putc = leon2_serial_putc,
  104. .puts = default_serial_puts,
  105. .getc = leon2_serial_getc,
  106. .tstc = leon2_serial_tstc,
  107. };
  108. void leon2_serial_initialize(void)
  109. {
  110. serial_register(&leon2_serial_drv);
  111. }
  112. __weak struct serial_device *default_serial_console(void)
  113. {
  114. return &leon2_serial_drv;
  115. }