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