mxs_auart.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Freescale i.MX23/i.MX28 AUART driver
  3. *
  4. * Copyright (C) 2013 Andreas Wass <andreas.wass@dalelven.com>
  5. *
  6. * Based on the MXC serial driver:
  7. *
  8. * (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
  9. *
  10. * Further based on the Linux mxs-auart.c driver:
  11. *
  12. * Freescale STMP37XX/STMP38X Application UART drkiver
  13. * Copyright 2008-2010 Freescale Semiconductor, Inc.
  14. *
  15. * SPDX-License-Identifier: GPL-2.0+
  16. */
  17. #include <common.h>
  18. #include <asm/io.h>
  19. #include <serial.h>
  20. #include <linux/compiler.h>
  21. #include <asm/arch/regs-base.h>
  22. #include <asm/arch/regs-uartapp.h>
  23. #include <asm/arch/sys_proto.h>
  24. DECLARE_GLOBAL_DATA_PTR;
  25. #ifndef CONFIG_MXS_AUART_BASE
  26. #error "CONFIG_MXS_AUART_BASE must be set to the base UART to use"
  27. #endif
  28. /* AUART clock always supplied by XTAL and always 24MHz */
  29. #define MXS_AUART_CLK 24000000
  30. static struct mxs_uartapp_regs *get_uartapp_registers(void)
  31. {
  32. return (struct mxs_uartapp_regs *)CONFIG_MXS_AUART_BASE;
  33. }
  34. /**
  35. * Sets the baud rate and settings.
  36. * The settings are: 8 data bits, no parit and 1 stop bit.
  37. */
  38. void mxs_auart_setbrg(void)
  39. {
  40. u32 div;
  41. u32 linectrl = 0;
  42. struct mxs_uartapp_regs *regs = get_uartapp_registers();
  43. if (!gd->baudrate)
  44. gd->baudrate = CONFIG_BAUDRATE;
  45. /*
  46. * From i.MX28 datasheet:
  47. * div is calculated by calculating UARTCLK*32/baudrate, rounded to int
  48. * div must be between 0xEC and 0x003FFFC0 inclusive
  49. * Lowest 6 bits of div goes in BAUD_DIVFRAC part of LINECTRL register
  50. * Next 16 bits goes in BAUD_DIVINT part of LINECTRL register
  51. */
  52. div = (MXS_AUART_CLK * 32) / gd->baudrate;
  53. if (div < 0xEC || div > 0x003FFFC0)
  54. return;
  55. linectrl |= ((div & UARTAPP_LINECTRL_EXTRACT_BAUD_DIVFRAC_MASK) <<
  56. UARTAPP_LINECTRL_BAUD_DIVFRAC_OFFSET) &
  57. UARTAPP_LINECTRL_BAUD_DIVFRAC_MASK;
  58. linectrl |= ((div >> UARTAPP_LINECTRL_EXTRACT_BAUD_DIVINT_OFFSET) <<
  59. UARTAPP_LINECTRL_BAUD_DIVINT_OFFSET) &
  60. UARTAPP_LINECTRL_BAUD_DIVINT_MASK;
  61. /* Word length: 8 bits */
  62. linectrl |= UARTAPP_LINECTRL_WLEN_8BITS;
  63. /* Enable FIFOs. */
  64. linectrl |= UARTAPP_LINECTRL_FEN_MASK;
  65. /* Write above settings, no parity, 1 stop bit */
  66. writel(linectrl, &regs->hw_uartapp_linectrl);
  67. }
  68. int mxs_auart_init(void)
  69. {
  70. struct mxs_uartapp_regs *regs = get_uartapp_registers();
  71. /* Reset everything */
  72. mxs_reset_block(&regs->hw_uartapp_ctrl0_reg);
  73. /* Disable interrupts */
  74. writel(0, &regs->hw_uartapp_intr);
  75. /* Set baud rate and settings */
  76. serial_setbrg();
  77. /* Disable RTS and CTS, ignore LINECTRL2 register */
  78. writel(UARTAPP_CTRL2_RTSEN_MASK |
  79. UARTAPP_CTRL2_CTSEN_MASK |
  80. UARTAPP_CTRL2_USE_LCR2_MASK,
  81. &regs->hw_uartapp_ctrl2_clr);
  82. /* Enable receiver, transmitter and UART */
  83. writel(UARTAPP_CTRL2_RXE_MASK |
  84. UARTAPP_CTRL2_TXE_MASK |
  85. UARTAPP_CTRL2_UARTEN_MASK,
  86. &regs->hw_uartapp_ctrl2_set);
  87. return 0;
  88. }
  89. void mxs_auart_putc(const char c)
  90. {
  91. struct mxs_uartapp_regs *regs = get_uartapp_registers();
  92. /* Wait in loop while the transmit FIFO is full */
  93. while (readl(&regs->hw_uartapp_stat) & UARTAPP_STAT_TXFF_MASK)
  94. ;
  95. writel(c, &regs->hw_uartapp_data);
  96. if (c == '\n')
  97. mxs_auart_putc('\r');
  98. }
  99. int mxs_auart_tstc(void)
  100. {
  101. struct mxs_uartapp_regs *regs = get_uartapp_registers();
  102. /* Checks if receive FIFO is empty */
  103. return !(readl(&regs->hw_uartapp_stat) & UARTAPP_STAT_RXFE_MASK);
  104. }
  105. int mxs_auart_getc(void)
  106. {
  107. struct mxs_uartapp_regs *regs = get_uartapp_registers();
  108. /* Wait until a character is available to read */
  109. while (!mxs_auart_tstc())
  110. ;
  111. /* Read the character from the data register */
  112. return readl(&regs->hw_uartapp_data) & 0xFF;
  113. }
  114. static struct serial_device mxs_auart_drv = {
  115. .name = "mxs_auart_serial",
  116. .start = mxs_auart_init,
  117. .stop = NULL,
  118. .setbrg = mxs_auart_setbrg,
  119. .putc = mxs_auart_putc,
  120. .puts = default_serial_puts,
  121. .getc = mxs_auart_getc,
  122. .tstc = mxs_auart_tstc,
  123. };
  124. void mxs_auart_initialize(void)
  125. {
  126. serial_register(&mxs_auart_drv);
  127. }
  128. __weak struct serial_device *default_serial_console(void)
  129. {
  130. return &mxs_auart_drv;
  131. }