serial4.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. #define MMR_UART(n) _PASTE_UART(n, UART, REVID)
  15. #define UART_BASE MMR_UART(CONFIG_UART_CONSOLE)
  16. struct bfin_mmr_serial {
  17. u32 revid;
  18. u32 control;
  19. u32 status;
  20. u32 scr;
  21. u32 clock;
  22. u32 emask;
  23. u32 emaskst;
  24. u32 emaskcl;
  25. u32 rbr;
  26. u32 thr;
  27. u32 taip;
  28. u32 tsr;
  29. u32 rsr;
  30. u32 txdiv_cnt;
  31. u32 rxdiv_cnt;
  32. };
  33. #define uart_lsr_t uint32_t
  34. #define _lsr_read(p) bfin_read(&p->status)
  35. #define _lsr_write(p, v) bfin_write(&p->status, v)
  36. __attribute__((always_inline))
  37. static inline void serial_early_do_mach_portmux(char port, int mux_mask,
  38. int mux_func, int port_pin)
  39. {
  40. switch (port) {
  41. case 'D':
  42. bfin_write_PORTD_MUX((bfin_read_PORTD_MUX() &
  43. ~mux_mask) | mux_func);
  44. bfin_write_PORTD_FER_SET(port_pin);
  45. break;
  46. case 'G':
  47. bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() &
  48. ~mux_mask) | mux_func);
  49. bfin_write_PORTG_FER_SET(port_pin);
  50. break;
  51. }
  52. }
  53. __attribute__((always_inline))
  54. static inline void serial_early_do_portmux(void)
  55. {
  56. #if defined(__ADSPBF60x__)
  57. switch (CONFIG_UART_CONSOLE) {
  58. case 0:
  59. serial_early_do_mach_portmux('D', PORT_x_MUX_7_MASK,
  60. PORT_x_MUX_7_FUNC_2, PD7); /* TX: D; mux 7; func 2; PD7 */
  61. serial_early_do_mach_portmux('D', PORT_x_MUX_8_MASK,
  62. PORT_x_MUX_8_FUNC_2, PD8); /* RX: D; mux 8; func 2; PD8 */
  63. break;
  64. case 1:
  65. serial_early_do_mach_portmux('G', PORT_x_MUX_15_MASK,
  66. PORT_x_MUX_15_FUNC_1, PG15); /* TX: G; mux 15; func 1; PG15 */
  67. serial_early_do_mach_portmux('G', PORT_x_MUX_14_MASK,
  68. PORT_x_MUX_14_FUNC_1, PG14); /* RX: G; mux 14; func 1; PG14 */
  69. break;
  70. }
  71. #else
  72. # if (P_UART(RX) & P_DEFINED) || (P_UART(TX) & P_DEFINED)
  73. # error "missing portmux logic for UART"
  74. # endif
  75. #endif
  76. SSYNC();
  77. }
  78. __attribute__((always_inline))
  79. static inline uint32_t uart_sclk(void)
  80. {
  81. #if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL)
  82. /* We cannot use get_sclk() early on as it uses caches in
  83. * external memory
  84. */
  85. return CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV /
  86. CONFIG_SCLK0_DIV;
  87. #else
  88. return get_sclk0();
  89. #endif
  90. }
  91. __attribute__((always_inline))
  92. static inline int uart_init(uint32_t uart_base)
  93. {
  94. /* always enable UART to 8-bit mode */
  95. bfin_write(&pUART->control, UEN | UMOD_UART | WLS_8);
  96. SSYNC();
  97. return 0;
  98. }
  99. __attribute__((always_inline))
  100. static inline int serial_early_init(uint32_t uart_base)
  101. {
  102. /* handle portmux crap on different Blackfins */
  103. serial_do_portmux();
  104. return uart_init(uart_base);
  105. }
  106. __attribute__((always_inline))
  107. static inline int serial_early_uninit(uint32_t uart_base)
  108. {
  109. /* disable the UART by clearing UEN */
  110. bfin_write(&pUART->control, 0);
  111. return 0;
  112. }
  113. __attribute__((always_inline))
  114. static inline int serial_early_enabled(uint32_t uart_base)
  115. {
  116. return bfin_read(&pUART->control) & UEN;
  117. }
  118. __attribute__((always_inline))
  119. static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud)
  120. {
  121. uint32_t divisor = uart_sclk() / (baud * 16);
  122. /* Program the divisor to get the baud rate we want */
  123. bfin_write(&pUART->clock, divisor);
  124. SSYNC();
  125. }
  126. __attribute__((always_inline))
  127. static inline void serial_early_put_div(uint32_t divisor)
  128. {
  129. uint32_t uart_base = UART_BASE;
  130. bfin_write(&pUART->clock, divisor);
  131. }
  132. __attribute__((always_inline))
  133. static inline uint32_t serial_early_get_div(void)
  134. {
  135. uint32_t uart_base = UART_BASE;
  136. return bfin_read(&pUART->clock);
  137. }
  138. #endif
  139. #endif