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