serial.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * Simple serial driver for Cogent motherboard serial ports
  3. * for use during boot
  4. */
  5. #include <common.h>
  6. #include <board/cogent/serial.h>
  7. #include <serial.h>
  8. #include <linux/compiler.h>
  9. DECLARE_GLOBAL_DATA_PTR;
  10. #if (CMA_MB_CAPS & CMA_MB_CAP_SERPAR)
  11. #if (defined(CONFIG_8xx) && defined(CONFIG_8xx_CONS_NONE)) || \
  12. (defined(CONFIG_8260) && defined(CONFIG_CONS_NONE))
  13. #if CONFIG_CONS_INDEX == 1
  14. #define CMA_MB_SERIAL_BASE CMA_MB_SERIALA_BASE
  15. #elif CONFIG_CONS_INDEX == 2
  16. #define CMA_MB_SERIAL_BASE CMA_MB_SERIALB_BASE
  17. #elif CONFIG_CONS_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  18. #define CMA_MB_SERIAL_BASE CMA_MB_SER2A_BASE
  19. #elif CONFIG_CONS_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  20. #define CMA_MB_SERIAL_BASE CMA_MB_SER2B_BASE
  21. #else
  22. #error CONFIG_CONS_INDEX must be configured for Cogent motherboard serial
  23. #endif
  24. static int cogent_serial_init(void)
  25. {
  26. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  27. cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */
  28. serial_setbrg ();
  29. cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
  30. cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */
  31. cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
  32. return (0);
  33. }
  34. static void cogent_serial_setbrg(void)
  35. {
  36. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  37. unsigned int divisor;
  38. unsigned char lcr;
  39. if ((divisor = br_to_div (gd->baudrate)) == 0)
  40. divisor = DEFDIV;
  41. lcr = cma_mb_reg_read (&mbsp->ser_lcr);
  42. cma_mb_reg_write (&mbsp->ser_lcr, lcr | 0x80); /* Access baud rate(set DLAB) */
  43. cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff);
  44. cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff);
  45. cma_mb_reg_write (&mbsp->ser_lcr, lcr); /* unset DLAB */
  46. }
  47. static void cogent_serial_putc(const char c)
  48. {
  49. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  50. if (c == '\n')
  51. serial_putc ('\r');
  52. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0);
  53. cma_mb_reg_write (&mbsp->ser_thr, c);
  54. }
  55. static void cogent_serial_puts(const char *s)
  56. {
  57. while (*s != '\0')
  58. serial_putc (*s++);
  59. }
  60. static int cogent_serial_getc(void)
  61. {
  62. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  63. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0);
  64. return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f);
  65. }
  66. static int cogent_serial_tstc(void)
  67. {
  68. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  69. return ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) != 0);
  70. }
  71. #ifdef CONFIG_SERIAL_MULTI
  72. static struct serial_device cogent_serial_drv = {
  73. .name = "cogent_serial",
  74. .start = cogent_serial_init,
  75. .stop = NULL,
  76. .setbrg = cogent_serial_setbrg,
  77. .putc = cogent_serial_putc,
  78. .puts = cogent_serial_puts,
  79. .getc = cogent_serial_getc,
  80. .tstc = cogent_serial_tstc,
  81. };
  82. void cogent_serial_initialize(void)
  83. {
  84. serial_register(&cogent_serial_drv);
  85. }
  86. __weak struct serial_device *default_serial_console(void)
  87. {
  88. return &cogent_serial_drv;
  89. }
  90. #else
  91. int serial_init(void)
  92. {
  93. return cogent_serial_init();
  94. }
  95. void serial_setbrg(void)
  96. {
  97. cogent_serial_setbrg();
  98. }
  99. void serial_putc(const char c)
  100. {
  101. cogent_serial_putc(c);
  102. }
  103. void serial_puts(const char *s)
  104. {
  105. cogent_serial_puts(s);
  106. }
  107. int serial_getc(void)
  108. {
  109. return cogent_serial_getc();
  110. }
  111. int serial_tstc(void)
  112. {
  113. return cogent_serial_tstc();
  114. }
  115. #endif
  116. #endif /* CONS_NONE */
  117. #if defined(CONFIG_CMD_KGDB) && \
  118. defined(CONFIG_KGDB_NONE)
  119. #if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
  120. #error Console and kgdb are on the same serial port - this is not supported
  121. #endif
  122. #if CONFIG_KGDB_INDEX == 1
  123. #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALA_BASE
  124. #elif CONFIG_KGDB_INDEX == 2
  125. #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALB_BASE
  126. #elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  127. #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2A_BASE
  128. #elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  129. #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2B_BASE
  130. #else
  131. #error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial
  132. #endif
  133. void kgdb_serial_init (void)
  134. {
  135. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  136. unsigned int divisor;
  137. if ((divisor = br_to_div (CONFIG_KGDB_BAUDRATE)) == 0)
  138. divisor = DEFDIV;
  139. cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */
  140. cma_mb_reg_write (&mbsp->ser_lcr, 0x80); /* Access baud rate(set DLAB) */
  141. cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff);
  142. cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff);
  143. cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
  144. cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */
  145. cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
  146. printf ("[on cma10x serial port B] ");
  147. }
  148. void putDebugChar (int c)
  149. {
  150. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  151. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0);
  152. cma_mb_reg_write (&mbsp->ser_thr, c & 0xff);
  153. }
  154. void putDebugStr (const char *str)
  155. {
  156. while (*str != '\0') {
  157. if (*str == '\n')
  158. putDebugChar ('\r');
  159. putDebugChar (*str++);
  160. }
  161. }
  162. int getDebugChar (void)
  163. {
  164. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  165. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0);
  166. return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f);
  167. }
  168. void kgdb_interruptible (int yes)
  169. {
  170. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  171. if (yes == 1) {
  172. printf ("kgdb: turning serial ints on\n");
  173. cma_mb_reg_write (&mbsp->ser_ier, 0xf);
  174. } else {
  175. printf ("kgdb: turning serial ints off\n");
  176. cma_mb_reg_write (&mbsp->ser_ier, 0x0);
  177. }
  178. }
  179. #endif /* KGDB && KGDB_NONE */
  180. #endif /* CAPS & SERPAR */