uart_dev_oct16550.c revision 213345
1/*- 2 * Copyright (c) 2003 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27/* 28 * uart_dev_oct16550.c 29 * 30 * Derived from uart_dev_ns8250.c 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 * 53 * 54 */ 55 56 57#include <sys/cdefs.h> 58__FBSDID("$FreeBSD: head/sys/mips/cavium/uart_dev_oct16550.c 213345 2010-10-02 05:38:45Z jmallett $"); 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/bus.h> 63#include <sys/conf.h> 64#include <machine/bus.h> 65#include <machine/pcpu.h> 66 67#include <dev/uart/uart.h> 68#include <dev/uart/uart_cpu.h> 69#include <dev/uart/uart_bus.h> 70 71#include <dev/ic/ns16550.h> 72 73#include <mips/cavium/octeon_pcmap_regs.h> 74 75#include <contrib/octeon-sdk/cvmx.h> 76#include <contrib/octeon-sdk/cvmx-interrupt.h> 77 78#include "uart_if.h" 79 80/* 81 * Clear pending interrupts. THRE is cleared by reading IIR. Data 82 * that may have been received gets lost here. 83 */ 84static void 85oct16550_clrint (struct uart_bas *bas) 86{ 87 uint8_t iir; 88 89 iir = uart_getreg(bas, REG_IIR); 90 while ((iir & IIR_NOPEND) == 0) { 91 iir &= IIR_IMASK; 92 if (iir == IIR_RLS) 93 (void)uart_getreg(bas, REG_LSR); 94 else if (iir == IIR_RXRDY || iir == IIR_RXTOUT) 95 (void)uart_getreg(bas, REG_DATA); 96 else if (iir == IIR_MLSC) 97 (void)uart_getreg(bas, REG_MSR); 98 else if (iir == IIR_BUSY) 99 (void) uart_getreg(bas, REG_USR); 100 uart_barrier(bas); 101 iir = uart_getreg(bas, REG_IIR); 102 } 103} 104 105static int delay_changed = 1; 106 107static int 108oct16550_delay (struct uart_bas *bas) 109{ 110 int divisor; 111 u_char lcr; 112 static int delay = 0; 113 114 if (!delay_changed) return delay; 115 delay_changed = 0; 116 lcr = uart_getreg(bas, REG_LCR); 117 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 118 uart_barrier(bas); 119 divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8); 120 uart_barrier(bas); 121 uart_setreg(bas, REG_LCR, lcr); 122 uart_barrier(bas); 123 124 if(!bas->rclk) 125 return 10; /* return an approx delay value */ 126 127 /* 1/10th the time to transmit 1 character (estimate). */ 128 if (divisor <= 134) 129 return (16000000 * divisor / bas->rclk); 130 return (16000 * divisor / (bas->rclk / 1000)); 131 132} 133 134static int 135oct16550_divisor (int rclk, int baudrate) 136{ 137 int actual_baud, divisor; 138 int error; 139 140 if (baudrate == 0) 141 return (0); 142 143 divisor = (rclk / (baudrate << 3) + 1) >> 1; 144 if (divisor == 0 || divisor >= 65536) 145 return (0); 146 actual_baud = rclk / (divisor << 4); 147 148 /* 10 times error in percent: */ 149 error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1; 150 151 /* 3.0% maximum error tolerance: */ 152 if (error < -30 || error > 30) 153 return (0); 154 155 return (divisor); 156} 157 158static int 159oct16550_drain (struct uart_bas *bas, int what) 160{ 161 int delay, limit; 162 163 delay = oct16550_delay(bas); 164 165 if (what & UART_DRAIN_TRANSMITTER) { 166 /* 167 * Pick an arbitrary high limit to avoid getting stuck in 168 * an infinite loop when the hardware is broken. Make the 169 * limit high enough to handle large FIFOs. 170 */ 171 limit = 10*10*10*1024; 172 while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) 173 DELAY(delay); 174 if (limit == 0) { 175 /* printf("oct16550: transmitter appears stuck... "); */ 176 return (0); 177 } 178 } 179 180 if (what & UART_DRAIN_RECEIVER) { 181 /* 182 * Pick an arbitrary high limit to avoid getting stuck in 183 * an infinite loop when the hardware is broken. Make the 184 * limit high enough to handle large FIFOs and integrated 185 * UARTs. The HP rx2600 for example has 3 UARTs on the 186 * management board that tend to get a lot of data send 187 * to it when the UART is first activated. 188 */ 189 limit=10*4096; 190 while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { 191 (void)uart_getreg(bas, REG_DATA); 192 uart_barrier(bas); 193 DELAY(delay << 2); 194 } 195 if (limit == 0) { 196 /* printf("oct16550: receiver appears broken... "); */ 197 return (EIO); 198 } 199 } 200 201 return (0); 202} 203 204/* 205 * We can only flush UARTs with FIFOs. UARTs without FIFOs should be 206 * drained. WARNING: this function clobbers the FIFO setting! 207 */ 208static void 209oct16550_flush (struct uart_bas *bas, int what) 210{ 211 uint8_t fcr; 212 213 fcr = FCR_ENABLE; 214 if (what & UART_FLUSH_TRANSMITTER) 215 fcr |= FCR_XMT_RST; 216 if (what & UART_FLUSH_RECEIVER) 217 fcr |= FCR_RCV_RST; 218 uart_setreg(bas, REG_FCR, fcr); 219 uart_barrier(bas); 220} 221 222static int 223oct16550_param (struct uart_bas *bas, int baudrate, int databits, int stopbits, 224 int parity) 225{ 226 int divisor; 227 uint8_t lcr; 228 229 lcr = 0; 230 if (databits >= 8) 231 lcr |= LCR_8BITS; 232 else if (databits == 7) 233 lcr |= LCR_7BITS; 234 else if (databits == 6) 235 lcr |= LCR_6BITS; 236 else 237 lcr |= LCR_5BITS; 238 if (stopbits > 1) 239 lcr |= LCR_STOPB; 240 lcr |= parity << 3; 241 242 /* Set baudrate. */ 243 if (baudrate > 0) { 244 divisor = oct16550_divisor(bas->rclk, baudrate); 245 if (divisor == 0) 246 return (EINVAL); 247 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 248 uart_barrier(bas); 249 uart_setreg(bas, REG_DLL, divisor & 0xff); 250 uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); 251 uart_barrier(bas); 252 delay_changed = 1; 253 } 254 255 /* Set LCR and clear DLAB. */ 256 uart_setreg(bas, REG_LCR, lcr); 257 uart_barrier(bas); 258 return (0); 259} 260 261/* 262 * Low-level UART interface. 263 */ 264static int oct16550_probe(struct uart_bas *bas); 265static void oct16550_init(struct uart_bas *bas, int, int, int, int); 266static void oct16550_term(struct uart_bas *bas); 267static void oct16550_putc(struct uart_bas *bas, int); 268static int oct16550_rxready(struct uart_bas *bas); 269static int oct16550_getc(struct uart_bas *bas, struct mtx *); 270 271struct uart_ops uart_oct16550_ops = { 272 .probe = oct16550_probe, 273 .init = oct16550_init, 274 .term = oct16550_term, 275 .putc = oct16550_putc, 276 .rxready = oct16550_rxready, 277 .getc = oct16550_getc, 278}; 279 280static int 281oct16550_probe (struct uart_bas *bas) 282{ 283 u_char val; 284 285 /* Check known 0 bits that don't depend on DLAB. */ 286 val = uart_getreg(bas, REG_IIR); 287 if (val & 0x30) 288 return (ENXIO); 289 val = uart_getreg(bas, REG_MCR); 290 if (val & 0xc0) 291 return (ENXIO); 292 val = uart_getreg(bas, REG_USR); 293 if (val & 0xe0) 294 return (ENXIO); 295 return (0); 296} 297 298static void 299oct16550_init (struct uart_bas *bas, int baudrate, int databits, int stopbits, 300 int parity) 301{ 302 u_char ier; 303 304 oct16550_param(bas, baudrate, databits, stopbits, parity); 305 306 /* Disable all interrupt sources. */ 307 ier = uart_getreg(bas, REG_IER) & 0x0; 308 uart_setreg(bas, REG_IER, ier); 309 uart_barrier(bas); 310 311 /* Disable the FIFO (if present). */ 312// uart_setreg(bas, REG_FCR, 0); 313 uart_barrier(bas); 314 315 /* Set RTS & DTR. */ 316 uart_setreg(bas, REG_MCR, MCR_RTS | MCR_DTR); 317 uart_barrier(bas); 318 319 oct16550_clrint(bas); 320} 321 322static void 323oct16550_term (struct uart_bas *bas) 324{ 325 326 /* Clear RTS & DTR. */ 327 uart_setreg(bas, REG_MCR, 0); 328 uart_barrier(bas); 329} 330 331static inline void oct16550_wait_txhr_empty (struct uart_bas *bas, int limit, int delay) 332{ 333 while (((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) && 334 ((uart_getreg(bas, REG_USR) & USR_TXFIFO_NOTFULL) == 0)) 335 DELAY(delay); 336} 337 338static void 339oct16550_putc (struct uart_bas *bas, int c) 340{ 341 int delay; 342 343 /* 1/10th the time to transmit 1 character (estimate). */ 344 delay = oct16550_delay(bas); 345 oct16550_wait_txhr_empty(bas, 100, delay); 346 uart_setreg(bas, REG_DATA, c); 347 uart_barrier(bas); 348 oct16550_wait_txhr_empty(bas, 100, delay); 349} 350 351static int 352oct16550_rxready (struct uart_bas *bas) 353{ 354 355 return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); 356} 357 358static int 359oct16550_getc (struct uart_bas *bas, struct mtx *hwmtx) 360{ 361 int c, delay; 362 363 uart_lock(hwmtx); 364 365 /* 1/10th the time to transmit 1 character (estimate). */ 366 delay = oct16550_delay(bas); 367 368 while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) { 369 uart_unlock(hwmtx); 370 DELAY(delay); 371 uart_lock(hwmtx); 372 } 373 374 c = uart_getreg(bas, REG_DATA); 375 376 uart_unlock(hwmtx); 377 378 return (c); 379} 380 381/* 382 * High-level UART interface. 383 */ 384struct oct16550_softc { 385 struct uart_softc base; 386 uint8_t fcr; 387 uint8_t ier; 388 uint8_t mcr; 389}; 390 391static int oct16550_bus_attach(struct uart_softc *); 392static int oct16550_bus_detach(struct uart_softc *); 393static int oct16550_bus_flush(struct uart_softc *, int); 394static int oct16550_bus_getsig(struct uart_softc *); 395static int oct16550_bus_ioctl(struct uart_softc *, int, intptr_t); 396static int oct16550_bus_ipend(struct uart_softc *); 397static int oct16550_bus_param(struct uart_softc *, int, int, int, int); 398static int oct16550_bus_probe(struct uart_softc *); 399static int oct16550_bus_receive(struct uart_softc *); 400static int oct16550_bus_setsig(struct uart_softc *, int); 401static int oct16550_bus_transmit(struct uart_softc *); 402 403static kobj_method_t oct16550_methods[] = { 404 KOBJMETHOD(uart_attach, oct16550_bus_attach), 405 KOBJMETHOD(uart_detach, oct16550_bus_detach), 406 KOBJMETHOD(uart_flush, oct16550_bus_flush), 407 KOBJMETHOD(uart_getsig, oct16550_bus_getsig), 408 KOBJMETHOD(uart_ioctl, oct16550_bus_ioctl), 409 KOBJMETHOD(uart_ipend, oct16550_bus_ipend), 410 KOBJMETHOD(uart_param, oct16550_bus_param), 411 KOBJMETHOD(uart_probe, oct16550_bus_probe), 412 KOBJMETHOD(uart_receive, oct16550_bus_receive), 413 KOBJMETHOD(uart_setsig, oct16550_bus_setsig), 414 KOBJMETHOD(uart_transmit, oct16550_bus_transmit), 415 { 0, 0 } 416}; 417 418struct uart_class uart_oct16550_class = { 419 "oct16550 class", 420 oct16550_methods, 421 sizeof(struct oct16550_softc), 422 .uc_ops = &uart_oct16550_ops, 423 .uc_range = 8 << 3, 424 .uc_rclk = 0 425}; 426 427#define SIGCHG(c, i, s, d) \ 428 if (c) { \ 429 i |= (i & s) ? s : s | d; \ 430 } else { \ 431 i = (i & s) ? (i & ~s) | d : i; \ 432 } 433 434static int 435oct16550_bus_attach (struct uart_softc *sc) 436{ 437 struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; 438 struct uart_bas *bas; 439 int unit; 440 441 unit = device_get_unit(sc->sc_dev); 442 bas = &sc->sc_bas; 443 444 oct16550_drain(bas, UART_DRAIN_TRANSMITTER); 445 oct16550->mcr = uart_getreg(bas, REG_MCR); 446 oct16550->fcr = FCR_ENABLE | FCR_RX_HIGH; 447 uart_setreg(bas, REG_FCR, oct16550->fcr); 448 uart_barrier(bas); 449 oct16550_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); 450 451 if (oct16550->mcr & MCR_DTR) 452 sc->sc_hwsig |= SER_DTR; 453 if (oct16550->mcr & MCR_RTS) 454 sc->sc_hwsig |= SER_RTS; 455 oct16550_bus_getsig(sc); 456 457 oct16550_clrint(bas); 458 oct16550->ier = uart_getreg(bas, REG_IER) & 0xf0; 459 oct16550->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY; 460 uart_setreg(bas, REG_IER, oct16550->ier); 461 uart_barrier(bas); 462 463 /* 464 * Enable the interrupt in CIU. // UART-x2 @ IP2 465 */ 466 switch (unit) { 467 case 0: 468 cvmx_interrupt_unmask_irq(CVMX_IRQ_UART0); 469 break; 470 case 1: 471 cvmx_interrupt_unmask_irq(CVMX_IRQ_UART1); 472 break; 473 default: 474 panic("%s: invalid UART %d", __func__, unit); 475 } 476 return (0); 477} 478 479static int 480oct16550_bus_detach (struct uart_softc *sc) 481{ 482 struct uart_bas *bas; 483 u_char ier; 484 485 bas = &sc->sc_bas; 486 ier = uart_getreg(bas, REG_IER) & 0xf0; 487 uart_setreg(bas, REG_IER, ier); 488 uart_barrier(bas); 489 oct16550_clrint(bas); 490 return (0); 491} 492 493static int 494oct16550_bus_flush (struct uart_softc *sc, int what) 495{ 496 struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; 497 struct uart_bas *bas; 498 int error; 499 500 bas = &sc->sc_bas; 501 uart_lock(sc->sc_hwmtx); 502 if (sc->sc_rxfifosz > 1) { 503 oct16550_flush(bas, what); 504 uart_setreg(bas, REG_FCR, oct16550->fcr); 505 uart_barrier(bas); 506 error = 0; 507 } else 508 error = oct16550_drain(bas, what); 509 uart_unlock(sc->sc_hwmtx); 510 return (error); 511} 512 513static int 514oct16550_bus_getsig (struct uart_softc *sc) 515{ 516 uint32_t new, old, sig; 517 uint8_t msr; 518 519 do { 520 old = sc->sc_hwsig; 521 sig = old; 522 uart_lock(sc->sc_hwmtx); 523 msr = uart_getreg(&sc->sc_bas, REG_MSR); 524 uart_unlock(sc->sc_hwmtx); 525 SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR); 526 SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS); 527 SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD); 528 SIGCHG(msr & MSR_RI, sig, SER_RI, SER_DRI); 529 new = sig & ~SER_MASK_DELTA; 530 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 531 return (sig); 532} 533 534static int 535oct16550_bus_ioctl (struct uart_softc *sc, int request, intptr_t data) 536{ 537 struct uart_bas *bas; 538 int baudrate, divisor, error; 539 uint8_t efr, lcr; 540 541 bas = &sc->sc_bas; 542 error = 0; 543 uart_lock(sc->sc_hwmtx); 544 switch (request) { 545 case UART_IOCTL_BREAK: 546 lcr = uart_getreg(bas, REG_LCR); 547 if (data) 548 lcr |= LCR_SBREAK; 549 else 550 lcr &= ~LCR_SBREAK; 551 uart_setreg(bas, REG_LCR, lcr); 552 uart_barrier(bas); 553 break; 554 case UART_IOCTL_IFLOW: 555 lcr = uart_getreg(bas, REG_LCR); 556 uart_barrier(bas); 557 uart_setreg(bas, REG_LCR, 0xbf); 558 uart_barrier(bas); 559 efr = uart_getreg(bas, REG_EFR); 560 if (data) 561 efr |= EFR_RTS; 562 else 563 efr &= ~EFR_RTS; 564 uart_setreg(bas, REG_EFR, efr); 565 uart_barrier(bas); 566 uart_setreg(bas, REG_LCR, lcr); 567 uart_barrier(bas); 568 break; 569 case UART_IOCTL_OFLOW: 570 lcr = uart_getreg(bas, REG_LCR); 571 uart_barrier(bas); 572 uart_setreg(bas, REG_LCR, 0xbf); 573 uart_barrier(bas); 574 efr = uart_getreg(bas, REG_EFR); 575 if (data) 576 efr |= EFR_CTS; 577 else 578 efr &= ~EFR_CTS; 579 uart_setreg(bas, REG_EFR, efr); 580 uart_barrier(bas); 581 uart_setreg(bas, REG_LCR, lcr); 582 uart_barrier(bas); 583 break; 584 case UART_IOCTL_BAUD: 585 lcr = uart_getreg(bas, REG_LCR); 586 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 587 uart_barrier(bas); 588 divisor = uart_getreg(bas, REG_DLL) | 589 (uart_getreg(bas, REG_DLH) << 8); 590 uart_barrier(bas); 591 uart_setreg(bas, REG_LCR, lcr); 592 uart_barrier(bas); 593 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; 594 delay_changed = 1; 595 if (baudrate > 0) 596 *(int*)data = baudrate; 597 else 598 error = ENXIO; 599 break; 600 default: 601 error = EINVAL; 602 break; 603 } 604 uart_unlock(sc->sc_hwmtx); 605 return (error); 606} 607 608 609static int 610oct16550_bus_ipend(struct uart_softc *sc) 611{ 612 struct uart_bas *bas; 613 int ipend = 0; 614 uint8_t iir, lsr; 615 616 bas = &sc->sc_bas; 617 uart_lock(sc->sc_hwmtx); 618 619 iir = uart_getreg(bas, REG_IIR) & IIR_IMASK; 620 if (iir != IIR_NOPEND) { 621 622 if (iir == IIR_RLS) { 623 lsr = uart_getreg(bas, REG_LSR); 624 if (lsr & LSR_OE) 625 ipend |= SER_INT_OVERRUN; 626 if (lsr & LSR_BI) 627 ipend |= SER_INT_BREAK; 628 if (lsr & LSR_RXRDY) 629 ipend |= SER_INT_RXREADY; 630 631 } else if (iir == IIR_RXRDY) { 632 ipend |= SER_INT_RXREADY; 633 634 } else if (iir == IIR_RXTOUT) { 635 ipend |= SER_INT_RXREADY; 636 637 } else if (iir == IIR_TXRDY) { 638 ipend |= SER_INT_TXIDLE; 639 640 } else if (iir == IIR_MLSC) { 641 ipend |= SER_INT_SIGCHG; 642 643 } else if (iir == IIR_BUSY) { 644 (void) uart_getreg(bas, REG_USR); 645 } 646 } 647 uart_unlock(sc->sc_hwmtx); 648 649//#define OCTEON_VISUAL_UART 1 650#ifdef OCTEON_VISUAL_UART 651 static int where1 = 0; 652 653 if (ipend) octeon_led_run_wheel(&where1, 6 + device_get_unit(sc->sc_dev)); 654#endif 655 656 return (ipend); 657} 658 659static int 660oct16550_bus_param (struct uart_softc *sc, int baudrate, int databits, 661 int stopbits, int parity) 662{ 663 struct uart_bas *bas; 664 int error; 665 666 bas = &sc->sc_bas; 667 uart_lock(sc->sc_hwmtx); 668 error = oct16550_param(bas, baudrate, databits, stopbits, parity); 669 uart_unlock(sc->sc_hwmtx); 670 return (error); 671} 672 673static int 674oct16550_bus_probe (struct uart_softc *sc) 675{ 676 struct uart_bas *bas; 677 int error; 678 679 bas = &sc->sc_bas; 680 bas->rclk = uart_oct16550_class.uc_rclk = cvmx_sysinfo_get()->cpu_clock_hz; 681 682 error = oct16550_probe(bas); 683 if (error) { 684 return (error); 685 } 686 687 uart_setreg(bas, REG_MCR, (MCR_DTR | MCR_RTS)); 688 689 /* 690 * Enable FIFOs. And check that the UART has them. If not, we're 691 * done. Since this is the first time we enable the FIFOs, we reset 692 * them. 693 */ 694 oct16550_drain(bas, UART_DRAIN_TRANSMITTER); 695#define ENABLE_OCTEON_FIFO 1 696#ifdef ENABLE_OCTEON_FIFO 697 uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); 698#endif 699 uart_barrier(bas); 700 701 oct16550_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); 702 703 if (device_get_unit(sc->sc_dev)) { 704 device_set_desc(sc->sc_dev, "Octeon-16550 channel 1"); 705 } else { 706 device_set_desc(sc->sc_dev, "Octeon-16550 channel 0"); 707 } 708#ifdef ENABLE_OCTEON_FIFO 709 sc->sc_rxfifosz = 64; 710 sc->sc_txfifosz = 64; 711#else 712 sc->sc_rxfifosz = 1; 713 sc->sc_txfifosz = 1; 714#endif 715 716 717#if 0 718 /* 719 * XXX there are some issues related to hardware flow control and 720 * it's likely that uart(4) is the cause. This basicly needs more 721 * investigation, but we avoid using for hardware flow control 722 * until then. 723 */ 724 /* 16650s or higher have automatic flow control. */ 725 if (sc->sc_rxfifosz > 16) { 726 sc->sc_hwiflow = 1; 727 sc->sc_hwoflow = 1; 728 } 729#endif 730 731 return (0); 732} 733 734static int 735oct16550_bus_receive (struct uart_softc *sc) 736{ 737 struct uart_bas *bas; 738 int xc; 739 uint8_t lsr; 740 741 bas = &sc->sc_bas; 742 uart_lock(sc->sc_hwmtx); 743 lsr = uart_getreg(bas, REG_LSR); 744 745 while (lsr & LSR_RXRDY) { 746 if (uart_rx_full(sc)) { 747 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 748 break; 749 } 750 xc = uart_getreg(bas, REG_DATA); 751 if (lsr & LSR_FE) 752 xc |= UART_STAT_FRAMERR; 753 if (lsr & LSR_PE) 754 xc |= UART_STAT_PARERR; 755 uart_rx_put(sc, xc); 756 lsr = uart_getreg(bas, REG_LSR); 757 } 758 /* Discard everything left in the Rx FIFO. */ 759 /* 760 * First do a dummy read/discard anyway, in case the UART was lying to us. 761 * This problem was seen on board, when IIR said RBR, but LSR said no RXRDY 762 * Results in a stuck ipend loop. 763 */ 764 (void)uart_getreg(bas, REG_DATA); 765 while (lsr & LSR_RXRDY) { 766 (void)uart_getreg(bas, REG_DATA); 767 uart_barrier(bas); 768 lsr = uart_getreg(bas, REG_LSR); 769 } 770 uart_unlock(sc->sc_hwmtx); 771 return (0); 772} 773 774static int 775oct16550_bus_setsig (struct uart_softc *sc, int sig) 776{ 777 struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; 778 struct uart_bas *bas; 779 uint32_t new, old; 780 781 bas = &sc->sc_bas; 782 do { 783 old = sc->sc_hwsig; 784 new = old; 785 if (sig & SER_DDTR) { 786 SIGCHG(sig & SER_DTR, new, SER_DTR, 787 SER_DDTR); 788 } 789 if (sig & SER_DRTS) { 790 SIGCHG(sig & SER_RTS, new, SER_RTS, 791 SER_DRTS); 792 } 793 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 794 uart_lock(sc->sc_hwmtx); 795 oct16550->mcr &= ~(MCR_DTR|MCR_RTS); 796 if (new & SER_DTR) 797 oct16550->mcr |= MCR_DTR; 798 if (new & SER_RTS) 799 oct16550->mcr |= MCR_RTS; 800 uart_setreg(bas, REG_MCR, oct16550->mcr); 801 uart_barrier(bas); 802 uart_unlock(sc->sc_hwmtx); 803 return (0); 804} 805 806static int 807oct16550_bus_transmit (struct uart_softc *sc) 808{ 809 struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; 810 struct uart_bas *bas; 811 int i; 812 813 bas = &sc->sc_bas; 814 uart_lock(sc->sc_hwmtx); 815#ifdef NO_UART_INTERRUPTS 816 for (i = 0; i < sc->sc_txdatasz; i++) { 817 oct16550_putc(bas, sc->sc_txbuf[i]); 818 } 819#else 820 821 oct16550_wait_txhr_empty(bas, 100, oct16550_delay(bas)); 822 uart_setreg(bas, REG_IER, oct16550->ier | IER_ETXRDY); 823 uart_barrier(bas); 824 825 for (i = 0; i < sc->sc_txdatasz; i++) { 826 uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); 827 uart_barrier(bas); 828 } 829 sc->sc_txbusy = 1; 830#endif 831 uart_unlock(sc->sc_hwmtx); 832 return (0); 833} 834