m8xx_tty.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* Minimal serial functions needed to send messages out the serial
  2. * port on the MBX console.
  3. *
  4. * The MBX uxes SMC1 for the serial port. We reset the port and use
  5. * only the first BD that EPPC-Bug set up as a character FIFO.
  6. *
  7. * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
  8. * use COM1 instead of SMC1 as the console port. This kinda sucks
  9. * for the rest of the kernel, so here we force the use of SMC1 again.
  10. */
  11. #include <linux/types.h>
  12. #include <asm/uaccess.h>
  13. #include <asm/mpc8xx.h>
  14. #include <asm/commproc.h>
  15. #ifdef CONFIG_MBX
  16. #define MBX_CSR1 ((volatile u_char *)0xfa100000)
  17. #define CSR1_COMEN (u_char)0x02
  18. #endif
  19. #ifdef TQM_SMC2_CONSOLE
  20. #define PROFF_CONS PROFF_SMC2
  21. #define CPM_CR_CH_CONS CPM_CR_CH_SMC2
  22. #define SMC_INDEX 1
  23. static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
  24. #else
  25. #define PROFF_CONS PROFF_SMC1
  26. #define CPM_CR_CH_CONS CPM_CR_CH_SMC1
  27. #define SMC_INDEX 0
  28. #endif
  29. static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
  30. unsigned long
  31. serial_init(int ignored, bd_t *bd)
  32. {
  33. volatile smc_t *sp;
  34. volatile smc_uart_t *up;
  35. volatile cbd_t *tbdf, *rbdf;
  36. volatile cpm8xx_t *cp;
  37. uint dpaddr, memaddr;
  38. #ifndef CONFIG_MBX
  39. uint ui;
  40. #endif
  41. cp = cpmp;
  42. sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
  43. up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
  44. /* Disable transmitter/receiver.
  45. */
  46. sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
  47. #ifdef CONFIG_FADS
  48. /* Enable SMC1/2 transceivers.
  49. */
  50. *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2);
  51. #endif
  52. #ifndef CONFIG_MBX
  53. {
  54. /* Initialize SMCx and use it for the console port.
  55. */
  56. /* Enable SDMA.
  57. */
  58. ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
  59. #ifdef TQM_SMC2_CONSOLE
  60. /* Use Port A for SMC2 instead of other functions.
  61. */
  62. iopp->iop_papar |= 0x00c0;
  63. iopp->iop_padir &= ~0x00c0;
  64. iopp->iop_paodr &= ~0x00c0;
  65. #else
  66. /* Use Port B for SMCs instead of other functions.
  67. */
  68. cp->cp_pbpar |= 0x00000cc0;
  69. cp->cp_pbdir &= ~0x00000cc0;
  70. cp->cp_pbodr &= ~0x00000cc0;
  71. #endif
  72. /* Allocate space for two buffer descriptors in the DP ram.
  73. * For now, this address seems OK, but it may have to
  74. * change with newer versions of the firmware.
  75. */
  76. dpaddr = 0x0800;
  77. /* Grab a few bytes from the top of memory for SMC FIFOs.
  78. */
  79. memaddr = (bd->bi_memsize - 32) & ~15;
  80. /* Set the physical address of the host memory buffers in
  81. * the buffer descriptors.
  82. */
  83. rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
  84. rbdf->cbd_bufaddr = memaddr;
  85. rbdf->cbd_sc = 0;
  86. tbdf = rbdf + 1;
  87. tbdf->cbd_bufaddr = memaddr+4;
  88. tbdf->cbd_sc = 0;
  89. /* Set up the uart parameters in the parameter ram.
  90. */
  91. up->smc_rbase = dpaddr;
  92. up->smc_tbase = dpaddr+sizeof(cbd_t);
  93. up->smc_rfcr = SMC_EB;
  94. up->smc_tfcr = SMC_EB;
  95. /* Set UART mode, 8 bit, no parity, one stop.
  96. * Enable receive and transmit.
  97. */
  98. sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
  99. /* Mask all interrupts and remove anything pending.
  100. */
  101. sp->smc_smcm = 0;
  102. sp->smc_smce = 0xff;
  103. /* Set up the baud rate generator.
  104. * See 8xx_io/commproc.c for details.
  105. * This wires BRG1 to SMC1 and BRG2 to SMC2;
  106. */
  107. cp->cp_simode = 0x10000000;
  108. ui = bd->bi_intfreq / 16 / bd->bi_baudrate;
  109. #ifdef TQM_SMC2_CONSOLE
  110. cp->cp_brgc2 =
  111. #else
  112. cp->cp_brgc1 =
  113. #endif
  114. ((ui - 1) < 4096)
  115. ? (((ui - 1) << 1) | CPM_BRG_EN)
  116. : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16);
  117. #else /* CONFIG_MBX */
  118. if (*MBX_CSR1 & CSR1_COMEN) {
  119. /* COM1 is enabled. Initialize SMC1 and use it for
  120. * the console port.
  121. */
  122. /* Enable SDMA.
  123. */
  124. ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
  125. /* Use Port B for SMCs instead of other functions.
  126. */
  127. cp->cp_pbpar |= 0x00000cc0;
  128. cp->cp_pbdir &= ~0x00000cc0;
  129. cp->cp_pbodr &= ~0x00000cc0;
  130. /* Allocate space for two buffer descriptors in the DP ram.
  131. * For now, this address seems OK, but it may have to
  132. * change with newer versions of the firmware.
  133. */
  134. dpaddr = 0x0800;
  135. /* Grab a few bytes from the top of memory. EPPC-Bug isn't
  136. * running any more, so we can do this.
  137. */
  138. memaddr = (bd->bi_memsize - 32) & ~15;
  139. /* Set the physical address of the host memory buffers in
  140. * the buffer descriptors.
  141. */
  142. rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
  143. rbdf->cbd_bufaddr = memaddr;
  144. rbdf->cbd_sc = 0;
  145. tbdf = rbdf + 1;
  146. tbdf->cbd_bufaddr = memaddr+4;
  147. tbdf->cbd_sc = 0;
  148. /* Set up the uart parameters in the parameter ram.
  149. */
  150. up->smc_rbase = dpaddr;
  151. up->smc_tbase = dpaddr+sizeof(cbd_t);
  152. up->smc_rfcr = SMC_EB;
  153. up->smc_tfcr = SMC_EB;
  154. /* Set UART mode, 8 bit, no parity, one stop.
  155. * Enable receive and transmit.
  156. */
  157. sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
  158. /* Mask all interrupts and remove anything pending.
  159. */
  160. sp->smc_smcm = 0;
  161. sp->smc_smce = 0xff;
  162. /* Set up the baud rate generator.
  163. * See 8xx_io/commproc.c for details.
  164. */
  165. cp->cp_simode = 0x10000000;
  166. cp->cp_brgc1 =
  167. (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN;
  168. /* Enable SMC1 for console output.
  169. */
  170. *MBX_CSR1 &= ~CSR1_COMEN;
  171. }
  172. else {
  173. #endif /* ndef CONFIG_MBX */
  174. /* SMCx is used as console port.
  175. */
  176. tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
  177. rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
  178. /* Issue a stop transmit, and wait for it.
  179. */
  180. cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
  181. CPM_CR_STOP_TX) | CPM_CR_FLG;
  182. while (cp->cp_cpcr & CPM_CR_FLG);
  183. }
  184. /* Make the first buffer the only buffer.
  185. */
  186. tbdf->cbd_sc |= BD_SC_WRAP;
  187. rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
  188. /* Single character receive.
  189. */
  190. up->smc_mrblr = 1;
  191. up->smc_maxidl = 0;
  192. /* Initialize Tx/Rx parameters.
  193. */
  194. cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
  195. while (cp->cp_cpcr & CPM_CR_FLG);
  196. /* Enable transmitter/receiver.
  197. */
  198. sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
  199. /* This is ignored.
  200. */
  201. return 0;
  202. }
  203. void
  204. serial_putc(void *ignored, const char c)
  205. {
  206. volatile cbd_t *tbdf;
  207. volatile char *buf;
  208. volatile smc_uart_t *up;
  209. up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
  210. tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
  211. /* Wait for last character to go.
  212. */
  213. buf = (char *)tbdf->cbd_bufaddr;
  214. while (tbdf->cbd_sc & BD_SC_READY);
  215. *buf = c;
  216. tbdf->cbd_datlen = 1;
  217. tbdf->cbd_sc |= BD_SC_READY;
  218. }
  219. char
  220. serial_getc(void *ignored)
  221. {
  222. volatile cbd_t *rbdf;
  223. volatile char *buf;
  224. volatile smc_uart_t *up;
  225. char c;
  226. up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
  227. rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
  228. /* Wait for character to show up.
  229. */
  230. buf = (char *)rbdf->cbd_bufaddr;
  231. while (rbdf->cbd_sc & BD_SC_EMPTY);
  232. c = *buf;
  233. rbdf->cbd_sc |= BD_SC_EMPTY;
  234. return(c);
  235. }
  236. int
  237. serial_tstc(void *ignored)
  238. {
  239. volatile cbd_t *rbdf;
  240. volatile smc_uart_t *up;
  241. up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
  242. rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
  243. return(!(rbdf->cbd_sc & BD_SC_EMPTY));
  244. }