serial4.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * serial.h - common serial defines for early debug and serial driver.
  3. * any functions defined here must be always_inline since
  4. * initcode cannot have function calls.
  5. *
  6. * Copyright (c) 2004-2011 Analog Devices Inc.
  7. *
  8. * Licensed under the GPL-2 or later.
  9. */
  10. #ifndef __BFIN_CPU_SERIAL4_H__
  11. #define __BFIN_CPU_SERIAL4_H__
  12. #include <asm/mach-common/bits/uart4.h>
  13. #ifndef __ASSEMBLY__
  14. #include <asm/clock.h>
  15. #define MMR_UART(n) _PASTE_UART(n, UART, REVID)
  16. #define UART_BASE MMR_UART(CONFIG_UART_CONSOLE)
  17. struct bfin_mmr_serial {
  18. u32 revid;
  19. u32 control;
  20. u32 status;
  21. u32 scr;
  22. u32 clock;
  23. u32 emask;
  24. u32 emaskst;
  25. u32 emaskcl;
  26. u32 rbr;
  27. u32 thr;
  28. u32 taip;
  29. u32 tsr;
  30. u32 rsr;
  31. u32 txdiv_cnt;
  32. u32 rxdiv_cnt;
  33. };
  34. #define uart_lsr_t uint32_t
  35. #define _lsr_read(p) bfin_read(&p->status)
  36. #define _lsr_write(p, v) bfin_write(&p->status, v)
  37. __attribute__((always_inline))
  38. static inline void serial_early_do_mach_portmux(char port, int mux_mask,
  39. int mux_func, int port_pin)
  40. {
  41. switch (port) {
  42. case 'D':
  43. bfin_write_PORTD_MUX((bfin_read_PORTD_MUX() &
  44. ~mux_mask) | mux_func);
  45. bfin_write_PORTD_FER_SET(port_pin);
  46. break;
  47. case 'G':
  48. bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() &
  49. ~mux_mask) | mux_func);
  50. bfin_write_PORTG_FER_SET(port_pin);
  51. break;
  52. }
  53. }
  54. __attribute__((always_inline))
  55. static inline void serial_early_do_portmux(void)
  56. {
  57. #if defined(__ADSPBF60x__)
  58. switch (CONFIG_UART_CONSOLE) {
  59. case 0:
  60. serial_early_do_mach_portmux('D', PORT_x_MUX_7_MASK,
  61. PORT_x_MUX_7_FUNC_2, PD7); /* TX: D; mux 7; func 2; PD7 */
  62. serial_early_do_mach_portmux('D', PORT_x_MUX_8_MASK,
  63. PORT_x_MUX_8_FUNC_2, PD8); /* RX: D; mux 8; func 2; PD8 */
  64. break;
  65. case 1:
  66. serial_early_do_mach_portmux('G', PORT_x_MUX_15_MASK,
  67. PORT_x_MUX_15_FUNC_1, PG15); /* TX: G; mux 15; func 1; PG15 */
  68. serial_early_do_mach_portmux('G', PORT_x_MUX_14_MASK,
  69. PORT_x_MUX_14_FUNC_1, PG14); /* RX: G; mux 14; func 1; PG14 */
  70. break;
  71. }
  72. #else
  73. # if (P_UART(RX) & P_DEFINED) || (P_UART(TX) & P_DEFINED)
  74. # error "missing portmux logic for UART"
  75. # endif
  76. #endif
  77. SSYNC();
  78. }
  79. __attribute__((always_inline))
  80. static inline int uart_init(uint32_t uart_base)
  81. {
  82. /* always enable UART to 8-bit mode */
  83. bfin_write(&pUART->control, UEN | UMOD_UART | WLS_8);
  84. SSYNC();
  85. return 0;
  86. }
  87. __attribute__((always_inline))
  88. static inline int serial_early_init(uint32_t uart_base)
  89. {
  90. /* handle portmux crap on different Blackfins */
  91. serial_do_portmux();
  92. return uart_init(uart_base);
  93. }
  94. __attribute__((always_inline))
  95. static inline int serial_early_uninit(uint32_t uart_base)
  96. {
  97. /* disable the UART by clearing UEN */
  98. bfin_write(&pUART->control, 0);
  99. return 0;
  100. }
  101. __attribute__((always_inline))
  102. static inline void serial_set_divisor(uint32_t uart_base, uint16_t divisor)
  103. {
  104. /* Program the divisor to get the baud rate we want */
  105. bfin_write(&pUART->clock, divisor);
  106. SSYNC();
  107. }
  108. __attribute__((always_inline))
  109. static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud)
  110. {
  111. uint16_t divisor = early_division(early_get_uart_clk(), baud * 16);
  112. /* Program the divisor to get the baud rate we want */
  113. serial_set_divisor(uart_base, divisor);
  114. }
  115. __attribute__((always_inline))
  116. static inline void serial_early_put_div(uint32_t divisor)
  117. {
  118. uint32_t uart_base = UART_BASE;
  119. bfin_write(&pUART->clock, divisor);
  120. }
  121. __attribute__((always_inline))
  122. static inline uint32_t serial_early_get_div(void)
  123. {
  124. uint32_t uart_base = UART_BASE;
  125. return bfin_read(&pUART->clock);
  126. }
  127. #endif
  128. #endif