1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * 6 * This software was developed by Oleksandr Rybalko under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 #include "opt_ddb.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/bus.h> 37 #include <sys/conf.h> 38 #include <sys/kdb.h> 39 #include <machine/bus.h> 40 41 #include <dev/uart/uart.h> 42 #include <dev/uart/uart_cpu.h> 43 #include <dev/uart/uart_cpu_fdt.h> 44 #include <dev/uart/uart_bus.h> 45 #include <dev/uart/uart_dev_imx.h> 46 47 #if defined(__aarch64__) 48 #define IMX_ENABLE_CLOCKS 49 #endif 50 51 #ifdef IMX_ENABLE_CLOCKS 52 #include <dev/extres/clk/clk.h> 53 #endif 54 55 #include "uart_if.h" 56 57 #include <arm/freescale/imx/imx_ccmvar.h> 58 59 /* 60 * The hardare FIFOs are 32 bytes. We want an interrupt when there are 24 bytes 61 * available to read or space for 24 more bytes to write. While 8 bytes of 62 * slack before over/underrun might seem excessive, the hardware can run at 63 * 5mbps, which means 2uS per char, so at full speed 8 bytes provides only 16uS 64 * to get into the interrupt handler and service the fifo. 65 */ 66 #define IMX_FIFOSZ 32 67 #define IMX_RXFIFO_LEVEL 24 68 #define IMX_TXFIFO_LEVEL 24 69 70 /* 71 * Low-level UART interface. 72 */ 73 static int imx_uart_probe(struct uart_bas *bas); 74 static void imx_uart_init(struct uart_bas *bas, int, int, int, int); 75 static void imx_uart_term(struct uart_bas *bas); 76 static void imx_uart_putc(struct uart_bas *bas, int); 77 static int imx_uart_rxready(struct uart_bas *bas); 78 static int imx_uart_getc(struct uart_bas *bas, struct mtx *); 79 80 static struct uart_ops uart_imx_uart_ops = { 81 .probe = imx_uart_probe, 82 .init = imx_uart_init, 83 .term = imx_uart_term, 84 .putc = imx_uart_putc, 85 .rxready = imx_uart_rxready, 86 .getc = imx_uart_getc, 87 }; 88 89 #if 0 /* Handy when debugging. */ 90 static void 91 dumpregs(struct uart_bas *bas, const char * msg) 92 { 93 94 if (!bootverbose) 95 return; 96 printf("%s bsh 0x%08lx UCR1 0x%08x UCR2 0x%08x " 97 "UCR3 0x%08x UCR4 0x%08x USR1 0x%08x USR2 0x%08x\n", 98 msg, bas->bsh, 99 GETREG(bas, REG(UCR1)), GETREG(bas, REG(UCR2)), 100 GETREG(bas, REG(UCR3)), GETREG(bas, REG(UCR4)), 101 GETREG(bas, REG(USR1)), GETREG(bas, REG(USR2))); 102 } 103 #endif 104 105 static int 106 imx_uart_probe(struct uart_bas *bas) 107 { 108 109 return (0); 110 } 111 112 static u_int 113 imx_uart_getbaud(struct uart_bas *bas) 114 { 115 uint32_t rate, ubir, ubmr; 116 u_int baud, blo, bhi, i; 117 static const u_int predivs[] = {6, 5, 4, 3, 2, 1, 7, 1}; 118 static const u_int std_rates[] = { 119 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 120 }; 121 122 /* 123 * Get the baud rate the hardware is programmed for, then search the 124 * table of standard baud rates for a number that's within 3% of the 125 * actual rate the hardware is programmed for. It's more comforting to 126 * see that your console is running at 115200 than 114942. Note that 127 * here we cannot make a simplifying assumption that the predivider and 128 * numerator are 1 (like we do when setting the baud rate), because we 129 * don't know what u-boot might have set up. 130 */ 131 i = (GETREG(bas, REG(UFCR)) & IMXUART_UFCR_RFDIV_MASK) >> 132 IMXUART_UFCR_RFDIV_SHIFT; 133 rate = bas->rclk / predivs[i]; 134 ubir = GETREG(bas, REG(UBIR)) + 1; 135 ubmr = GETREG(bas, REG(UBMR)) + 1; 136 baud = ((rate / 16 ) * ubir) / ubmr; 137 138 blo = (baud * 100) / 103; 139 bhi = (baud * 100) / 97; 140 for (i = 0; i < nitems(std_rates); i++) { 141 rate = std_rates[i]; 142 if (rate >= blo && rate <= bhi) { 143 baud = rate; 144 break; 145 } 146 } 147 148 return (baud); 149 } 150 151 static void 152 imx_uart_init(struct uart_bas *bas, int baudrate, int databits, 153 int stopbits, int parity) 154 { 155 uint32_t baseclk, reg; 156 157 /* Enable the device and the RX/TX channels. */ 158 SET(bas, REG(UCR1), FLD(UCR1, UARTEN)); 159 SET(bas, REG(UCR2), FLD(UCR2, RXEN) | FLD(UCR2, TXEN)); 160 161 if (databits == 7) 162 DIS(bas, UCR2, WS); 163 else 164 ENA(bas, UCR2, WS); 165 166 if (stopbits == 2) 167 ENA(bas, UCR2, STPB); 168 else 169 DIS(bas, UCR2, STPB); 170 171 switch (parity) { 172 case UART_PARITY_ODD: 173 DIS(bas, UCR2, PROE); 174 ENA(bas, UCR2, PREN); 175 break; 176 case UART_PARITY_EVEN: 177 ENA(bas, UCR2, PROE); 178 ENA(bas, UCR2, PREN); 179 break; 180 case UART_PARITY_MARK: 181 case UART_PARITY_SPACE: 182 /* FALLTHROUGH: Hardware doesn't support mark/space. */ 183 case UART_PARITY_NONE: 184 default: 185 DIS(bas, UCR2, PREN); 186 break; 187 } 188 189 /* 190 * The hardware has an extremely flexible baud clock: it allows setting 191 * both the numerator and denominator of the divider, as well as a 192 * separate pre-divider. We simplify the problem of coming up with a 193 * workable pair of numbers by assuming a pre-divider and numerator of 194 * one because our base clock is so fast we can reach virtually any 195 * reasonable speed with a simple divisor. The numerator value actually 196 * includes the 16x over-sampling (so a value of 16 means divide by 1); 197 * the register value is the numerator-1, so we have a hard-coded 15. 198 * Note that a quirk of the hardware requires that both UBIR and UBMR be 199 * set back to back in order for the change to take effect. 200 */ 201 if ((baudrate > 0) && (bas->rclk != 0)) { 202 baseclk = bas->rclk; 203 reg = GETREG(bas, REG(UFCR)); 204 reg = (reg & ~IMXUART_UFCR_RFDIV_MASK) | IMXUART_UFCR_RFDIV_DIV1; 205 SETREG(bas, REG(UFCR), reg); 206 SETREG(bas, REG(UBIR), 15); 207 SETREG(bas, REG(UBMR), (baseclk / baudrate) - 1); 208 } 209 210 /* 211 * Program the tx lowater and rx hiwater levels at which fifo-service 212 * interrupts are signaled. The tx value is interpetted as "when there 213 * are only this many bytes remaining" (not "this many free"). 214 */ 215 reg = GETREG(bas, REG(UFCR)); 216 reg &= ~(IMXUART_UFCR_TXTL_MASK | IMXUART_UFCR_RXTL_MASK); 217 reg |= (IMX_FIFOSZ - IMX_TXFIFO_LEVEL) << IMXUART_UFCR_TXTL_SHIFT; 218 reg |= IMX_RXFIFO_LEVEL << IMXUART_UFCR_RXTL_SHIFT; 219 SETREG(bas, REG(UFCR), reg); 220 } 221 222 static void 223 imx_uart_term(struct uart_bas *bas) 224 { 225 226 } 227 228 static void 229 imx_uart_putc(struct uart_bas *bas, int c) 230 { 231 232 while (!(IS(bas, USR1, TRDY))) 233 ; 234 SETREG(bas, REG(UTXD), c); 235 } 236 237 static int 238 imx_uart_rxready(struct uart_bas *bas) 239 { 240 241 return ((IS(bas, USR2, RDR)) ? 1 : 0); 242 } 243 244 static int 245 imx_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) 246 { 247 int c; 248 249 uart_lock(hwmtx); 250 while (!(IS(bas, USR2, RDR))) 251 ; 252 253 c = GETREG(bas, REG(URXD)); 254 uart_unlock(hwmtx); 255 #if defined(KDB) 256 if (c & FLD(URXD, BRK)) { 257 if (kdb_break()) 258 return (0); 259 } 260 #endif 261 return (c & 0xff); 262 } 263 264 /* 265 * High-level UART interface. 266 */ 267 struct imx_uart_softc { 268 struct uart_softc base; 269 }; 270 271 static int imx_uart_bus_attach(struct uart_softc *); 272 static int imx_uart_bus_detach(struct uart_softc *); 273 static int imx_uart_bus_flush(struct uart_softc *, int); 274 static int imx_uart_bus_getsig(struct uart_softc *); 275 static int imx_uart_bus_ioctl(struct uart_softc *, int, intptr_t); 276 static int imx_uart_bus_ipend(struct uart_softc *); 277 static int imx_uart_bus_param(struct uart_softc *, int, int, int, int); 278 static int imx_uart_bus_probe(struct uart_softc *); 279 static int imx_uart_bus_receive(struct uart_softc *); 280 static int imx_uart_bus_setsig(struct uart_softc *, int); 281 static int imx_uart_bus_transmit(struct uart_softc *); 282 static void imx_uart_bus_grab(struct uart_softc *); 283 static void imx_uart_bus_ungrab(struct uart_softc *); 284 285 static kobj_method_t imx_uart_methods[] = { 286 KOBJMETHOD(uart_attach, imx_uart_bus_attach), 287 KOBJMETHOD(uart_detach, imx_uart_bus_detach), 288 KOBJMETHOD(uart_flush, imx_uart_bus_flush), 289 KOBJMETHOD(uart_getsig, imx_uart_bus_getsig), 290 KOBJMETHOD(uart_ioctl, imx_uart_bus_ioctl), 291 KOBJMETHOD(uart_ipend, imx_uart_bus_ipend), 292 KOBJMETHOD(uart_param, imx_uart_bus_param), 293 KOBJMETHOD(uart_probe, imx_uart_bus_probe), 294 KOBJMETHOD(uart_receive, imx_uart_bus_receive), 295 KOBJMETHOD(uart_setsig, imx_uart_bus_setsig), 296 KOBJMETHOD(uart_transmit, imx_uart_bus_transmit), 297 KOBJMETHOD(uart_grab, imx_uart_bus_grab), 298 KOBJMETHOD(uart_ungrab, imx_uart_bus_ungrab), 299 { 0, 0 } 300 }; 301 302 static struct uart_class uart_imx_class = { 303 "imx", 304 imx_uart_methods, 305 sizeof(struct imx_uart_softc), 306 .uc_ops = &uart_imx_uart_ops, 307 .uc_range = 0x100, 308 .uc_rclk = 24000000, /* TODO: get value from CCM */ 309 .uc_rshift = 0 310 }; 311 312 static struct ofw_compat_data compat_data[] = { 313 {"fsl,imx6q-uart", (uintptr_t)&uart_imx_class}, 314 {"fsl,imx53-uart", (uintptr_t)&uart_imx_class}, 315 {"fsl,imx51-uart", (uintptr_t)&uart_imx_class}, 316 {"fsl,imx31-uart", (uintptr_t)&uart_imx_class}, 317 {"fsl,imx27-uart", (uintptr_t)&uart_imx_class}, 318 {"fsl,imx25-uart", (uintptr_t)&uart_imx_class}, 319 {"fsl,imx21-uart", (uintptr_t)&uart_imx_class}, 320 {NULL, (uintptr_t)NULL}, 321 }; 322 UART_FDT_CLASS_AND_DEVICE(compat_data); 323 324 #define SIGCHG(c, i, s, d) \ 325 if (c) { \ 326 i |= (i & s) ? s : s | d; \ 327 } else { \ 328 i = (i & s) ? (i & ~s) | d : i; \ 329 } 330 331 #ifdef IMX_ENABLE_CLOCKS 332 static int 333 imx_uart_setup_clocks(struct uart_softc *sc) 334 { 335 struct uart_bas *bas; 336 clk_t ipgclk, perclk; 337 uint64_t freq; 338 int error; 339 340 bas = &sc->sc_bas; 341 342 if (clk_get_by_ofw_name(sc->sc_dev, 0, "ipg", &ipgclk) != 0) 343 return (ENOENT); 344 345 if (clk_get_by_ofw_name(sc->sc_dev, 0, "per", &perclk) != 0) { 346 return (ENOENT); 347 } 348 349 error = clk_enable(ipgclk); 350 if (error != 0) { 351 device_printf(sc->sc_dev, "cannot enable ipg clock\n"); 352 return (error); 353 } 354 355 error = clk_get_freq(perclk, &freq); 356 if (error != 0) { 357 device_printf(sc->sc_dev, "cannot get frequency\n"); 358 return (error); 359 } 360 361 bas->rclk = (uint32_t)freq; 362 363 return (0); 364 } 365 #endif 366 367 static int 368 imx_uart_bus_attach(struct uart_softc *sc) 369 { 370 struct uart_bas *bas; 371 struct uart_devinfo *di; 372 373 bas = &sc->sc_bas; 374 375 #ifdef IMX_ENABLE_CLOCKS 376 int error = imx_uart_setup_clocks(sc); 377 if (error) 378 return (error); 379 #else 380 bas->rclk = imx_ccm_uart_hz(); 381 #endif 382 383 if (sc->sc_sysdev != NULL) { 384 di = sc->sc_sysdev; 385 imx_uart_init(bas, di->baudrate, di->databits, di->stopbits, 386 di->parity); 387 } else { 388 imx_uart_init(bas, 115200, 8, 1, 0); 389 } 390 391 (void)imx_uart_bus_getsig(sc); 392 393 /* Clear all pending interrupts. */ 394 SETREG(bas, REG(USR1), 0xffff); 395 SETREG(bas, REG(USR2), 0xffff); 396 397 DIS(bas, UCR4, DREN); 398 ENA(bas, UCR1, RRDYEN); 399 DIS(bas, UCR1, IDEN); 400 DIS(bas, UCR3, RXDSEN); 401 ENA(bas, UCR2, ATEN); 402 DIS(bas, UCR1, TXMPTYEN); 403 DIS(bas, UCR1, TRDYEN); 404 DIS(bas, UCR4, TCEN); 405 DIS(bas, UCR4, OREN); 406 ENA(bas, UCR4, BKEN); 407 DIS(bas, UCR4, WKEN); 408 DIS(bas, UCR1, ADEN); 409 DIS(bas, UCR3, ACIEN); 410 DIS(bas, UCR2, ESCI); 411 DIS(bas, UCR4, ENIRI); 412 DIS(bas, UCR3, AIRINTEN); 413 DIS(bas, UCR3, AWAKEN); 414 DIS(bas, UCR3, FRAERREN); 415 DIS(bas, UCR3, PARERREN); 416 DIS(bas, UCR1, RTSDEN); 417 DIS(bas, UCR2, RTSEN); 418 DIS(bas, UCR3, DTREN); 419 DIS(bas, UCR3, RI); 420 DIS(bas, UCR3, DCD); 421 DIS(bas, UCR3, DTRDEN); 422 ENA(bas, UCR2, IRTS); 423 ENA(bas, UCR3, RXDMUXSEL); 424 425 return (0); 426 } 427 428 static int 429 imx_uart_bus_detach(struct uart_softc *sc) 430 { 431 432 SETREG(&sc->sc_bas, REG(UCR4), 0); 433 434 return (0); 435 } 436 437 static int 438 imx_uart_bus_flush(struct uart_softc *sc, int what) 439 { 440 441 /* TODO */ 442 return (0); 443 } 444 445 static int 446 imx_uart_bus_getsig(struct uart_softc *sc) 447 { 448 uint32_t new, old, sig; 449 uint8_t bes; 450 451 do { 452 old = sc->sc_hwsig; 453 sig = old; 454 uart_lock(sc->sc_hwmtx); 455 bes = GETREG(&sc->sc_bas, REG(USR2)); 456 uart_unlock(sc->sc_hwmtx); 457 /* XXX: chip can show delta */ 458 SIGCHG(bes & FLD(USR2, DCDIN), sig, SER_DCD, SER_DDCD); 459 new = sig & ~SER_MASK_DELTA; 460 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 461 462 return (sig); 463 } 464 465 static int 466 imx_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 467 { 468 struct uart_bas *bas; 469 int error; 470 471 bas = &sc->sc_bas; 472 error = 0; 473 uart_lock(sc->sc_hwmtx); 474 switch (request) { 475 case UART_IOCTL_BREAK: 476 /* TODO */ 477 break; 478 case UART_IOCTL_BAUD: 479 *(u_int*)data = imx_uart_getbaud(bas); 480 break; 481 default: 482 error = EINVAL; 483 break; 484 } 485 uart_unlock(sc->sc_hwmtx); 486 487 return (error); 488 } 489 490 static int 491 imx_uart_bus_ipend(struct uart_softc *sc) 492 { 493 struct uart_bas *bas; 494 int ipend; 495 uint32_t usr1, usr2; 496 uint32_t ucr1, ucr2, ucr4; 497 498 bas = &sc->sc_bas; 499 ipend = 0; 500 501 uart_lock(sc->sc_hwmtx); 502 503 /* Read pending interrupts */ 504 usr1 = GETREG(bas, REG(USR1)); 505 usr2 = GETREG(bas, REG(USR2)); 506 /* ACK interrupts */ 507 SETREG(bas, REG(USR1), usr1); 508 SETREG(bas, REG(USR2), usr2); 509 510 ucr1 = GETREG(bas, REG(UCR1)); 511 ucr2 = GETREG(bas, REG(UCR2)); 512 ucr4 = GETREG(bas, REG(UCR4)); 513 514 /* If we have reached tx low-water, we can tx some more now. */ 515 if ((usr1 & FLD(USR1, TRDY)) && (ucr1 & FLD(UCR1, TRDYEN))) { 516 DIS(bas, UCR1, TRDYEN); 517 ipend |= SER_INT_TXIDLE; 518 } 519 520 /* 521 * If we have reached the rx high-water, or if there are bytes in the rx 522 * fifo and no new data has arrived for 8 character periods (aging 523 * timer), we have input data to process. 524 */ 525 if (((usr1 & FLD(USR1, RRDY)) && (ucr1 & FLD(UCR1, RRDYEN))) || 526 ((usr1 & FLD(USR1, AGTIM)) && (ucr2 & FLD(UCR2, ATEN)))) { 527 DIS(bas, UCR1, RRDYEN); 528 DIS(bas, UCR2, ATEN); 529 ipend |= SER_INT_RXREADY; 530 } 531 532 /* A break can come in at any time, it never gets disabled. */ 533 if ((usr2 & FLD(USR2, BRCD)) && (ucr4 & FLD(UCR4, BKEN))) 534 ipend |= SER_INT_BREAK; 535 536 uart_unlock(sc->sc_hwmtx); 537 538 return (ipend); 539 } 540 541 static int 542 imx_uart_bus_param(struct uart_softc *sc, int baudrate, int databits, 543 int stopbits, int parity) 544 { 545 546 uart_lock(sc->sc_hwmtx); 547 imx_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity); 548 uart_unlock(sc->sc_hwmtx); 549 return (0); 550 } 551 552 static int 553 imx_uart_bus_probe(struct uart_softc *sc) 554 { 555 int error; 556 557 error = imx_uart_probe(&sc->sc_bas); 558 if (error) 559 return (error); 560 561 /* 562 * On input we can read up to the full fifo size at once. On output, we 563 * want to write only as much as the programmed tx low water level, 564 * because that's all we can be certain we have room for in the fifo 565 * when we get a tx-ready interrupt. 566 */ 567 sc->sc_rxfifosz = IMX_FIFOSZ; 568 sc->sc_txfifosz = IMX_TXFIFO_LEVEL; 569 570 device_set_desc(sc->sc_dev, "Freescale i.MX UART"); 571 return (0); 572 } 573 574 static int 575 imx_uart_bus_receive(struct uart_softc *sc) 576 { 577 struct uart_bas *bas; 578 int xc, out; 579 580 bas = &sc->sc_bas; 581 uart_lock(sc->sc_hwmtx); 582 583 /* 584 * Empty the rx fifo. We get the RRDY interrupt when IMX_RXFIFO_LEVEL 585 * (the rx high-water level) is reached, but we set sc_rxfifosz to the 586 * full hardware fifo size, so we can safely process however much is 587 * there, not just the highwater size. 588 */ 589 while (IS(bas, USR2, RDR)) { 590 if (uart_rx_full(sc)) { 591 /* No space left in input buffer */ 592 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 593 break; 594 } 595 xc = GETREG(bas, REG(URXD)); 596 out = xc & 0x000000ff; 597 if (xc & FLD(URXD, FRMERR)) 598 out |= UART_STAT_FRAMERR; 599 if (xc & FLD(URXD, PRERR)) 600 out |= UART_STAT_PARERR; 601 if (xc & FLD(URXD, OVRRUN)) 602 out |= UART_STAT_OVERRUN; 603 if (xc & FLD(URXD, BRK)) 604 out |= UART_STAT_BREAK; 605 606 uart_rx_put(sc, out); 607 } 608 ENA(bas, UCR1, RRDYEN); 609 ENA(bas, UCR2, ATEN); 610 611 uart_unlock(sc->sc_hwmtx); 612 return (0); 613 } 614 615 static int 616 imx_uart_bus_setsig(struct uart_softc *sc, int sig) 617 { 618 619 return (0); 620 } 621 622 static int 623 imx_uart_bus_transmit(struct uart_softc *sc) 624 { 625 struct uart_bas *bas = &sc->sc_bas; 626 int i; 627 628 bas = &sc->sc_bas; 629 uart_lock(sc->sc_hwmtx); 630 631 /* 632 * Fill the tx fifo. The uart core puts at most IMX_TXFIFO_LEVEL bytes 633 * into the txbuf (because that's what sc_txfifosz is set to), and 634 * because we got the TRDY (low-water reached) interrupt we know at 635 * least that much space is available in the fifo. 636 */ 637 for (i = 0; i < sc->sc_txdatasz; i++) { 638 SETREG(bas, REG(UTXD), sc->sc_txbuf[i] & 0xff); 639 } 640 sc->sc_txbusy = 1; 641 ENA(bas, UCR1, TRDYEN); 642 643 uart_unlock(sc->sc_hwmtx); 644 645 return (0); 646 } 647 648 static void 649 imx_uart_bus_grab(struct uart_softc *sc) 650 { 651 struct uart_bas *bas = &sc->sc_bas; 652 653 bas = &sc->sc_bas; 654 uart_lock(sc->sc_hwmtx); 655 DIS(bas, UCR1, RRDYEN); 656 DIS(bas, UCR2, ATEN); 657 uart_unlock(sc->sc_hwmtx); 658 } 659 660 static void 661 imx_uart_bus_ungrab(struct uart_softc *sc) 662 { 663 struct uart_bas *bas = &sc->sc_bas; 664 665 bas = &sc->sc_bas; 666 uart_lock(sc->sc_hwmtx); 667 ENA(bas, UCR1, RRDYEN); 668 ENA(bas, UCR2, ATEN); 669 uart_unlock(sc->sc_hwmtx); 670 } 671