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