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 "PXA", 272 ffuart_init, 273 NULL, 274 ffuart_setbrg, 275 ffuart_getc, 276 ffuart_tstc, 277 ffuart_putc, 278 ffuart_puts, 279 }; 280 #endif 281 282 #if defined (CONFIG_BTUART) 283 static int btuart_init(void) 284 { 285 return pxa_init_dev(BTUART_INDEX); 286 } 287 288 static void btuart_setbrg(void) 289 { 290 return pxa_setbrg_dev(BTUART_INDEX); 291 } 292 293 static void btuart_putc(const char c) 294 { 295 return pxa_putc_dev(BTUART_INDEX,c); 296 } 297 298 static void btuart_puts(const char *s) 299 { 300 return pxa_puts_dev(BTUART_INDEX,s); 301 } 302 303 static int btuart_getc(void) 304 { 305 return pxa_getc_dev(BTUART_INDEX); 306 } 307 308 static int btuart_tstc(void) 309 { 310 return pxa_tstc_dev(BTUART_INDEX); 311 } 312 313 struct serial_device serial_btuart_device = 314 { 315 "serial_btuart", 316 "PXA", 317 btuart_init, 318 NULL, 319 btuart_setbrg, 320 btuart_getc, 321 btuart_tstc, 322 btuart_putc, 323 btuart_puts, 324 }; 325 #endif 326 327 #if defined (CONFIG_STUART) 328 static int stuart_init(void) 329 { 330 return pxa_init_dev(STUART_INDEX); 331 } 332 333 static void stuart_setbrg(void) 334 { 335 return pxa_setbrg_dev(STUART_INDEX); 336 } 337 338 static void stuart_putc(const char c) 339 { 340 return pxa_putc_dev(STUART_INDEX,c); 341 } 342 343 static void stuart_puts(const char *s) 344 { 345 return pxa_puts_dev(STUART_INDEX,s); 346 } 347 348 static int stuart_getc(void) 349 { 350 return pxa_getc_dev(STUART_INDEX); 351 } 352 353 static int stuart_tstc(void) 354 { 355 return pxa_tstc_dev(STUART_INDEX); 356 } 357 358 struct serial_device serial_stuart_device = 359 { 360 "serial_stuart", 361 "PXA", 362 stuart_init, 363 NULL, 364 stuart_setbrg, 365 stuart_getc, 366 stuart_tstc, 367 stuart_putc, 368 stuart_puts, 369 }; 370 #endif 371 372 373 #ifndef CONFIG_SERIAL_MULTI 374 inline int serial_init(void) { 375 return (pxa_init_dev(UART_INDEX)); 376 } 377 void serial_setbrg(void) { 378 pxa_setbrg_dev(UART_INDEX); 379 } 380 int serial_getc(void) { 381 return(pxa_getc_dev(UART_INDEX)); 382 } 383 int serial_tstc(void) { 384 return(pxa_tstc_dev(UART_INDEX)); 385 } 386 void serial_putc(const char c) { 387 pxa_putc_dev(UART_INDEX,c); 388 } 389 void serial_puts(const char *s) { 390 pxa_puts_dev(UART_INDEX,s); 391 } 392 #endif /* CONFIG_SERIAL_MULTI */ 393