serial_pxa.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * (C) Copyright 2002
  3. * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
  4. *
  5. * (C) Copyright 2002
  6. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  7. * Marius Groeger <mgroeger@sysgo.de>
  8. *
  9. * (C) Copyright 2002
  10. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  11. * Alex Zuepke <azu@sysgo.de>
  12. *
  13. * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation; either version 2 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  28. *
  29. */
  30. #include <common.h>
  31. #include <watchdog.h>
  32. #include <serial.h>
  33. #include <asm/arch/pxa-regs.h>
  34. DECLARE_GLOBAL_DATA_PTR;
  35. #define FFUART_INDEX 0
  36. #define BTUART_INDEX 1
  37. #define STUART_INDEX 2
  38. #ifndef CONFIG_SERIAL_MULTI
  39. #if defined (CONFIG_FFUART)
  40. #define UART_INDEX FFUART_INDEX
  41. #elif defined (CONFIG_BTUART)
  42. #define UART_INDEX BTUART_INDEX
  43. #elif defined (CONFIG_STUART)
  44. #define UART_INDEX STUART_INDEX
  45. #else
  46. #error "Bad: you didn't configure serial ..."
  47. #endif
  48. #endif
  49. void pxa_setbrg_dev (unsigned int uart_index)
  50. {
  51. unsigned int quot = 0;
  52. if (gd->baudrate == 1200)
  53. quot = 768;
  54. else if (gd->baudrate == 9600)
  55. quot = 96;
  56. else if (gd->baudrate == 19200)
  57. quot = 48;
  58. else if (gd->baudrate == 38400)
  59. quot = 24;
  60. else if (gd->baudrate == 57600)
  61. quot = 16;
  62. else if (gd->baudrate == 115200)
  63. quot = 8;
  64. else
  65. hang ();
  66. switch (uart_index) {
  67. case FFUART_INDEX:
  68. #ifdef CONFIG_CPU_MONAHANS
  69. CKENA |= CKENA_22_FFUART;
  70. #else
  71. CKEN |= CKEN6_FFUART;
  72. #endif /* CONFIG_CPU_MONAHANS */
  73. FFIER = 0; /* Disable for now */
  74. FFFCR = 0; /* No fifos enabled */
  75. /* set baud rate */
  76. FFLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB;
  77. FFDLL = quot & 0xff;
  78. FFDLH = quot >> 8;
  79. FFLCR = LCR_WLS0 | LCR_WLS1;
  80. FFIER = IER_UUE; /* Enable FFUART */
  81. break;
  82. case BTUART_INDEX:
  83. #ifdef CONFIG_CPU_MONAHANS
  84. CKENA |= CKENA_21_BTUART;
  85. #else
  86. CKEN |= CKEN7_BTUART;
  87. #endif /* CONFIG_CPU_MONAHANS */
  88. BTIER = 0;
  89. BTFCR = 0;
  90. /* set baud rate */
  91. BTLCR = LCR_DLAB;
  92. BTDLL = quot & 0xff;
  93. BTDLH = quot >> 8;
  94. BTLCR = LCR_WLS0 | LCR_WLS1;
  95. BTIER = IER_UUE; /* Enable BFUART */
  96. break;
  97. case STUART_INDEX:
  98. #ifdef CONFIG_CPU_MONAHANS
  99. CKENA |= CKENA_23_STUART;
  100. #else
  101. CKEN |= CKEN5_STUART;
  102. #endif /* CONFIG_CPU_MONAHANS */
  103. STIER = 0;
  104. STFCR = 0;
  105. /* set baud rate */
  106. STLCR = LCR_DLAB;
  107. STDLL = quot & 0xff;
  108. STDLH = quot >> 8;
  109. STLCR = LCR_WLS0 | LCR_WLS1;
  110. STIER = IER_UUE; /* Enable STUART */
  111. break;
  112. default:
  113. hang();
  114. }
  115. }
  116. /*
  117. * Initialise the serial port with the given baudrate. The settings
  118. * are always 8 data bits, no parity, 1 stop bit, no start bits.
  119. *
  120. */
  121. int pxa_init_dev (unsigned int uart_index)
  122. {
  123. pxa_setbrg_dev (uart_index);
  124. return (0);
  125. }
  126. /*
  127. * Output a single byte to the serial port.
  128. */
  129. void pxa_putc_dev (unsigned int uart_index,const char c)
  130. {
  131. switch (uart_index) {
  132. case FFUART_INDEX:
  133. /* wait for room in the tx FIFO on FFUART */
  134. while ((FFLSR & LSR_TEMT) == 0)
  135. WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
  136. FFTHR = c;
  137. break;
  138. case BTUART_INDEX:
  139. while ((BTLSR & LSR_TEMT ) == 0 )
  140. WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
  141. BTTHR = c;
  142. break;
  143. case STUART_INDEX:
  144. while ((STLSR & LSR_TEMT ) == 0 )
  145. WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
  146. STTHR = c;
  147. break;
  148. }
  149. /* If \n, also do \r */
  150. if (c == '\n')
  151. pxa_putc_dev (uart_index,'\r');
  152. }
  153. /*
  154. * Read a single byte from the serial port. Returns 1 on success, 0
  155. * otherwise. When the function is succesfull, the character read is
  156. * written into its argument c.
  157. */
  158. int pxa_tstc_dev (unsigned int uart_index)
  159. {
  160. switch (uart_index) {
  161. case FFUART_INDEX:
  162. return FFLSR & LSR_DR;
  163. case BTUART_INDEX:
  164. return BTLSR & LSR_DR;
  165. case STUART_INDEX:
  166. return STLSR & LSR_DR;
  167. }
  168. return -1;
  169. }
  170. /*
  171. * Read a single byte from the serial port. Returns 1 on success, 0
  172. * otherwise. When the function is succesfull, the character read is
  173. * written into its argument c.
  174. */
  175. int pxa_getc_dev (unsigned int uart_index)
  176. {
  177. switch (uart_index) {
  178. case FFUART_INDEX:
  179. while (!(FFLSR & LSR_DR))
  180. WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
  181. return (char) FFRBR & 0xff;
  182. case BTUART_INDEX:
  183. while (!(BTLSR & LSR_DR))
  184. WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
  185. return (char) BTRBR & 0xff;
  186. case STUART_INDEX:
  187. while (!(STLSR & LSR_DR))
  188. WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
  189. return (char) STRBR & 0xff;
  190. }
  191. return -1;
  192. }
  193. void
  194. pxa_puts_dev (unsigned int uart_index,const char *s)
  195. {
  196. while (*s) {
  197. pxa_putc_dev (uart_index,*s++);
  198. }
  199. }
  200. #if defined (CONFIG_FFUART)
  201. static int ffuart_init(void)
  202. {
  203. return pxa_init_dev(FFUART_INDEX);
  204. }
  205. static void ffuart_setbrg(void)
  206. {
  207. return pxa_setbrg_dev(FFUART_INDEX);
  208. }
  209. static void ffuart_putc(const char c)
  210. {
  211. return pxa_putc_dev(FFUART_INDEX,c);
  212. }
  213. static void ffuart_puts(const char *s)
  214. {
  215. return pxa_puts_dev(FFUART_INDEX,s);
  216. }
  217. static int ffuart_getc(void)
  218. {
  219. return pxa_getc_dev(FFUART_INDEX);
  220. }
  221. static int ffuart_tstc(void)
  222. {
  223. return pxa_tstc_dev(FFUART_INDEX);
  224. }
  225. struct serial_device serial_ffuart_device =
  226. {
  227. "serial_ffuart",
  228. "PXA",
  229. ffuart_init,
  230. ffuart_setbrg,
  231. ffuart_getc,
  232. ffuart_tstc,
  233. ffuart_putc,
  234. ffuart_puts,
  235. };
  236. #endif
  237. #if defined (CONFIG_BTUART)
  238. static int btuart_init(void)
  239. {
  240. return pxa_init_dev(BTUART_INDEX);
  241. }
  242. static void btuart_setbrg(void)
  243. {
  244. return pxa_setbrg_dev(BTUART_INDEX);
  245. }
  246. static void btuart_putc(const char c)
  247. {
  248. return pxa_putc_dev(BTUART_INDEX,c);
  249. }
  250. static void btuart_puts(const char *s)
  251. {
  252. return pxa_puts_dev(BTUART_INDEX,s);
  253. }
  254. static int btuart_getc(void)
  255. {
  256. return pxa_getc_dev(BTUART_INDEX);
  257. }
  258. static int btuart_tstc(void)
  259. {
  260. return pxa_tstc_dev(BTUART_INDEX);
  261. }
  262. struct serial_device serial_btuart_device =
  263. {
  264. "serial_btuart",
  265. "PXA",
  266. btuart_init,
  267. btuart_setbrg,
  268. btuart_getc,
  269. btuart_tstc,
  270. btuart_putc,
  271. btuart_puts,
  272. };
  273. #endif
  274. #if defined (CONFIG_STUART)
  275. static int stuart_init(void)
  276. {
  277. return pxa_init_dev(STUART_INDEX);
  278. }
  279. static void stuart_setbrg(void)
  280. {
  281. return pxa_setbrg_dev(STUART_INDEX);
  282. }
  283. static void stuart_putc(const char c)
  284. {
  285. return pxa_putc_dev(STUART_INDEX,c);
  286. }
  287. static void stuart_puts(const char *s)
  288. {
  289. return pxa_puts_dev(STUART_INDEX,s);
  290. }
  291. static int stuart_getc(void)
  292. {
  293. return pxa_getc_dev(STUART_INDEX);
  294. }
  295. static int stuart_tstc(void)
  296. {
  297. return pxa_tstc_dev(STUART_INDEX);
  298. }
  299. struct serial_device serial_stuart_device =
  300. {
  301. "serial_stuart",
  302. "PXA",
  303. stuart_init,
  304. stuart_setbrg,
  305. stuart_getc,
  306. stuart_tstc,
  307. stuart_putc,
  308. stuart_puts,
  309. };
  310. #endif
  311. #ifndef CONFIG_SERIAL_MULTI
  312. inline int serial_init(void) {
  313. return (pxa_init_dev(UART_INDEX));
  314. }
  315. void serial_setbrg(void) {
  316. pxa_setbrg_dev(UART_INDEX);
  317. }
  318. int serial_getc(void) {
  319. return(pxa_getc_dev(UART_INDEX));
  320. }
  321. int serial_tstc(void) {
  322. return(pxa_tstc_dev(UART_INDEX));
  323. }
  324. void serial_putc(const char c) {
  325. pxa_putc_dev(UART_INDEX,c);
  326. }
  327. void serial_puts(const char *s) {
  328. pxa_puts_dev(UART_INDEX,s);
  329. }
  330. #endif /* CONFIG_SERIAL_MULTI */