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