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