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