serial.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 int cogent_serial_getc(void)
  56. {
  57. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  58. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0);
  59. return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f);
  60. }
  61. static int cogent_serial_tstc(void)
  62. {
  63. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_SERIAL_BASE;
  64. return ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) != 0);
  65. }
  66. static struct serial_device cogent_serial_drv = {
  67. .name = "cogent_serial",
  68. .start = cogent_serial_init,
  69. .stop = NULL,
  70. .setbrg = cogent_serial_setbrg,
  71. .putc = cogent_serial_putc,
  72. .puts = default_serial_puts,
  73. .getc = cogent_serial_getc,
  74. .tstc = cogent_serial_tstc,
  75. };
  76. void cogent_serial_initialize(void)
  77. {
  78. serial_register(&cogent_serial_drv);
  79. }
  80. __weak struct serial_device *default_serial_console(void)
  81. {
  82. return &cogent_serial_drv;
  83. }
  84. #endif /* CONS_NONE */
  85. #if defined(CONFIG_CMD_KGDB) && \
  86. defined(CONFIG_KGDB_NONE)
  87. #if CONFIG_KGDB_INDEX == CONFIG_CONS_INDEX
  88. #error Console and kgdb are on the same serial port - this is not supported
  89. #endif
  90. #if CONFIG_KGDB_INDEX == 1
  91. #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALA_BASE
  92. #elif CONFIG_KGDB_INDEX == 2
  93. #define CMA_MB_KGDB_SER_BASE CMA_MB_SERIALB_BASE
  94. #elif CONFIG_KGDB_INDEX == 3 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  95. #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2A_BASE
  96. #elif CONFIG_KGDB_INDEX == 4 && (CMA_MB_CAPS & CMA_MB_CAP_SER2)
  97. #define CMA_MB_KGDB_SER_BASE CMA_MB_SER2B_BASE
  98. #else
  99. #error CONFIG_KGDB_INDEX must be configured for Cogent motherboard serial
  100. #endif
  101. void kgdb_serial_init (void)
  102. {
  103. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  104. unsigned int divisor;
  105. if ((divisor = br_to_div (CONFIG_KGDB_BAUDRATE)) == 0)
  106. divisor = DEFDIV;
  107. cma_mb_reg_write (&mbsp->ser_ier, 0x00); /* turn off interrupts */
  108. cma_mb_reg_write (&mbsp->ser_lcr, 0x80); /* Access baud rate(set DLAB) */
  109. cma_mb_reg_write (&mbsp->ser_brl, divisor & 0xff);
  110. cma_mb_reg_write (&mbsp->ser_brh, (divisor >> 8) & 0xff);
  111. cma_mb_reg_write (&mbsp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */
  112. cma_mb_reg_write (&mbsp->ser_mcr, 0x03); /* RTS/DTR */
  113. cma_mb_reg_write (&mbsp->ser_fcr, 0x07); /* Clear & enable FIFOs */
  114. printf ("[on cma10x serial port B] ");
  115. }
  116. void putDebugChar (int c)
  117. {
  118. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  119. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_THRE) == 0);
  120. cma_mb_reg_write (&mbsp->ser_thr, c & 0xff);
  121. }
  122. void putDebugStr (const char *str)
  123. {
  124. while (*str != '\0') {
  125. if (*str == '\n')
  126. putDebugChar ('\r');
  127. putDebugChar (*str++);
  128. }
  129. }
  130. int getDebugChar (void)
  131. {
  132. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  133. while ((cma_mb_reg_read (&mbsp->ser_lsr) & LSR_DR) == 0);
  134. return ((int) cma_mb_reg_read (&mbsp->ser_rhr) & 0x7f);
  135. }
  136. void kgdb_interruptible (int yes)
  137. {
  138. cma_mb_serial *mbsp = (cma_mb_serial *) CMA_MB_KGDB_SER_BASE;
  139. if (yes == 1) {
  140. printf ("kgdb: turning serial ints on\n");
  141. cma_mb_reg_write (&mbsp->ser_ier, 0xf);
  142. } else {
  143. printf ("kgdb: turning serial ints off\n");
  144. cma_mb_reg_write (&mbsp->ser_ier, 0x0);
  145. }
  146. }
  147. #endif /* KGDB && KGDB_NONE */
  148. #endif /* CAPS & SERPAR */