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 31 #include <common.h> 32 #include <watchdog.h> 33 #include <serial.h> 34 #include <asm/arch/pxa-regs.h> 35 36 DECLARE_GLOBAL_DATA_PTR; 37 38 #define FFUART_INDEX 0 39 #define BTUART_INDEX 1 40 #define STUART_INDEX 2 41 42 #ifndef CONFIG_SERIAL_MULTI 43 #if defined (CONFIG_FFUART) 44 #define UART_INDEX FFUART_INDEX 45 #elif defined (CONFIG_BTUART) 46 #define UART_INDEX BTUART_INDEX 47 #elif defined (CONFIG_STUART) 48 #define UART_INDEX STUART_INDEX 49 #else 50 #error "Bad: you didn't configure serial ..." 51 #endif 52 #endif 53 54 void pxa_setbrg_dev (unsigned int uart_index) 55 { 56 unsigned int quot = 0; 57 58 if (gd->baudrate == 1200) 59 quot = 768; 60 else if (gd->baudrate == 9600) 61 quot = 96; 62 else if (gd->baudrate == 19200) 63 quot = 48; 64 else if (gd->baudrate == 38400) 65 quot = 24; 66 else if (gd->baudrate == 57600) 67 quot = 16; 68 else if (gd->baudrate == 115200) 69 quot = 8; 70 else 71 hang (); 72 73 switch (uart_index) { 74 case FFUART_INDEX: 75 #ifdef CONFIG_CPU_MONAHANS 76 CKENA |= CKENA_22_FFUART; 77 #else 78 CKEN |= CKEN6_FFUART; 79 #endif /* CONFIG_CPU_MONAHANS */ 80 81 FFIER = 0; /* Disable for now */ 82 FFFCR = 0; /* No fifos enabled */ 83 84 /* set baud rate */ 85 FFLCR = LCR_WLS0 | LCR_WLS1 | LCR_DLAB; 86 FFDLL = quot & 0xff; 87 FFDLH = quot >> 8; 88 FFLCR = LCR_WLS0 | LCR_WLS1; 89 90 FFIER = IER_UUE; /* Enable FFUART */ 91 break; 92 93 case BTUART_INDEX: 94 #ifdef CONFIG_CPU_MONAHANS 95 CKENA |= CKENA_21_BTUART; 96 #else 97 CKEN |= CKEN7_BTUART; 98 #endif /* CONFIG_CPU_MONAHANS */ 99 100 BTIER = 0; 101 BTFCR = 0; 102 103 /* set baud rate */ 104 BTLCR = LCR_DLAB; 105 BTDLL = quot & 0xff; 106 BTDLH = quot >> 8; 107 BTLCR = LCR_WLS0 | LCR_WLS1; 108 109 BTIER = IER_UUE; /* Enable BFUART */ 110 111 break; 112 113 case STUART_INDEX: 114 #ifdef CONFIG_CPU_MONAHANS 115 CKENA |= CKENA_23_STUART; 116 #else 117 CKEN |= CKEN5_STUART; 118 #endif /* CONFIG_CPU_MONAHANS */ 119 120 STIER = 0; 121 STFCR = 0; 122 123 /* set baud rate */ 124 STLCR = LCR_DLAB; 125 STDLL = quot & 0xff; 126 STDLH = quot >> 8; 127 STLCR = LCR_WLS0 | LCR_WLS1; 128 129 STIER = IER_UUE; /* Enable STUART */ 130 break; 131 132 default: 133 hang(); 134 } 135 } 136 137 138 /* 139 * Initialise the serial port with the given baudrate. The settings 140 * are always 8 data bits, no parity, 1 stop bit, no start bits. 141 * 142 */ 143 int pxa_init_dev (unsigned int uart_index) 144 { 145 pxa_setbrg_dev (uart_index); 146 147 return (0); 148 } 149 150 151 /* 152 * Output a single byte to the serial port. 153 */ 154 void pxa_putc_dev (unsigned int uart_index,const char c) 155 { 156 switch (uart_index) { 157 case FFUART_INDEX: 158 /* wait for room in the tx FIFO on FFUART */ 159 while ((FFLSR & LSR_TEMT) == 0) 160 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ 161 FFTHR = c; 162 break; 163 164 case BTUART_INDEX: 165 while ((BTLSR & LSR_TEMT ) == 0 ) 166 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ 167 BTTHR = c; 168 break; 169 170 case STUART_INDEX: 171 while ((STLSR & LSR_TEMT ) == 0 ) 172 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ 173 STTHR = c; 174 break; 175 } 176 177 /* If \n, also do \r */ 178 if (c == '\n') 179 pxa_putc_dev (uart_index,'\r'); 180 } 181 182 /* 183 * Read a single byte from the serial port. Returns 1 on success, 0 184 * otherwise. When the function is succesfull, the character read is 185 * written into its argument c. 186 */ 187 int pxa_tstc_dev (unsigned int uart_index) 188 { 189 switch (uart_index) { 190 case FFUART_INDEX: 191 return FFLSR & LSR_DR; 192 case BTUART_INDEX: 193 return BTLSR & LSR_DR; 194 case STUART_INDEX: 195 return STLSR & LSR_DR; 196 } 197 return -1; 198 } 199 200 /* 201 * Read a single byte from the serial port. Returns 1 on success, 0 202 * otherwise. When the function is succesfull, the character read is 203 * written into its argument c. 204 */ 205 int pxa_getc_dev (unsigned int uart_index) 206 { 207 switch (uart_index) { 208 case FFUART_INDEX: 209 while (!(FFLSR & LSR_DR)) 210 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ 211 return (char) FFRBR & 0xff; 212 213 case BTUART_INDEX: 214 while (!(BTLSR & LSR_DR)) 215 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ 216 return (char) BTRBR & 0xff; 217 case STUART_INDEX: 218 while (!(STLSR & LSR_DR)) 219 WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */ 220 return (char) STRBR & 0xff; 221 } 222 return -1; 223 } 224 225 void 226 pxa_puts_dev (unsigned int uart_index,const char *s) 227 { 228 while (*s) { 229 pxa_putc_dev (uart_index,*s++); 230 } 231 } 232 233 #if defined (CONFIG_FFUART) 234 static int ffuart_init(void) 235 { 236 return pxa_init_dev(FFUART_INDEX); 237 } 238 239 static void ffuart_setbrg(void) 240 { 241 return pxa_setbrg_dev(FFUART_INDEX); 242 } 243 244 static void ffuart_putc(const char c) 245 { 246 return pxa_putc_dev(FFUART_INDEX,c); 247 } 248 249 static void ffuart_puts(const char *s) 250 { 251 return pxa_puts_dev(FFUART_INDEX,s); 252 } 253 254 static int ffuart_getc(void) 255 { 256 return pxa_getc_dev(FFUART_INDEX); 257 } 258 259 static int ffuart_tstc(void) 260 { 261 return pxa_tstc_dev(FFUART_INDEX); 262 } 263 264 struct serial_device serial_ffuart_device = 265 { 266 "serial_ffuart", 267 "PXA", 268 ffuart_init, 269 ffuart_setbrg, 270 ffuart_getc, 271 ffuart_tstc, 272 ffuart_putc, 273 ffuart_puts, 274 }; 275 #endif 276 277 #if defined (CONFIG_BTUART) 278 static int btuart_init(void) 279 { 280 return pxa_init_dev(BTUART_INDEX); 281 } 282 283 static void btuart_setbrg(void) 284 { 285 return pxa_setbrg_dev(BTUART_INDEX); 286 } 287 288 static void btuart_putc(const char c) 289 { 290 return pxa_putc_dev(BTUART_INDEX,c); 291 } 292 293 static void btuart_puts(const char *s) 294 { 295 return pxa_puts_dev(BTUART_INDEX,s); 296 } 297 298 static int btuart_getc(void) 299 { 300 return pxa_getc_dev(BTUART_INDEX); 301 } 302 303 static int btuart_tstc(void) 304 { 305 return pxa_tstc_dev(BTUART_INDEX); 306 } 307 308 struct serial_device serial_btuart_device = 309 { 310 "serial_btuart", 311 "PXA", 312 btuart_init, 313 btuart_setbrg, 314 btuart_getc, 315 btuart_tstc, 316 btuart_putc, 317 btuart_puts, 318 }; 319 #endif 320 321 #if defined (CONFIG_STUART) 322 static int stuart_init(void) 323 { 324 return pxa_init_dev(STUART_INDEX); 325 } 326 327 static void stuart_setbrg(void) 328 { 329 return pxa_setbrg_dev(STUART_INDEX); 330 } 331 332 static void stuart_putc(const char c) 333 { 334 return pxa_putc_dev(STUART_INDEX,c); 335 } 336 337 static void stuart_puts(const char *s) 338 { 339 return pxa_puts_dev(STUART_INDEX,s); 340 } 341 342 static int stuart_getc(void) 343 { 344 return pxa_getc_dev(STUART_INDEX); 345 } 346 347 static int stuart_tstc(void) 348 { 349 return pxa_tstc_dev(STUART_INDEX); 350 } 351 352 struct serial_device serial_stuart_device = 353 { 354 "serial_stuart", 355 "PXA", 356 stuart_init, 357 stuart_setbrg, 358 stuart_getc, 359 stuart_tstc, 360 stuart_putc, 361 stuart_puts, 362 }; 363 #endif 364 365 366 #ifndef CONFIG_SERIAL_MULTI 367 inline int serial_init(void) { 368 return (pxa_init_dev(UART_INDEX)); 369 } 370 void serial_setbrg(void) { 371 pxa_setbrg_dev(UART_INDEX); 372 } 373 int serial_getc(void) { 374 return(pxa_getc_dev(UART_INDEX)); 375 } 376 int serial_tstc(void) { 377 return(pxa_tstc_dev(UART_INDEX)); 378 } 379 void serial_putc(const char c) { 380 pxa_putc_dev(UART_INDEX,c); 381 } 382 void serial_puts(const char *s) { 383 pxa_puts_dev(UART_INDEX,s); 384 } 385 #endif /* CONFIG_SERIAL_MULTI */ 386