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 void 94 imx_uart_init(struct uart_bas *bas, int baudrate, int databits, 95 int stopbits, int parity) 96 { 97 uint32_t baseclk, reg; 98 99 /* Enable the device and the RX/TX channels. */ 100 SET(bas, REG(UCR1), FLD(UCR1, UARTEN)); 101 SET(bas, REG(UCR2), FLD(UCR2, RXEN) | FLD(UCR2, TXEN)); 102 103 if (databits == 7) 104 DIS(bas, UCR2, WS); 105 else 106 ENA(bas, UCR2, WS); 107 108 if (stopbits == 2) 109 ENA(bas, UCR2, STPB); 110 else 111 DIS(bas, UCR2, STPB); 112 113 switch (parity) { 114 case UART_PARITY_ODD: 115 DIS(bas, UCR2, PROE); 116 ENA(bas, UCR2, PREN); 117 break; 118 case UART_PARITY_EVEN: 119 ENA(bas, UCR2, PROE); 120 ENA(bas, UCR2, PREN); 121 break; 122 case UART_PARITY_MARK: 123 case UART_PARITY_SPACE: 124 /* FALLTHROUGH: Hardware doesn't support mark/space. */ 125 case UART_PARITY_NONE: 126 default: 127 DIS(bas, UCR2, PREN); 128 break; 129 } 130 131 /* 132 * The hardware has an extremely flexible baud clock: it allows setting 133 * both the numerator and denominator of the divider, as well as a 134 * separate pre-divider. We simplify that problem by assuming a 135 * pre-divider and numerator of one because our base clock is so fast we 136 * can reach virtually any reasonable speed with a simple divisor. The 137 * numerator value actually includes the 16x over-sampling; the register 138 * value is the numerator-1, so we have a hard-coded 15. Note that a 139 * quirk of the hardware requires that both UBIR and UBMR be set back to 140 * back in order for the change to take effect. 141 */ 142 if (baudrate > 0) { 143 baseclk = imx_ccm_uart_hz(); 144 reg = GETREG(bas, REG(UFCR)); 145 reg = (reg & ~IMXUART_UFCR_RFDIV_MASK) | IMXUART_UFCR_RFDIV_DIV1; 146 SETREG(bas, REG(UFCR), reg); 147 SETREG(bas, REG(UBIR), 15); 148 SETREG(bas, REG(UBMR), (baseclk / baudrate) - 1); 149 } 150 } 151 152 static void 153 imx_uart_term(struct uart_bas *bas) 154 { 155 156 } 157 158 static void 159 imx_uart_putc(struct uart_bas *bas, int c) 160 { 161 162 while (!(IS(bas, USR2, TXFE))) 163 ; 164 SETREG(bas, REG(UTXD), c); 165 } 166 167 static int 168 imx_uart_rxready(struct uart_bas *bas) 169 { 170 171 return ((IS(bas, USR2, RDR)) ? 1 : 0); 172 } 173 174 static int 175 imx_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) 176 { 177 int c; 178 179 uart_lock(hwmtx); 180 while (!(IS(bas, USR2, RDR))) 181 ; 182 183 c = GETREG(bas, REG(URXD)); 184 uart_unlock(hwmtx); 185 #if defined(KDB) 186 if (c & FLD(URXD, BRK)) { 187 if (kdb_break()) 188 return (0); 189 } 190 #endif 191 return (c & 0xff); 192 } 193 194 /* 195 * High-level UART interface. 196 */ 197 struct imx_uart_softc { 198 struct uart_softc base; 199 }; 200 201 static int imx_uart_bus_attach(struct uart_softc *); 202 static int imx_uart_bus_detach(struct uart_softc *); 203 static int imx_uart_bus_flush(struct uart_softc *, int); 204 static int imx_uart_bus_getsig(struct uart_softc *); 205 static int imx_uart_bus_ioctl(struct uart_softc *, int, intptr_t); 206 static int imx_uart_bus_ipend(struct uart_softc *); 207 static int imx_uart_bus_param(struct uart_softc *, int, int, int, int); 208 static int imx_uart_bus_probe(struct uart_softc *); 209 static int imx_uart_bus_receive(struct uart_softc *); 210 static int imx_uart_bus_setsig(struct uart_softc *, int); 211 static int imx_uart_bus_transmit(struct uart_softc *); 212 static void imx_uart_bus_grab(struct uart_softc *); 213 static void imx_uart_bus_ungrab(struct uart_softc *); 214 215 static kobj_method_t imx_uart_methods[] = { 216 KOBJMETHOD(uart_attach, imx_uart_bus_attach), 217 KOBJMETHOD(uart_detach, imx_uart_bus_detach), 218 KOBJMETHOD(uart_flush, imx_uart_bus_flush), 219 KOBJMETHOD(uart_getsig, imx_uart_bus_getsig), 220 KOBJMETHOD(uart_ioctl, imx_uart_bus_ioctl), 221 KOBJMETHOD(uart_ipend, imx_uart_bus_ipend), 222 KOBJMETHOD(uart_param, imx_uart_bus_param), 223 KOBJMETHOD(uart_probe, imx_uart_bus_probe), 224 KOBJMETHOD(uart_receive, imx_uart_bus_receive), 225 KOBJMETHOD(uart_setsig, imx_uart_bus_setsig), 226 KOBJMETHOD(uart_transmit, imx_uart_bus_transmit), 227 KOBJMETHOD(uart_grab, imx_uart_bus_grab), 228 KOBJMETHOD(uart_ungrab, imx_uart_bus_ungrab), 229 { 0, 0 } 230 }; 231 232 struct uart_class uart_imx_class = { 233 "imx", 234 imx_uart_methods, 235 sizeof(struct imx_uart_softc), 236 .uc_ops = &uart_imx_uart_ops, 237 .uc_range = 0x100, 238 .uc_rclk = 24000000 /* TODO: get value from CCM */ 239 }; 240 241 #define SIGCHG(c, i, s, d) \ 242 if (c) { \ 243 i |= (i & s) ? s : s | d; \ 244 } else { \ 245 i = (i & s) ? (i & ~s) | d : i; \ 246 } 247 248 static int 249 imx_uart_bus_attach(struct uart_softc *sc) 250 { 251 struct uart_bas *bas; 252 struct uart_devinfo *di; 253 254 bas = &sc->sc_bas; 255 if (sc->sc_sysdev != NULL) { 256 di = sc->sc_sysdev; 257 imx_uart_init(bas, di->baudrate, di->databits, di->stopbits, 258 di->parity); 259 } else { 260 imx_uart_init(bas, 115200, 8, 1, 0); 261 } 262 263 (void)imx_uart_bus_getsig(sc); 264 265 ENA(bas, UCR4, DREN); 266 DIS(bas, UCR1, RRDYEN); 267 DIS(bas, UCR1, IDEN); 268 DIS(bas, UCR3, RXDSEN); 269 DIS(bas, UCR2, ATEN); 270 DIS(bas, UCR1, TXMPTYEN); 271 DIS(bas, UCR1, TRDYEN); 272 DIS(bas, UCR4, TCEN); 273 DIS(bas, UCR4, OREN); 274 ENA(bas, UCR4, BKEN); 275 DIS(bas, UCR4, WKEN); 276 DIS(bas, UCR1, ADEN); 277 DIS(bas, UCR3, ACIEN); 278 DIS(bas, UCR2, ESCI); 279 DIS(bas, UCR4, ENIRI); 280 DIS(bas, UCR3, AIRINTEN); 281 DIS(bas, UCR3, AWAKEN); 282 DIS(bas, UCR3, FRAERREN); 283 DIS(bas, UCR3, PARERREN); 284 DIS(bas, UCR1, RTSDEN); 285 DIS(bas, UCR2, RTSEN); 286 DIS(bas, UCR3, DTREN); 287 DIS(bas, UCR3, RI); 288 DIS(bas, UCR3, DCD); 289 DIS(bas, UCR3, DTRDEN); 290 ENA(bas, UCR2, IRTS); 291 ENA(bas, UCR3, RXDMUXSEL); 292 293 /* ACK all interrupts */ 294 SETREG(bas, REG(USR1), 0xffff); 295 SETREG(bas, REG(USR2), 0xffff); 296 return (0); 297 } 298 299 static int 300 imx_uart_bus_detach(struct uart_softc *sc) 301 { 302 303 SETREG(&sc->sc_bas, REG(UCR4), 0); 304 305 return (0); 306 } 307 308 static int 309 imx_uart_bus_flush(struct uart_softc *sc, int what) 310 { 311 312 /* TODO */ 313 return (0); 314 } 315 316 static int 317 imx_uart_bus_getsig(struct uart_softc *sc) 318 { 319 uint32_t new, old, sig; 320 uint8_t bes; 321 322 do { 323 old = sc->sc_hwsig; 324 sig = old; 325 uart_lock(sc->sc_hwmtx); 326 bes = GETREG(&sc->sc_bas, REG(USR2)); 327 uart_unlock(sc->sc_hwmtx); 328 /* XXX: chip can show delta */ 329 SIGCHG(bes & FLD(USR2, DCDIN), sig, SER_DCD, SER_DDCD); 330 new = sig & ~SER_MASK_DELTA; 331 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 332 333 return (sig); 334 } 335 336 static int 337 imx_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 338 { 339 struct uart_bas *bas; 340 int error; 341 342 bas = &sc->sc_bas; 343 error = 0; 344 uart_lock(sc->sc_hwmtx); 345 switch (request) { 346 case UART_IOCTL_BREAK: 347 /* TODO */ 348 break; 349 case UART_IOCTL_BAUD: 350 /* TODO */ 351 *(int*)data = 115200; 352 break; 353 default: 354 error = EINVAL; 355 break; 356 } 357 uart_unlock(sc->sc_hwmtx); 358 359 return (error); 360 } 361 362 static int 363 imx_uart_bus_ipend(struct uart_softc *sc) 364 { 365 struct uart_bas *bas; 366 int ipend; 367 uint32_t usr1, usr2; 368 uint32_t ucr1, ucr4; 369 370 bas = &sc->sc_bas; 371 ipend = 0; 372 373 uart_lock(sc->sc_hwmtx); 374 375 /* Read pending interrupts */ 376 usr1 = GETREG(bas, REG(USR1)); 377 usr2 = GETREG(bas, REG(USR2)); 378 /* ACK interrupts */ 379 SETREG(bas, REG(USR1), usr1); 380 SETREG(bas, REG(USR2), usr2); 381 382 ucr1 = GETREG(bas, REG(UCR1)); 383 ucr4 = GETREG(bas, REG(UCR4)); 384 385 if ((usr2 & FLD(USR2, TXFE)) && (ucr1 & FLD(UCR1, TXMPTYEN))) { 386 DIS(bas, UCR1, TXMPTYEN); 387 /* Continue TXing */ 388 ipend |= SER_INT_TXIDLE; 389 } 390 if ((usr2 & FLD(USR2, RDR)) && (ucr4 & FLD(UCR4, DREN))) { 391 DIS(bas, UCR4, DREN); 392 /* Wow, new char on input */ 393 ipend |= SER_INT_RXREADY; 394 } 395 if ((usr2 & FLD(USR2, BRCD)) && (ucr4 & FLD(UCR4, BKEN))) 396 ipend |= SER_INT_BREAK; 397 398 uart_unlock(sc->sc_hwmtx); 399 400 return (ipend); 401 } 402 403 static int 404 imx_uart_bus_param(struct uart_softc *sc, int baudrate, int databits, 405 int stopbits, int parity) 406 { 407 408 uart_lock(sc->sc_hwmtx); 409 imx_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity); 410 uart_unlock(sc->sc_hwmtx); 411 return (0); 412 } 413 414 static int 415 imx_uart_bus_probe(struct uart_softc *sc) 416 { 417 int error; 418 419 error = imx_uart_probe(&sc->sc_bas); 420 if (error) 421 return (error); 422 423 sc->sc_rxfifosz = 1; 424 sc->sc_txfifosz = 1; 425 426 device_set_desc(sc->sc_dev, "Freescale i.MX UART"); 427 return (0); 428 } 429 430 static int 431 imx_uart_bus_receive(struct uart_softc *sc) 432 { 433 struct uart_bas *bas; 434 int xc, out; 435 436 bas = &sc->sc_bas; 437 uart_lock(sc->sc_hwmtx); 438 439 /* Read while we have anything in FIFO */ 440 while (IS(bas, USR2, RDR)) { 441 if (uart_rx_full(sc)) { 442 /* No space left in input buffer */ 443 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 444 break; 445 } 446 out = 0; 447 xc = GETREG(bas, REG(URXD)); 448 449 /* We have valid char */ 450 if (xc & FLD(URXD, CHARRDY)) 451 out = xc & 0x000000ff; 452 453 if (xc & FLD(URXD, FRMERR)) 454 out |= UART_STAT_FRAMERR; 455 if (xc & FLD(URXD, PRERR)) 456 out |= UART_STAT_PARERR; 457 if (xc & FLD(URXD, OVRRUN)) 458 out |= UART_STAT_OVERRUN; 459 if (xc & FLD(URXD, BRK)) 460 out |= UART_STAT_BREAK; 461 462 uart_rx_put(sc, out); 463 } 464 /* Reenable Data Ready interrupt */ 465 ENA(bas, UCR4, DREN); 466 467 uart_unlock(sc->sc_hwmtx); 468 return (0); 469 } 470 471 static int 472 imx_uart_bus_setsig(struct uart_softc *sc, int sig) 473 { 474 475 return (0); 476 } 477 478 static int 479 imx_uart_bus_transmit(struct uart_softc *sc) 480 { 481 struct uart_bas *bas = &sc->sc_bas; 482 int i; 483 484 bas = &sc->sc_bas; 485 uart_lock(sc->sc_hwmtx); 486 487 /* Fill TX FIFO */ 488 for (i = 0; i < sc->sc_txdatasz; i++) { 489 SETREG(bas, REG(UTXD), sc->sc_txbuf[i] & 0xff); 490 } 491 492 sc->sc_txbusy = 1; 493 /* Call me when ready */ 494 ENA(bas, UCR1, TXMPTYEN); 495 496 uart_unlock(sc->sc_hwmtx); 497 498 return (0); 499 } 500 501 static void 502 imx_uart_bus_grab(struct uart_softc *sc) 503 { 504 struct uart_bas *bas = &sc->sc_bas; 505 506 bas = &sc->sc_bas; 507 uart_lock(sc->sc_hwmtx); 508 DIS(bas, UCR4, DREN); 509 uart_unlock(sc->sc_hwmtx); 510 } 511 512 static void 513 imx_uart_bus_ungrab(struct uart_softc *sc) 514 { 515 struct uart_bas *bas = &sc->sc_bas; 516 517 bas = &sc->sc_bas; 518 uart_lock(sc->sc_hwmtx); 519 ENA(bas, UCR4, DREN); 520 uart_unlock(sc->sc_hwmtx); 521 } 522