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