serial.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. DECLARE_GLOBAL_DATA_PTR;
  8. #if (CMA_MB_CAPS & CMA_MB_CAP_SERPAR)
  9. #if (defined(CONFIG_8xx) && defined(CONFIG_8xx_CONS_NONE)) || \
  10. (defined(CONFIG_8260) && defined(CONFIG_CONS_NONE))
  11. #if CONFIG_CONS_INDEX == 1
  12. #define CMA_MB_SERIAL_BASE CMA_MB_SERIALA_BASE
  13. #elif CONFIG_CONS_INDEX == 2
  14. #define CMA_MB_SERIAL_BASE CMA_MB_SERIALB_BASE
  15. #elif CONFIG_CONS_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  16. #define CMA_MB_SERIAL_BASE CMA_MB_SER2A_BASE
  17. #elif CONFIG_CONS_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  18. #define CMA_MB_SERIAL_BASE CMA_MB_SER2B_BASE
  19. #else
  20. #error CONFIG_CONS_INDEX must be configured for Cogent motherboard serial
  21. #endif
  22. int serial_init (void)
  23. {
  24. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  25. cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */
  26. serial_setbrg ();
  27. cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
  28. cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */
  29. cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
  30. return (0);
  31. }
  32. void serial_setbrg (void)
  33. {
  34. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  35. unsigned int divisor;
  36. unsigned char lcr;
  37. if ((divisor = br_to_div (gd->baudrate)) == 0)
  38. divisor = DEFDIV;
  39. lcr = cma_mb_reg_read (&mbsp->ser_lcr);
  40. cma_mb_reg_write (&mbsp->ser_lcr, lcr | 0x80); /* Access baud rate(set DLAB) */
  41. cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff);
  42. cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff);
  43. cma_mb_reg_write (&mbsp->ser_lcr, lcr); /* unset DLAB */
  44. }
  45. void serial_putc (const char c)
  46. {
  47. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  48. if (c == '\n')
  49. serial_putc ('\r');
  50. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0);
  51. cma_mb_reg_write (&mbsp->ser_thr, c);
  52. }
  53. void serial_puts (const char *s)
  54. {
  55. while (*s != '\0')
  56. serial_putc (*s++);
  57. }
  58. int serial_getc (void)
  59. {
  60. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  61. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0);
  62. return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f);
  63. }
  64. int serial_tstc (void)
  65. {
  66. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  67. return ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) != 0);
  68. }
  69. #endif /* CONS_NONE */
  70. #if defined(CONFIG_CMD_KGDB) && \
  71. defined(CONFIG_KGDB_NONE)
  72. #if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
  73. #error Console and kgdb are on the same serial port - this is not supported
  74. #endif
  75. #if CONFIG_KGDB_INDEX == 1
  76. #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALA_BASE
  77. #elif CONFIG_KGDB_INDEX == 2
  78. #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALB_BASE
  79. #elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  80. #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2A_BASE
  81. #elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  82. #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2B_BASE
  83. #else
  84. #error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial
  85. #endif
  86. void kgdb_serial_init (void)
  87. {
  88. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  89. unsigned int divisor;
  90. if ((divisor = br_to_div (CONFIG_KGDB_BAUDRATE)) == 0)
  91. divisor = DEFDIV;
  92. cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */
  93. cma_mb_reg_write (&mbsp->ser_lcr, 0x80); /* Access baud rate(set DLAB) */
  94. cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff);
  95. cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff);
  96. cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
  97. cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */
  98. cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
  99. printf ("[on cma10x serial port B] ");
  100. }
  101. void putDebugChar (int c)
  102. {
  103. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  104. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0);
  105. cma_mb_reg_write (&mbsp->ser_thr, c & 0xff);
  106. }
  107. void putDebugStr (const char *str)
  108. {
  109. while (*str != '\0') {
  110. if (*str == '\n')
  111. putDebugChar ('\r');
  112. putDebugChar (*str++);
  113. }
  114. }
  115. int getDebugChar (void)
  116. {
  117. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  118. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0);
  119. return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f);
  120. }
  121. void kgdb_interruptible (int yes)
  122. {
  123. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  124. if (yes == 1) {
  125. printf ("kgdb: turning serial ints on\n");
  126. cma_mb_reg_write (&mbsp->ser_ier, 0xf);
  127. } else {
  128. printf ("kgdb: turning serial ints off\n");
  129. cma_mb_reg_write (&mbsp->ser_ier, 0x0);
  130. }
  131. }
  132. #endif /* KGDB && KGDB_NONE */
  133. #endif /* CAPS & SERPAR */