1139749Simp/*- 2119815Smarcel * Copyright (c) 2003 Marcel Moolenaar 3119815Smarcel * All rights reserved. 4119815Smarcel * 5119815Smarcel * Redistribution and use in source and binary forms, with or without 6119815Smarcel * modification, are permitted provided that the following conditions 7119815Smarcel * are met: 8119815Smarcel * 9119815Smarcel * 1. Redistributions of source code must retain the above copyright 10119815Smarcel * notice, this list of conditions and the following disclaimer. 11119815Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12119815Smarcel * notice, this list of conditions and the following disclaimer in the 13119815Smarcel * documentation and/or other materials provided with the distribution. 14119815Smarcel * 15119815Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16119815Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17119815Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18119815Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19119815Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20119815Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21119815Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22119815Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23119815Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24119815Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25119815Smarcel */ 26119815Smarcel 27247519Sganbold#include "opt_platform.h" 28247519Sganbold 29119815Smarcel#include <sys/cdefs.h> 30119815Smarcel__FBSDID("$FreeBSD: releng/10.3/sys/dev/uart/uart_dev_ns8250.c 294229 2016-01-17 18:18:01Z ian $"); 31119815Smarcel 32119815Smarcel#include <sys/param.h> 33119815Smarcel#include <sys/systm.h> 34119815Smarcel#include <sys/bus.h> 35119815Smarcel#include <sys/conf.h> 36246016Scperciva#include <sys/kernel.h> 37246016Scperciva#include <sys/sysctl.h> 38119815Smarcel#include <machine/bus.h> 39119815Smarcel 40247519Sganbold#ifdef FDT 41247519Sganbold#include <dev/fdt/fdt_common.h> 42247519Sganbold#include <dev/ofw/ofw_bus.h> 43247519Sganbold#include <dev/ofw/ofw_bus_subr.h> 44247519Sganbold#endif 45247519Sganbold 46119815Smarcel#include <dev/uart/uart.h> 47119815Smarcel#include <dev/uart/uart_cpu.h> 48283327Sian#ifdef FDT 49283327Sian#include <dev/uart/uart_cpu_fdt.h> 50283327Sian#endif 51119815Smarcel#include <dev/uart/uart_bus.h> 52254597Sian#include <dev/uart/uart_dev_ns8250.h> 53294229Sian#include <dev/uart/uart_ppstypes.h> 54119815Smarcel 55137949Smarcel#include <dev/ic/ns16550.h> 56137949Smarcel 57119815Smarcel#include "uart_if.h" 58119815Smarcel 59119815Smarcel#define DEFAULT_RCLK 1843200 60119815Smarcel 61247519Sganboldstatic int broken_txfifo = 0; 62247519SganboldSYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RW | CTLFLAG_TUN, 63247519Sganbold &broken_txfifo, 0, "UART FIFO has QEMU emulation bug"); 64247519SganboldTUNABLE_INT("hw.broken_txfifo", &broken_txfifo); 65247519Sganbold 66119815Smarcel/* 67119815Smarcel * Clear pending interrupts. THRE is cleared by reading IIR. Data 68119815Smarcel * that may have been received gets lost here. 69119815Smarcel */ 70119815Smarcelstatic void 71119815Smarcelns8250_clrint(struct uart_bas *bas) 72119815Smarcel{ 73190834Smarcel uint8_t iir, lsr; 74119815Smarcel 75119815Smarcel iir = uart_getreg(bas, REG_IIR); 76119815Smarcel while ((iir & IIR_NOPEND) == 0) { 77119815Smarcel iir &= IIR_IMASK; 78190834Smarcel if (iir == IIR_RLS) { 79190834Smarcel lsr = uart_getreg(bas, REG_LSR); 80190834Smarcel if (lsr & (LSR_BI|LSR_FE|LSR_PE)) 81190834Smarcel (void)uart_getreg(bas, REG_DATA); 82190834Smarcel } else if (iir == IIR_RXRDY || iir == IIR_RXTOUT) 83119815Smarcel (void)uart_getreg(bas, REG_DATA); 84119815Smarcel else if (iir == IIR_MLSC) 85119815Smarcel (void)uart_getreg(bas, REG_MSR); 86119815Smarcel uart_barrier(bas); 87119815Smarcel iir = uart_getreg(bas, REG_IIR); 88119815Smarcel } 89119815Smarcel} 90119815Smarcel 91119815Smarcelstatic int 92119815Smarcelns8250_delay(struct uart_bas *bas) 93119815Smarcel{ 94119815Smarcel int divisor; 95119815Smarcel u_char lcr; 96119815Smarcel 97119815Smarcel lcr = uart_getreg(bas, REG_LCR); 98119815Smarcel uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 99119815Smarcel uart_barrier(bas); 100158844Sbenno divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8); 101119815Smarcel uart_barrier(bas); 102119815Smarcel uart_setreg(bas, REG_LCR, lcr); 103119815Smarcel uart_barrier(bas); 104119815Smarcel 105119815Smarcel /* 1/10th the time to transmit 1 character (estimate). */ 106168000Smarcel if (divisor <= 134) 107168000Smarcel return (16000000 * divisor / bas->rclk); 108168000Smarcel return (16000 * divisor / (bas->rclk / 1000)); 109119815Smarcel} 110119815Smarcel 111119815Smarcelstatic int 112119815Smarcelns8250_divisor(int rclk, int baudrate) 113119815Smarcel{ 114119815Smarcel int actual_baud, divisor; 115119815Smarcel int error; 116119815Smarcel 117119815Smarcel if (baudrate == 0) 118119815Smarcel return (0); 119119815Smarcel 120119815Smarcel divisor = (rclk / (baudrate << 3) + 1) >> 1; 121119815Smarcel if (divisor == 0 || divisor >= 65536) 122119815Smarcel return (0); 123119815Smarcel actual_baud = rclk / (divisor << 4); 124119815Smarcel 125119815Smarcel /* 10 times error in percent: */ 126119815Smarcel error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1; 127119815Smarcel 128119815Smarcel /* 3.0% maximum error tolerance: */ 129119815Smarcel if (error < -30 || error > 30) 130119815Smarcel return (0); 131119815Smarcel 132119815Smarcel return (divisor); 133119815Smarcel} 134119815Smarcel 135119815Smarcelstatic int 136119815Smarcelns8250_drain(struct uart_bas *bas, int what) 137119815Smarcel{ 138119815Smarcel int delay, limit; 139119815Smarcel 140119815Smarcel delay = ns8250_delay(bas); 141119815Smarcel 142119815Smarcel if (what & UART_DRAIN_TRANSMITTER) { 143119815Smarcel /* 144119815Smarcel * Pick an arbitrary high limit to avoid getting stuck in 145119815Smarcel * an infinite loop when the hardware is broken. Make the 146119815Smarcel * limit high enough to handle large FIFOs. 147119815Smarcel */ 148119815Smarcel limit = 10*1024; 149119815Smarcel while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) 150119815Smarcel DELAY(delay); 151119815Smarcel if (limit == 0) { 152119815Smarcel /* printf("ns8250: transmitter appears stuck... "); */ 153119815Smarcel return (EIO); 154119815Smarcel } 155119815Smarcel } 156119815Smarcel 157119815Smarcel if (what & UART_DRAIN_RECEIVER) { 158119815Smarcel /* 159119815Smarcel * Pick an arbitrary high limit to avoid getting stuck in 160119815Smarcel * an infinite loop when the hardware is broken. Make the 161119815Smarcel * limit high enough to handle large FIFOs and integrated 162119815Smarcel * UARTs. The HP rx2600 for example has 3 UARTs on the 163119815Smarcel * management board that tend to get a lot of data send 164119815Smarcel * to it when the UART is first activated. 165119815Smarcel */ 166119815Smarcel limit=10*4096; 167119815Smarcel while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { 168119815Smarcel (void)uart_getreg(bas, REG_DATA); 169119815Smarcel uart_barrier(bas); 170119815Smarcel DELAY(delay << 2); 171119815Smarcel } 172119815Smarcel if (limit == 0) { 173119815Smarcel /* printf("ns8250: receiver appears broken... "); */ 174119815Smarcel return (EIO); 175119815Smarcel } 176119815Smarcel } 177119815Smarcel 178119815Smarcel return (0); 179119815Smarcel} 180119815Smarcel 181119815Smarcel/* 182119815Smarcel * We can only flush UARTs with FIFOs. UARTs without FIFOs should be 183119815Smarcel * drained. WARNING: this function clobbers the FIFO setting! 184119815Smarcel */ 185119815Smarcelstatic void 186119815Smarcelns8250_flush(struct uart_bas *bas, int what) 187119815Smarcel{ 188119815Smarcel uint8_t fcr; 189119815Smarcel 190119815Smarcel fcr = FCR_ENABLE; 191119815Smarcel if (what & UART_FLUSH_TRANSMITTER) 192119815Smarcel fcr |= FCR_XMT_RST; 193119815Smarcel if (what & UART_FLUSH_RECEIVER) 194119815Smarcel fcr |= FCR_RCV_RST; 195119815Smarcel uart_setreg(bas, REG_FCR, fcr); 196119815Smarcel uart_barrier(bas); 197119815Smarcel} 198119815Smarcel 199119815Smarcelstatic int 200119815Smarcelns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits, 201119815Smarcel int parity) 202119815Smarcel{ 203119815Smarcel int divisor; 204119815Smarcel uint8_t lcr; 205119815Smarcel 206119815Smarcel lcr = 0; 207119815Smarcel if (databits >= 8) 208119815Smarcel lcr |= LCR_8BITS; 209119815Smarcel else if (databits == 7) 210119815Smarcel lcr |= LCR_7BITS; 211119815Smarcel else if (databits == 6) 212119815Smarcel lcr |= LCR_6BITS; 213119815Smarcel else 214119815Smarcel lcr |= LCR_5BITS; 215119815Smarcel if (stopbits > 1) 216119815Smarcel lcr |= LCR_STOPB; 217119815Smarcel lcr |= parity << 3; 218119815Smarcel 219119815Smarcel /* Set baudrate. */ 220119815Smarcel if (baudrate > 0) { 221119815Smarcel divisor = ns8250_divisor(bas->rclk, baudrate); 222119815Smarcel if (divisor == 0) 223119815Smarcel return (EINVAL); 224157989Smarcel uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 225157989Smarcel uart_barrier(bas); 226158844Sbenno uart_setreg(bas, REG_DLL, divisor & 0xff); 227158844Sbenno uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); 228119815Smarcel uart_barrier(bas); 229119815Smarcel } 230119815Smarcel 231119815Smarcel /* Set LCR and clear DLAB. */ 232119815Smarcel uart_setreg(bas, REG_LCR, lcr); 233119815Smarcel uart_barrier(bas); 234119815Smarcel return (0); 235119815Smarcel} 236119815Smarcel 237119815Smarcel/* 238119815Smarcel * Low-level UART interface. 239119815Smarcel */ 240119815Smarcelstatic int ns8250_probe(struct uart_bas *bas); 241119815Smarcelstatic void ns8250_init(struct uart_bas *bas, int, int, int, int); 242119815Smarcelstatic void ns8250_term(struct uart_bas *bas); 243119815Smarcelstatic void ns8250_putc(struct uart_bas *bas, int); 244166100Smariusstatic int ns8250_rxready(struct uart_bas *bas); 245157380Smarcelstatic int ns8250_getc(struct uart_bas *bas, struct mtx *); 246119815Smarcel 247254597Sianstruct uart_ops uart_ns8250_ops = { 248119815Smarcel .probe = ns8250_probe, 249119815Smarcel .init = ns8250_init, 250119815Smarcel .term = ns8250_term, 251119815Smarcel .putc = ns8250_putc, 252166100Smarius .rxready = ns8250_rxready, 253119815Smarcel .getc = ns8250_getc, 254119815Smarcel}; 255119815Smarcel 256119815Smarcelstatic int 257119815Smarcelns8250_probe(struct uart_bas *bas) 258119815Smarcel{ 259158849Sbenno u_char val; 260119815Smarcel 261119815Smarcel /* Check known 0 bits that don't depend on DLAB. */ 262119815Smarcel val = uart_getreg(bas, REG_IIR); 263119815Smarcel if (val & 0x30) 264119815Smarcel return (ENXIO); 265222317Smarcel /* 266222317Smarcel * Bit 6 of the MCR (= 0x40) appears to be 1 for the Sun1699 267222317Smarcel * chip, but otherwise doesn't seem to have a function. In 268222317Smarcel * other words, uart(4) works regardless. Ignore that bit so 269222317Smarcel * the probe succeeds. 270222317Smarcel */ 271119815Smarcel val = uart_getreg(bas, REG_MCR); 272222317Smarcel if (val & 0xa0) 273119815Smarcel return (ENXIO); 274119815Smarcel 275119815Smarcel return (0); 276119815Smarcel} 277119815Smarcel 278119815Smarcelstatic void 279119815Smarcelns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 280119815Smarcel int parity) 281119815Smarcel{ 282158844Sbenno u_char ier; 283119815Smarcel 284119815Smarcel if (bas->rclk == 0) 285119815Smarcel bas->rclk = DEFAULT_RCLK; 286119815Smarcel ns8250_param(bas, baudrate, databits, stopbits, parity); 287119815Smarcel 288119815Smarcel /* Disable all interrupt sources. */ 289179420Sbenno /* 290179420Sbenno * We use 0xe0 instead of 0xf0 as the mask because the XScale PXA 291179420Sbenno * UARTs split the receive time-out interrupt bit out separately as 292179420Sbenno * 0x10. This gets handled by ier_mask and ier_rxbits below. 293179420Sbenno */ 294179420Sbenno ier = uart_getreg(bas, REG_IER) & 0xe0; 295158844Sbenno uart_setreg(bas, REG_IER, ier); 296119815Smarcel uart_barrier(bas); 297119815Smarcel 298119815Smarcel /* Disable the FIFO (if present). */ 299119815Smarcel uart_setreg(bas, REG_FCR, 0); 300119815Smarcel uart_barrier(bas); 301119815Smarcel 302119815Smarcel /* Set RTS & DTR. */ 303119815Smarcel uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR); 304119815Smarcel uart_barrier(bas); 305119815Smarcel 306119815Smarcel ns8250_clrint(bas); 307119815Smarcel} 308119815Smarcel 309119815Smarcelstatic void 310119815Smarcelns8250_term(struct uart_bas *bas) 311119815Smarcel{ 312119815Smarcel 313119815Smarcel /* Clear RTS & DTR. */ 314119815Smarcel uart_setreg(bas, REG_MCR, MCR_IE); 315119815Smarcel uart_barrier(bas); 316119815Smarcel} 317119815Smarcel 318119815Smarcelstatic void 319119815Smarcelns8250_putc(struct uart_bas *bas, int c) 320119815Smarcel{ 321168285Smarcel int limit; 322119815Smarcel 323168285Smarcel limit = 250000; 324119815Smarcel while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit) 325168285Smarcel DELAY(4); 326119815Smarcel uart_setreg(bas, REG_DATA, c); 327127742Smarcel uart_barrier(bas); 328168285Smarcel limit = 250000; 329119815Smarcel while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) 330168285Smarcel DELAY(4); 331119815Smarcel} 332119815Smarcel 333119815Smarcelstatic int 334166100Smariusns8250_rxready(struct uart_bas *bas) 335119815Smarcel{ 336119815Smarcel 337166100Smarius return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); 338119815Smarcel} 339119815Smarcel 340119815Smarcelstatic int 341157380Smarcelns8250_getc(struct uart_bas *bas, struct mtx *hwmtx) 342119815Smarcel{ 343168285Smarcel int c; 344119815Smarcel 345157380Smarcel uart_lock(hwmtx); 346157380Smarcel 347157380Smarcel while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) { 348157380Smarcel uart_unlock(hwmtx); 349168285Smarcel DELAY(4); 350157380Smarcel uart_lock(hwmtx); 351157380Smarcel } 352157380Smarcel 353157380Smarcel c = uart_getreg(bas, REG_DATA); 354157380Smarcel 355157380Smarcel uart_unlock(hwmtx); 356157380Smarcel 357157380Smarcel return (c); 358119815Smarcel} 359119815Smarcel 360119815Smarcelstatic kobj_method_t ns8250_methods[] = { 361119815Smarcel KOBJMETHOD(uart_attach, ns8250_bus_attach), 362119815Smarcel KOBJMETHOD(uart_detach, ns8250_bus_detach), 363119815Smarcel KOBJMETHOD(uart_flush, ns8250_bus_flush), 364119815Smarcel KOBJMETHOD(uart_getsig, ns8250_bus_getsig), 365119815Smarcel KOBJMETHOD(uart_ioctl, ns8250_bus_ioctl), 366119815Smarcel KOBJMETHOD(uart_ipend, ns8250_bus_ipend), 367119815Smarcel KOBJMETHOD(uart_param, ns8250_bus_param), 368119815Smarcel KOBJMETHOD(uart_probe, ns8250_bus_probe), 369119815Smarcel KOBJMETHOD(uart_receive, ns8250_bus_receive), 370119815Smarcel KOBJMETHOD(uart_setsig, ns8250_bus_setsig), 371119815Smarcel KOBJMETHOD(uart_transmit, ns8250_bus_transmit), 372262649Simp KOBJMETHOD(uart_grab, ns8250_bus_grab), 373262649Simp KOBJMETHOD(uart_ungrab, ns8250_bus_ungrab), 374119815Smarcel { 0, 0 } 375119815Smarcel}; 376119815Smarcel 377119815Smarcelstruct uart_class uart_ns8250_class = { 378168281Smarcel "ns8250", 379119815Smarcel ns8250_methods, 380119815Smarcel sizeof(struct ns8250_softc), 381168281Smarcel .uc_ops = &uart_ns8250_ops, 382119815Smarcel .uc_range = 8, 383119815Smarcel .uc_rclk = DEFAULT_RCLK 384119815Smarcel}; 385119815Smarcel 386283327Sian#ifdef FDT 387283327Sianstatic struct ofw_compat_data compat_data[] = { 388283327Sian {"ns16550", (uintptr_t)&uart_ns8250_class}, 389283327Sian {NULL, (uintptr_t)NULL}, 390283327Sian}; 391283327SianUART_FDT_CLASS_AND_DEVICE(compat_data); 392283327Sian#endif 393283327Sian 394294229Sian/* Use token-pasting to form SER_ and MSR_ named constants. */ 395294229Sian#define SER(sig) SER_##sig 396294229Sian#define SERD(sig) SER_D##sig 397294229Sian#define MSR(sig) MSR_##sig 398294229Sian#define MSRD(sig) MSR_D##sig 399294229Sian 400294229Sian/* 401294229Sian * Detect signal changes using software delta detection. The previous state of 402294229Sian * the signals is in 'var' the new hardware state is in 'msr', and 'sig' is the 403294229Sian * short name (DCD, CTS, etc) of the signal bit being processed; 'var' gets the 404294229Sian * new state of both the signal and the delta bits. 405294229Sian */ 406294229Sian#define SIGCHGSW(var, msr, sig) \ 407294229Sian if ((msr) & MSR(sig)) { \ 408294229Sian if ((var & SER(sig)) == 0) \ 409294229Sian var |= SERD(sig) | SER(sig); \ 410294229Sian } else { \ 411294229Sian if ((var & SER(sig)) != 0) \ 412294229Sian var = SERD(sig) | (var & ~SER(sig)); \ 413119815Smarcel } 414119815Smarcel 415294229Sian/* 416294229Sian * Detect signal changes using the hardware msr delta bits. This is currently 417294229Sian * used only when PPS timing information is being captured using the "narrow 418294229Sian * pulse" option. With a narrow PPS pulse the signal may not still be asserted 419294229Sian * by time the interrupt handler is invoked. The hardware will latch the fact 420294229Sian * that it changed in the delta bits. 421294229Sian */ 422294229Sian#define SIGCHGHW(var, msr, sig) \ 423294229Sian if ((msr) & MSRD(sig)) { \ 424294229Sian if (((msr) & MSR(sig)) != 0) \ 425294229Sian var |= SERD(sig) | SER(sig); \ 426294229Sian else \ 427294229Sian var = SERD(sig) | (var & ~SER(sig)); \ 428294229Sian } 429294229Sian 430254597Sianint 431119815Smarcelns8250_bus_attach(struct uart_softc *sc) 432119815Smarcel{ 433119815Smarcel struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 434119815Smarcel struct uart_bas *bas; 435177117Ssam unsigned int ivar; 436247519Sganbold#ifdef FDT 437247519Sganbold phandle_t node; 438247519Sganbold pcell_t cell; 439247519Sganbold#endif 440119815Smarcel 441247519Sganbold ns8250->busy_detect = 0; 442247519Sganbold 443247519Sganbold#ifdef FDT 444247519Sganbold /* 445247519Sganbold * Check whether uart requires to read USR reg when IIR_BUSY and 446247519Sganbold * has broken txfifo. 447247519Sganbold */ 448247519Sganbold node = ofw_bus_get_node(sc->sc_dev); 449247519Sganbold if ((OF_getprop(node, "busy-detect", &cell, sizeof(cell))) > 0) 450247519Sganbold ns8250->busy_detect = 1; 451247519Sganbold if ((OF_getprop(node, "broken-txfifo", &cell, sizeof(cell))) > 0) 452247519Sganbold broken_txfifo = 1; 453247519Sganbold#endif 454247519Sganbold 455119815Smarcel bas = &sc->sc_bas; 456119815Smarcel 457119815Smarcel ns8250->mcr = uart_getreg(bas, REG_MCR); 458177117Ssam ns8250->fcr = FCR_ENABLE; 459177117Ssam if (!resource_int_value("uart", device_get_unit(sc->sc_dev), "flags", 460177117Ssam &ivar)) { 461177117Ssam if (UART_FLAGS_FCR_RX_LOW(ivar)) 462177117Ssam ns8250->fcr |= FCR_RX_LOW; 463177117Ssam else if (UART_FLAGS_FCR_RX_MEDL(ivar)) 464177117Ssam ns8250->fcr |= FCR_RX_MEDL; 465177117Ssam else if (UART_FLAGS_FCR_RX_HIGH(ivar)) 466177117Ssam ns8250->fcr |= FCR_RX_HIGH; 467177117Ssam else 468177117Ssam ns8250->fcr |= FCR_RX_MEDH; 469177117Ssam } else 470177117Ssam ns8250->fcr |= FCR_RX_MEDH; 471179420Sbenno 472179420Sbenno /* Get IER mask */ 473179420Sbenno ivar = 0xf0; 474179420Sbenno resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_mask", 475179420Sbenno &ivar); 476179420Sbenno ns8250->ier_mask = (uint8_t)(ivar & 0xff); 477179420Sbenno 478179420Sbenno /* Get IER RX interrupt bits */ 479179420Sbenno ivar = IER_EMSC | IER_ERLS | IER_ERXRDY; 480179420Sbenno resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_rxbits", 481179420Sbenno &ivar); 482179420Sbenno ns8250->ier_rxbits = (uint8_t)(ivar & 0xff); 483179420Sbenno 484119815Smarcel uart_setreg(bas, REG_FCR, ns8250->fcr); 485119815Smarcel uart_barrier(bas); 486119815Smarcel ns8250_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); 487119815Smarcel 488119815Smarcel if (ns8250->mcr & MCR_DTR) 489131043Sphk sc->sc_hwsig |= SER_DTR; 490119815Smarcel if (ns8250->mcr & MCR_RTS) 491131043Sphk sc->sc_hwsig |= SER_RTS; 492119815Smarcel ns8250_bus_getsig(sc); 493119815Smarcel 494119815Smarcel ns8250_clrint(bas); 495179420Sbenno ns8250->ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; 496179420Sbenno ns8250->ier |= ns8250->ier_rxbits; 497119815Smarcel uart_setreg(bas, REG_IER, ns8250->ier); 498119815Smarcel uart_barrier(bas); 499255031Smarcel 500255031Smarcel /* 501255031Smarcel * Timing of the H/W access was changed with r253161 of uart_core.c 502255031Smarcel * It has been observed that an ITE IT8513E would signal a break 503255031Smarcel * condition with pretty much every character it received, unless 504255031Smarcel * it had enough time to settle between ns8250_bus_attach() and 505255031Smarcel * ns8250_bus_ipend() -- which it accidentally had before r253161. 506255031Smarcel * It's not understood why the UART chip behaves this way and it 507255031Smarcel * could very well be that the DELAY make the H/W work in the same 508255031Smarcel * accidental manner as before. More analysis is warranted, but 509255031Smarcel * at least now we fixed a known regression. 510255031Smarcel */ 511255074Smarcel DELAY(200); 512119815Smarcel return (0); 513119815Smarcel} 514119815Smarcel 515254597Sianint 516119815Smarcelns8250_bus_detach(struct uart_softc *sc) 517119815Smarcel{ 518179420Sbenno struct ns8250_softc *ns8250; 519119815Smarcel struct uart_bas *bas; 520158844Sbenno u_char ier; 521119815Smarcel 522179420Sbenno ns8250 = (struct ns8250_softc *)sc; 523119815Smarcel bas = &sc->sc_bas; 524179420Sbenno ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; 525158844Sbenno uart_setreg(bas, REG_IER, ier); 526119815Smarcel uart_barrier(bas); 527119815Smarcel ns8250_clrint(bas); 528119815Smarcel return (0); 529119815Smarcel} 530119815Smarcel 531254597Sianint 532119815Smarcelns8250_bus_flush(struct uart_softc *sc, int what) 533119815Smarcel{ 534119815Smarcel struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 535119815Smarcel struct uart_bas *bas; 536120143Smarcel int error; 537119815Smarcel 538119815Smarcel bas = &sc->sc_bas; 539157300Smarcel uart_lock(sc->sc_hwmtx); 540157418Smarcel if (sc->sc_rxfifosz > 1) { 541119815Smarcel ns8250_flush(bas, what); 542119815Smarcel uart_setreg(bas, REG_FCR, ns8250->fcr); 543119815Smarcel uart_barrier(bas); 544120143Smarcel error = 0; 545120143Smarcel } else 546120143Smarcel error = ns8250_drain(bas, what); 547157300Smarcel uart_unlock(sc->sc_hwmtx); 548120143Smarcel return (error); 549119815Smarcel} 550119815Smarcel 551254597Sianint 552119815Smarcelns8250_bus_getsig(struct uart_softc *sc) 553119815Smarcel{ 554294229Sian uint32_t old, sig; 555119815Smarcel uint8_t msr; 556119815Smarcel 557294229Sian /* 558294229Sian * The delta bits are reputed to be broken on some hardware, so use 559294229Sian * software delta detection by default. Use the hardware delta bits 560294229Sian * when capturing PPS pulses which are too narrow for software detection 561294229Sian * to see the edges. Hardware delta for RI doesn't work like the 562294229Sian * others, so always use software for it. Other threads may be changing 563294229Sian * other (non-MSR) bits in sc_hwsig, so loop until it can succesfully 564294229Sian * update without other changes happening. Note that the SIGCHGxx() 565294229Sian * macros carefully preserve the delta bits when we have to loop several 566294229Sian * times and a signal transitions between iterations. 567294229Sian */ 568119815Smarcel do { 569119815Smarcel old = sc->sc_hwsig; 570119815Smarcel sig = old; 571157300Smarcel uart_lock(sc->sc_hwmtx); 572119815Smarcel msr = uart_getreg(&sc->sc_bas, REG_MSR); 573157300Smarcel uart_unlock(sc->sc_hwmtx); 574294229Sian if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) { 575294229Sian SIGCHGHW(sig, msr, DSR); 576294229Sian SIGCHGHW(sig, msr, CTS); 577294229Sian SIGCHGHW(sig, msr, DCD); 578294229Sian } else { 579294229Sian SIGCHGSW(sig, msr, DSR); 580294229Sian SIGCHGSW(sig, msr, CTS); 581294229Sian SIGCHGSW(sig, msr, DCD); 582294229Sian } 583294229Sian SIGCHGSW(sig, msr, RI); 584294229Sian } while (!atomic_cmpset_32(&sc->sc_hwsig, old, sig & ~SER_MASK_DELTA)); 585119815Smarcel return (sig); 586119815Smarcel} 587119815Smarcel 588254597Sianint 589119815Smarcelns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 590119815Smarcel{ 591119815Smarcel struct uart_bas *bas; 592137709Smarcel int baudrate, divisor, error; 593120022Smarcel uint8_t efr, lcr; 594119815Smarcel 595119815Smarcel bas = &sc->sc_bas; 596120143Smarcel error = 0; 597157300Smarcel uart_lock(sc->sc_hwmtx); 598119815Smarcel switch (request) { 599119815Smarcel case UART_IOCTL_BREAK: 600119815Smarcel lcr = uart_getreg(bas, REG_LCR); 601119815Smarcel if (data) 602119815Smarcel lcr |= LCR_SBREAK; 603119815Smarcel else 604119815Smarcel lcr &= ~LCR_SBREAK; 605119815Smarcel uart_setreg(bas, REG_LCR, lcr); 606119815Smarcel uart_barrier(bas); 607119815Smarcel break; 608120022Smarcel case UART_IOCTL_IFLOW: 609120022Smarcel lcr = uart_getreg(bas, REG_LCR); 610120022Smarcel uart_barrier(bas); 611120022Smarcel uart_setreg(bas, REG_LCR, 0xbf); 612120022Smarcel uart_barrier(bas); 613120022Smarcel efr = uart_getreg(bas, REG_EFR); 614120022Smarcel if (data) 615120022Smarcel efr |= EFR_RTS; 616120022Smarcel else 617120022Smarcel efr &= ~EFR_RTS; 618120022Smarcel uart_setreg(bas, REG_EFR, efr); 619120022Smarcel uart_barrier(bas); 620120022Smarcel uart_setreg(bas, REG_LCR, lcr); 621120022Smarcel uart_barrier(bas); 622120022Smarcel break; 623120022Smarcel case UART_IOCTL_OFLOW: 624120022Smarcel lcr = uart_getreg(bas, REG_LCR); 625120022Smarcel uart_barrier(bas); 626120022Smarcel uart_setreg(bas, REG_LCR, 0xbf); 627120022Smarcel uart_barrier(bas); 628120022Smarcel efr = uart_getreg(bas, REG_EFR); 629120022Smarcel if (data) 630120022Smarcel efr |= EFR_CTS; 631120022Smarcel else 632120022Smarcel efr &= ~EFR_CTS; 633120022Smarcel uart_setreg(bas, REG_EFR, efr); 634120022Smarcel uart_barrier(bas); 635120022Smarcel uart_setreg(bas, REG_LCR, lcr); 636120022Smarcel uart_barrier(bas); 637120022Smarcel break; 638137707Smarcel case UART_IOCTL_BAUD: 639137707Smarcel lcr = uart_getreg(bas, REG_LCR); 640137707Smarcel uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 641137707Smarcel uart_barrier(bas); 642158844Sbenno divisor = uart_getreg(bas, REG_DLL) | 643158844Sbenno (uart_getreg(bas, REG_DLH) << 8); 644137707Smarcel uart_barrier(bas); 645137707Smarcel uart_setreg(bas, REG_LCR, lcr); 646137707Smarcel uart_barrier(bas); 647137709Smarcel baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; 648137709Smarcel if (baudrate > 0) 649137709Smarcel *(int*)data = baudrate; 650137709Smarcel else 651137709Smarcel error = ENXIO; 652137707Smarcel break; 653119815Smarcel default: 654120143Smarcel error = EINVAL; 655120143Smarcel break; 656119815Smarcel } 657157300Smarcel uart_unlock(sc->sc_hwmtx); 658120143Smarcel return (error); 659119815Smarcel} 660119815Smarcel 661254597Sianint 662119815Smarcelns8250_bus_ipend(struct uart_softc *sc) 663119815Smarcel{ 664119815Smarcel struct uart_bas *bas; 665227032Scognet struct ns8250_softc *ns8250; 666119815Smarcel int ipend; 667119815Smarcel uint8_t iir, lsr; 668119815Smarcel 669227032Scognet ns8250 = (struct ns8250_softc *)sc; 670119815Smarcel bas = &sc->sc_bas; 671157300Smarcel uart_lock(sc->sc_hwmtx); 672119815Smarcel iir = uart_getreg(bas, REG_IIR); 673247519Sganbold 674247519Sganbold if (ns8250->busy_detect && (iir & IIR_BUSY) == IIR_BUSY) { 675247519Sganbold (void)uart_getreg(bas, DW_REG_USR); 676247519Sganbold uart_unlock(sc->sc_hwmtx); 677247519Sganbold return (0); 678247519Sganbold } 679120143Smarcel if (iir & IIR_NOPEND) { 680157300Smarcel uart_unlock(sc->sc_hwmtx); 681119815Smarcel return (0); 682120143Smarcel } 683119815Smarcel ipend = 0; 684119815Smarcel if (iir & IIR_RXRDY) { 685119815Smarcel lsr = uart_getreg(bas, REG_LSR); 686119815Smarcel if (lsr & LSR_OE) 687155971Smarcel ipend |= SER_INT_OVERRUN; 688119815Smarcel if (lsr & LSR_BI) 689155971Smarcel ipend |= SER_INT_BREAK; 690119815Smarcel if (lsr & LSR_RXRDY) 691155971Smarcel ipend |= SER_INT_RXREADY; 692119815Smarcel } else { 693227032Scognet if (iir & IIR_TXRDY) { 694155971Smarcel ipend |= SER_INT_TXIDLE; 695227032Scognet uart_setreg(bas, REG_IER, ns8250->ier); 696227032Scognet } else 697155971Smarcel ipend |= SER_INT_SIGCHG; 698119815Smarcel } 699190834Smarcel if (ipend == 0) 700190834Smarcel ns8250_clrint(bas); 701190834Smarcel uart_unlock(sc->sc_hwmtx); 702207533Smarius return (ipend); 703119815Smarcel} 704119815Smarcel 705254597Sianint 706119815Smarcelns8250_bus_param(struct uart_softc *sc, int baudrate, int databits, 707119815Smarcel int stopbits, int parity) 708119815Smarcel{ 709266046Sian struct ns8250_softc *ns8250; 710119815Smarcel struct uart_bas *bas; 711266046Sian int error, limit; 712119815Smarcel 713266046Sian ns8250 = (struct ns8250_softc*)sc; 714119815Smarcel bas = &sc->sc_bas; 715157300Smarcel uart_lock(sc->sc_hwmtx); 716266046Sian /* 717266046Sian * When using DW UART with BUSY detection it is necessary to wait 718266046Sian * until all serial transfers are finished before manipulating the 719266046Sian * line control. LCR will not be affected when UART is busy. 720266046Sian */ 721266046Sian if (ns8250->busy_detect != 0) { 722266046Sian /* 723266046Sian * Pick an arbitrary high limit to avoid getting stuck in 724266046Sian * an infinite loop in case when the hardware is broken. 725266046Sian */ 726266046Sian limit = 10 * 1024; 727266046Sian while (((uart_getreg(bas, DW_REG_USR) & USR_BUSY) != 0) && 728266046Sian --limit) 729266046Sian DELAY(4); 730266046Sian 731266046Sian if (limit <= 0) { 732266046Sian /* UART appears to be stuck */ 733266046Sian uart_unlock(sc->sc_hwmtx); 734266046Sian return (EIO); 735266046Sian } 736266046Sian } 737266046Sian 738120143Smarcel error = ns8250_param(bas, baudrate, databits, stopbits, parity); 739157300Smarcel uart_unlock(sc->sc_hwmtx); 740120143Smarcel return (error); 741119815Smarcel} 742119815Smarcel 743254597Sianint 744119815Smarcelns8250_bus_probe(struct uart_softc *sc) 745119815Smarcel{ 746179420Sbenno struct ns8250_softc *ns8250; 747119815Smarcel struct uart_bas *bas; 748119815Smarcel int count, delay, error, limit; 749158844Sbenno uint8_t lsr, mcr, ier; 750119815Smarcel 751179420Sbenno ns8250 = (struct ns8250_softc *)sc; 752119815Smarcel bas = &sc->sc_bas; 753119815Smarcel 754119815Smarcel error = ns8250_probe(bas); 755119815Smarcel if (error) 756119815Smarcel return (error); 757119815Smarcel 758119815Smarcel mcr = MCR_IE; 759119815Smarcel if (sc->sc_sysdev == NULL) { 760119815Smarcel /* By using ns8250_init() we also set DTR and RTS. */ 761158069Smarcel ns8250_init(bas, 115200, 8, 1, UART_PARITY_NONE); 762119815Smarcel } else 763119815Smarcel mcr |= MCR_DTR | MCR_RTS; 764119815Smarcel 765119815Smarcel error = ns8250_drain(bas, UART_DRAIN_TRANSMITTER); 766119815Smarcel if (error) 767119815Smarcel return (error); 768119815Smarcel 769119815Smarcel /* 770119815Smarcel * Set loopback mode. This avoids having garbage on the wire and 771119815Smarcel * also allows us send and receive data. We set DTR and RTS to 772119815Smarcel * avoid the possibility that automatic flow-control prevents 773129757Stmm * any data from being sent. 774119815Smarcel */ 775129757Stmm uart_setreg(bas, REG_MCR, MCR_LOOPBACK | MCR_IE | MCR_DTR | MCR_RTS); 776119815Smarcel uart_barrier(bas); 777119815Smarcel 778119815Smarcel /* 779119815Smarcel * Enable FIFOs. And check that the UART has them. If not, we're 780129757Stmm * done. Since this is the first time we enable the FIFOs, we reset 781129757Stmm * them. 782119815Smarcel */ 783119815Smarcel uart_setreg(bas, REG_FCR, FCR_ENABLE); 784119815Smarcel uart_barrier(bas); 785157418Smarcel if (!(uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) { 786119815Smarcel /* 787119815Smarcel * NS16450 or INS8250. We don't bother to differentiate 788119815Smarcel * between them. They're too old to be interesting. 789119815Smarcel */ 790119815Smarcel uart_setreg(bas, REG_MCR, mcr); 791119815Smarcel uart_barrier(bas); 792157418Smarcel sc->sc_rxfifosz = sc->sc_txfifosz = 1; 793119815Smarcel device_set_desc(sc->sc_dev, "8250 or 16450 or compatible"); 794119815Smarcel return (0); 795119815Smarcel } 796119815Smarcel 797129757Stmm uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); 798119815Smarcel uart_barrier(bas); 799119815Smarcel 800119815Smarcel count = 0; 801119815Smarcel delay = ns8250_delay(bas); 802119815Smarcel 803119815Smarcel /* We have FIFOs. Drain the transmitter and receiver. */ 804119815Smarcel error = ns8250_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER); 805119815Smarcel if (error) { 806119815Smarcel uart_setreg(bas, REG_MCR, mcr); 807119815Smarcel uart_setreg(bas, REG_FCR, 0); 808119815Smarcel uart_barrier(bas); 809119815Smarcel goto describe; 810119815Smarcel } 811119815Smarcel 812119815Smarcel /* 813119815Smarcel * We should have a sufficiently clean "pipe" to determine the 814119815Smarcel * size of the FIFOs. We send as much characters as is reasonable 815218909Sbrucec * and wait for the overflow bit in the LSR register to be 816129757Stmm * asserted, counting the characters as we send them. Based on 817129757Stmm * that count we know the FIFO size. 818119815Smarcel */ 819129757Stmm do { 820119815Smarcel uart_setreg(bas, REG_DATA, 0); 821119815Smarcel uart_barrier(bas); 822119815Smarcel count++; 823119815Smarcel 824119815Smarcel limit = 30; 825129757Stmm lsr = 0; 826129757Stmm /* 827129757Stmm * LSR bits are cleared upon read, so we must accumulate 828129757Stmm * them to be able to test LSR_OE below. 829129757Stmm */ 830129757Stmm while (((lsr |= uart_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 && 831129757Stmm --limit) 832119815Smarcel DELAY(delay); 833119815Smarcel if (limit == 0) { 834179420Sbenno ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; 835158844Sbenno uart_setreg(bas, REG_IER, ier); 836119815Smarcel uart_setreg(bas, REG_MCR, mcr); 837119815Smarcel uart_setreg(bas, REG_FCR, 0); 838119815Smarcel uart_barrier(bas); 839119815Smarcel count = 0; 840119815Smarcel goto describe; 841119815Smarcel } 842132650Smarcel } while ((lsr & LSR_OE) == 0 && count < 130); 843129757Stmm count--; 844119815Smarcel 845119815Smarcel uart_setreg(bas, REG_MCR, mcr); 846119815Smarcel 847119815Smarcel /* Reset FIFOs. */ 848119815Smarcel ns8250_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); 849119815Smarcel 850119815Smarcel describe: 851129757Stmm if (count >= 14 && count <= 16) { 852119815Smarcel sc->sc_rxfifosz = 16; 853119815Smarcel device_set_desc(sc->sc_dev, "16550 or compatible"); 854129757Stmm } else if (count >= 28 && count <= 32) { 855119815Smarcel sc->sc_rxfifosz = 32; 856119815Smarcel device_set_desc(sc->sc_dev, "16650 or compatible"); 857129757Stmm } else if (count >= 56 && count <= 64) { 858119815Smarcel sc->sc_rxfifosz = 64; 859119815Smarcel device_set_desc(sc->sc_dev, "16750 or compatible"); 860129757Stmm } else if (count >= 112 && count <= 128) { 861119815Smarcel sc->sc_rxfifosz = 128; 862119815Smarcel device_set_desc(sc->sc_dev, "16950 or compatible"); 863119815Smarcel } else { 864119943Smarcel sc->sc_rxfifosz = 16; 865119815Smarcel device_set_desc(sc->sc_dev, 866119815Smarcel "Non-standard ns8250 class UART with FIFOs"); 867119815Smarcel } 868119815Smarcel 869119815Smarcel /* 870119815Smarcel * Force the Tx FIFO size to 16 bytes for now. We don't program the 871119815Smarcel * Tx trigger. Also, we assume that all data has been sent when the 872119815Smarcel * interrupt happens. 873119815Smarcel */ 874119815Smarcel sc->sc_txfifosz = 16; 875119815Smarcel 876133220Smarcel#if 0 877133220Smarcel /* 878133220Smarcel * XXX there are some issues related to hardware flow control and 879133220Smarcel * it's likely that uart(4) is the cause. This basicly needs more 880133220Smarcel * investigation, but we avoid using for hardware flow control 881133220Smarcel * until then. 882133220Smarcel */ 883120022Smarcel /* 16650s or higher have automatic flow control. */ 884120022Smarcel if (sc->sc_rxfifosz > 16) { 885120022Smarcel sc->sc_hwiflow = 1; 886120022Smarcel sc->sc_hwoflow = 1; 887120022Smarcel } 888133220Smarcel#endif 889120022Smarcel 890119815Smarcel return (0); 891119815Smarcel} 892119815Smarcel 893254597Sianint 894119815Smarcelns8250_bus_receive(struct uart_softc *sc) 895119815Smarcel{ 896119815Smarcel struct uart_bas *bas; 897119815Smarcel int xc; 898119815Smarcel uint8_t lsr; 899119815Smarcel 900119815Smarcel bas = &sc->sc_bas; 901157300Smarcel uart_lock(sc->sc_hwmtx); 902120146Smarcel lsr = uart_getreg(bas, REG_LSR); 903120146Smarcel while (lsr & LSR_RXRDY) { 904120146Smarcel if (uart_rx_full(sc)) { 905120146Smarcel sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 906119815Smarcel break; 907120146Smarcel } 908119815Smarcel xc = uart_getreg(bas, REG_DATA); 909119815Smarcel if (lsr & LSR_FE) 910119815Smarcel xc |= UART_STAT_FRAMERR; 911119815Smarcel if (lsr & LSR_PE) 912119815Smarcel xc |= UART_STAT_PARERR; 913119815Smarcel uart_rx_put(sc, xc); 914120146Smarcel lsr = uart_getreg(bas, REG_LSR); 915119815Smarcel } 916120146Smarcel /* Discard everything left in the Rx FIFO. */ 917120146Smarcel while (lsr & LSR_RXRDY) { 918120146Smarcel (void)uart_getreg(bas, REG_DATA); 919120146Smarcel uart_barrier(bas); 920120146Smarcel lsr = uart_getreg(bas, REG_LSR); 921120146Smarcel } 922157300Smarcel uart_unlock(sc->sc_hwmtx); 923119815Smarcel return (0); 924119815Smarcel} 925119815Smarcel 926254597Sianint 927119815Smarcelns8250_bus_setsig(struct uart_softc *sc, int sig) 928119815Smarcel{ 929119815Smarcel struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 930119815Smarcel struct uart_bas *bas; 931119815Smarcel uint32_t new, old; 932119815Smarcel 933119815Smarcel bas = &sc->sc_bas; 934119815Smarcel do { 935119815Smarcel old = sc->sc_hwsig; 936119815Smarcel new = old; 937131043Sphk if (sig & SER_DDTR) { 938294229Sian new = (new & ~SER_DTR) | (sig & (SER_DTR | SER_DDTR)); 939119815Smarcel } 940131043Sphk if (sig & SER_DRTS) { 941294229Sian new = (new & ~SER_RTS) | (sig & (SER_RTS | SER_DRTS)); 942119815Smarcel } 943119815Smarcel } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 944157300Smarcel uart_lock(sc->sc_hwmtx); 945119815Smarcel ns8250->mcr &= ~(MCR_DTR|MCR_RTS); 946131043Sphk if (new & SER_DTR) 947119815Smarcel ns8250->mcr |= MCR_DTR; 948131043Sphk if (new & SER_RTS) 949119815Smarcel ns8250->mcr |= MCR_RTS; 950119815Smarcel uart_setreg(bas, REG_MCR, ns8250->mcr); 951119815Smarcel uart_barrier(bas); 952157300Smarcel uart_unlock(sc->sc_hwmtx); 953119815Smarcel return (0); 954119815Smarcel} 955119815Smarcel 956254597Sianint 957119815Smarcelns8250_bus_transmit(struct uart_softc *sc) 958119815Smarcel{ 959119815Smarcel struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 960119815Smarcel struct uart_bas *bas; 961119815Smarcel int i; 962119815Smarcel 963119815Smarcel bas = &sc->sc_bas; 964157300Smarcel uart_lock(sc->sc_hwmtx); 965119815Smarcel while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) 966119815Smarcel ; 967119815Smarcel uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); 968119815Smarcel uart_barrier(bas); 969119815Smarcel for (i = 0; i < sc->sc_txdatasz; i++) { 970119815Smarcel uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); 971119815Smarcel uart_barrier(bas); 972119815Smarcel } 973246016Scperciva if (broken_txfifo) 974246016Scperciva ns8250_drain(bas, UART_DRAIN_TRANSMITTER); 975246016Scperciva else 976246016Scperciva sc->sc_txbusy = 1; 977157300Smarcel uart_unlock(sc->sc_hwmtx); 978246016Scperciva if (broken_txfifo) 979246016Scperciva uart_sched_softih(sc, SER_INT_TXIDLE); 980119815Smarcel return (0); 981119815Smarcel} 982262649Simp 983262649Simpvoid 984262649Simpns8250_bus_grab(struct uart_softc *sc) 985262649Simp{ 986262649Simp struct uart_bas *bas = &sc->sc_bas; 987262649Simp 988262649Simp /* 989262649Simp * turn off all interrupts to enter polling mode. Leave the 990262649Simp * saved mask alone. We'll restore whatever it was in ungrab. 991262649Simp * All pending interupt signals are reset when IER is set to 0. 992262649Simp */ 993262649Simp uart_lock(sc->sc_hwmtx); 994262649Simp uart_setreg(bas, REG_IER, 0); 995262649Simp uart_barrier(bas); 996262649Simp uart_unlock(sc->sc_hwmtx); 997262649Simp} 998262649Simp 999262649Simpvoid 1000262649Simpns8250_bus_ungrab(struct uart_softc *sc) 1001262649Simp{ 1002262649Simp struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 1003262649Simp struct uart_bas *bas = &sc->sc_bas; 1004262649Simp 1005262649Simp /* 1006262649Simp * Restore previous interrupt mask 1007262649Simp */ 1008262649Simp uart_lock(sc->sc_hwmtx); 1009262649Simp uart_setreg(bas, REG_IER, ns8250->ier); 1010262649Simp uart_barrier(bas); 1011262649Simp uart_unlock(sc->sc_hwmtx); 1012262649Simp} 1013