1 /*- 2 * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 /* Qualcomm MSM7K/8K uart driver */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 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 #include <machine/fdt.h> 41 42 #include <dev/uart/uart.h> 43 #include <dev/uart/uart_cpu.h> 44 #include <dev/uart/uart_cpu_fdt.h> 45 #include <dev/uart/uart_bus.h> 46 #include <dev/uart/uart_dev_msm.h> 47 48 #include "uart_if.h" 49 50 #define DEF_CLK 7372800 51 52 #define GETREG(bas, reg) \ 53 bus_space_read_4((bas)->bst, (bas)->bsh, (reg)) 54 #define SETREG(bas, reg, value) \ 55 bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value)) 56 57 static int msm_uart_param(struct uart_bas *, int, int, int, int); 58 59 /* 60 * Low-level UART interface. 61 */ 62 static int msm_probe(struct uart_bas *bas); 63 static void msm_init(struct uart_bas *bas, int, int, int, int); 64 static void msm_term(struct uart_bas *bas); 65 static void msm_putc(struct uart_bas *bas, int); 66 static int msm_rxready(struct uart_bas *bas); 67 static int msm_getc(struct uart_bas *bas, struct mtx *mtx); 68 69 extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; 70 71 static int 72 msm_uart_param(struct uart_bas *bas, int baudrate, int databits, 73 int stopbits, int parity) 74 { 75 int ulcon; 76 77 ulcon = 0; 78 79 switch (databits) { 80 case 5: 81 ulcon |= (UART_DM_5_BPS << 4); 82 break; 83 case 6: 84 ulcon |= (UART_DM_6_BPS << 4); 85 break; 86 case 7: 87 ulcon |= (UART_DM_7_BPS << 4); 88 break; 89 case 8: 90 ulcon |= (UART_DM_8_BPS << 4); 91 break; 92 default: 93 return (EINVAL); 94 } 95 96 switch (parity) { 97 case UART_PARITY_NONE: 98 ulcon |= UART_DM_NO_PARITY; 99 break; 100 case UART_PARITY_ODD: 101 ulcon |= UART_DM_ODD_PARITY; 102 break; 103 case UART_PARITY_EVEN: 104 ulcon |= UART_DM_EVEN_PARITY; 105 break; 106 case UART_PARITY_SPACE: 107 ulcon |= UART_DM_SPACE_PARITY; 108 break; 109 case UART_PARITY_MARK: 110 default: 111 return (EINVAL); 112 } 113 114 switch (stopbits) { 115 case 1: 116 ulcon |= (UART_DM_SBL_1 << 2); 117 break; 118 case 2: 119 ulcon |= (UART_DM_SBL_2 << 2); 120 break; 121 default: 122 return (EINVAL); 123 } 124 uart_setreg(bas, UART_DM_MR2, ulcon); 125 126 /* Set 115200 for both TX and RX. */; 127 uart_setreg(bas, UART_DM_CSR, UART_DM_CSR_115200); 128 uart_barrier(bas); 129 130 return (0); 131 } 132 133 struct uart_ops uart_msm_ops = { 134 .probe = msm_probe, 135 .init = msm_init, 136 .term = msm_term, 137 .putc = msm_putc, 138 .rxready = msm_rxready, 139 .getc = msm_getc, 140 }; 141 142 static int 143 msm_probe(struct uart_bas *bas) 144 { 145 146 return (0); 147 } 148 149 static void 150 msm_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 151 int parity) 152 { 153 154 if (bas->rclk == 0) 155 bas->rclk = DEF_CLK; 156 157 KASSERT(bas->rclk != 0, ("msm_init: Invalid rclk")); 158 159 /* Set default parameters */ 160 msm_uart_param(bas, baudrate, databits, stopbits, parity); 161 162 /* 163 * Configure UART mode registers MR1 and MR2. 164 * Hardware flow control isn't supported. 165 */ 166 uart_setreg(bas, UART_DM_MR1, 0x0); 167 168 /* Reset interrupt mask register. */ 169 uart_setreg(bas, UART_DM_IMR, 0); 170 171 /* 172 * Configure Tx and Rx watermarks configuration registers. 173 * TX watermark value is set to 0 - interrupt is generated when 174 * FIFO level is less than or equal to 0. 175 */ 176 uart_setreg(bas, UART_DM_TFWR, UART_DM_TFW_VALUE); 177 178 /* Set RX watermark value */ 179 uart_setreg(bas, UART_DM_RFWR, UART_DM_RFW_VALUE); 180 181 /* 182 * Configure Interrupt Programming Register. 183 * Set initial Stale timeout value. 184 */ 185 uart_setreg(bas, UART_DM_IPR, UART_DM_STALE_TIMEOUT_LSB); 186 187 /* Disable IRDA mode */ 188 uart_setreg(bas, UART_DM_IRDA, 0x0); 189 190 /* 191 * Configure and enable sim interface if required. 192 * Configure hunt character value in HCR register. 193 * Keep it in reset state. 194 */ 195 uart_setreg(bas, UART_DM_HCR, 0x0); 196 197 /* Issue soft reset command */ 198 SETREG(bas, UART_DM_CR, UART_DM_RESET_TX); 199 SETREG(bas, UART_DM_CR, UART_DM_RESET_RX); 200 SETREG(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS); 201 SETREG(bas, UART_DM_CR, UART_DM_RESET_BREAK_INT); 202 SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT); 203 204 /* Enable/Disable Rx/Tx DM interfaces */ 205 /* Disable Data Mover for now. */ 206 uart_setreg(bas, UART_DM_DMEN, 0x0); 207 208 /* Enable transmitter and receiver */ 209 uart_setreg(bas, UART_DM_CR, UART_DM_CR_RX_ENABLE); 210 uart_setreg(bas, UART_DM_CR, UART_DM_CR_TX_ENABLE); 211 212 uart_barrier(bas); 213 } 214 215 static void 216 msm_term(struct uart_bas *bas) 217 { 218 219 /* XXX */ 220 } 221 222 static void 223 msm_putc(struct uart_bas *bas, int c) 224 { 225 int limit; 226 227 /* 228 * Write to NO_CHARS_FOR_TX register the number of characters 229 * to be transmitted. However, before writing TX_FIFO must 230 * be empty as indicated by TX_READY interrupt in IMR register 231 */ 232 233 /* 234 * Check if transmit FIFO is empty. 235 * If not wait for TX_READY interrupt. 236 */ 237 limit = 1000; 238 if (!(uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXEMT)) { 239 while ((uart_getreg(bas, UART_DM_ISR) & UART_DM_TX_READY) == 0 240 && --limit) 241 DELAY(4); 242 } 243 /* FIFO is ready, write number of characters to be written */ 244 uart_setreg(bas, UART_DM_NO_CHARS_FOR_TX, 1); 245 246 /* Wait till TX FIFO has space */ 247 while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXRDY) == 0) 248 DELAY(4); 249 250 /* TX FIFO has space. Write char */ 251 SETREG(bas, UART_DM_TF(0), (c & 0xff)); 252 } 253 254 static int 255 msm_rxready(struct uart_bas *bas) 256 { 257 258 /* Wait for a character to come ready */ 259 return ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) == 260 UART_DM_SR_RXRDY); 261 } 262 263 static int 264 msm_getc(struct uart_bas *bas, struct mtx *mtx) 265 { 266 int c; 267 268 uart_lock(mtx); 269 270 /* Wait for a character to come ready */ 271 while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) != 272 UART_DM_SR_RXRDY) 273 DELAY(4); 274 275 /* Check for Overrun error. If so reset Error Status */ 276 if (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_UART_OVERRUN) 277 uart_setreg(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS); 278 279 /* Read char */ 280 c = uart_getreg(bas, UART_DM_RF(0)); 281 282 uart_unlock(mtx); 283 284 return (c); 285 } 286 287 /* 288 * High-level UART interface. 289 */ 290 struct msm_uart_softc { 291 struct uart_softc base; 292 uint32_t ier; 293 }; 294 295 static int msm_bus_probe(struct uart_softc *sc); 296 static int msm_bus_attach(struct uart_softc *sc); 297 static int msm_bus_flush(struct uart_softc *, int); 298 static int msm_bus_getsig(struct uart_softc *); 299 static int msm_bus_ioctl(struct uart_softc *, int, intptr_t); 300 static int msm_bus_ipend(struct uart_softc *); 301 static int msm_bus_param(struct uart_softc *, int, int, int, int); 302 static int msm_bus_receive(struct uart_softc *); 303 static int msm_bus_setsig(struct uart_softc *, int); 304 static int msm_bus_transmit(struct uart_softc *); 305 static void msm_bus_grab(struct uart_softc *); 306 static void msm_bus_ungrab(struct uart_softc *); 307 308 static kobj_method_t msm_methods[] = { 309 KOBJMETHOD(uart_probe, msm_bus_probe), 310 KOBJMETHOD(uart_attach, msm_bus_attach), 311 KOBJMETHOD(uart_flush, msm_bus_flush), 312 KOBJMETHOD(uart_getsig, msm_bus_getsig), 313 KOBJMETHOD(uart_ioctl, msm_bus_ioctl), 314 KOBJMETHOD(uart_ipend, msm_bus_ipend), 315 KOBJMETHOD(uart_param, msm_bus_param), 316 KOBJMETHOD(uart_receive, msm_bus_receive), 317 KOBJMETHOD(uart_setsig, msm_bus_setsig), 318 KOBJMETHOD(uart_transmit, msm_bus_transmit), 319 KOBJMETHOD(uart_grab, msm_bus_grab), 320 KOBJMETHOD(uart_ungrab, msm_bus_ungrab), 321 {0, 0 } 322 }; 323 324 int 325 msm_bus_probe(struct uart_softc *sc) 326 { 327 328 sc->sc_txfifosz = 64; 329 sc->sc_rxfifosz = 64; 330 331 device_set_desc(sc->sc_dev, "Qualcomm HSUART"); 332 333 return (0); 334 } 335 336 static int 337 msm_bus_attach(struct uart_softc *sc) 338 { 339 struct msm_uart_softc *u = (struct msm_uart_softc *)sc; 340 struct uart_bas *bas = &sc->sc_bas; 341 342 sc->sc_hwiflow = 0; 343 sc->sc_hwoflow = 0; 344 345 /* Set TX_READY, TXLEV, RXLEV, RXSTALE */ 346 u->ier = UART_DM_IMR_ENABLED; 347 348 /* Configure Interrupt Mask register IMR */ 349 uart_setreg(bas, UART_DM_IMR, u->ier); 350 351 return (0); 352 } 353 354 /* 355 * Write the current transmit buffer to the TX FIFO. 356 */ 357 static int 358 msm_bus_transmit(struct uart_softc *sc) 359 { 360 struct msm_uart_softc *u = (struct msm_uart_softc *)sc; 361 struct uart_bas *bas = &sc->sc_bas; 362 int i; 363 364 uart_lock(sc->sc_hwmtx); 365 366 /* Write some data */ 367 for (i = 0; i < sc->sc_txdatasz; i++) { 368 /* Write TX data */ 369 msm_putc(bas, sc->sc_txbuf[i]); 370 uart_barrier(bas); 371 } 372 373 /* TX FIFO is empty now, enable TX_READY interrupt */ 374 u->ier |= UART_DM_TX_READY; 375 SETREG(bas, UART_DM_IMR, u->ier); 376 uart_barrier(bas); 377 378 /* 379 * Inform upper layer that it is transmitting data to hardware, 380 * this will be cleared when TXIDLE interrupt occurs. 381 */ 382 sc->sc_txbusy = 1; 383 uart_unlock(sc->sc_hwmtx); 384 385 return (0); 386 } 387 388 static int 389 msm_bus_setsig(struct uart_softc *sc, int sig) 390 { 391 392 return (0); 393 } 394 395 static int 396 msm_bus_receive(struct uart_softc *sc) 397 { 398 struct msm_uart_softc *u = (struct msm_uart_softc *)sc; 399 struct uart_bas *bas; 400 int c; 401 402 bas = &sc->sc_bas; 403 uart_lock(sc->sc_hwmtx); 404 405 /* Initialize Receive Path and interrupt */ 406 SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT); 407 SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_ENABLE); 408 u->ier |= UART_DM_RXLEV; 409 SETREG(bas, UART_DM_IMR, u->ier); 410 411 /* Loop over until we are full, or no data is available */ 412 while (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) { 413 if (uart_rx_full(sc)) { 414 /* No space left in input buffer */ 415 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 416 break; 417 } 418 419 /* Read RX FIFO */ 420 c = uart_getreg(bas, UART_DM_RF(0)); 421 uart_barrier(bas); 422 423 uart_rx_put(sc, c); 424 } 425 426 uart_unlock(sc->sc_hwmtx); 427 428 return (0); 429 } 430 431 static int 432 msm_bus_param(struct uart_softc *sc, int baudrate, int databits, 433 int stopbits, int parity) 434 { 435 int error; 436 437 if (sc->sc_bas.rclk == 0) 438 sc->sc_bas.rclk = DEF_CLK; 439 440 KASSERT(sc->sc_bas.rclk != 0, ("msm_init: Invalid rclk")); 441 442 uart_lock(sc->sc_hwmtx); 443 error = msm_uart_param(&sc->sc_bas, baudrate, databits, stopbits, 444 parity); 445 uart_unlock(sc->sc_hwmtx); 446 447 return (error); 448 } 449 450 static int 451 msm_bus_ipend(struct uart_softc *sc) 452 { 453 struct msm_uart_softc *u = (struct msm_uart_softc *)sc; 454 struct uart_bas *bas = &sc->sc_bas; 455 uint32_t isr; 456 int ipend; 457 458 uart_lock(sc->sc_hwmtx); 459 460 /* Get ISR status */ 461 isr = GETREG(bas, UART_DM_MISR); 462 463 ipend = 0; 464 465 /* Uart RX starting, notify upper layer */ 466 if (isr & UART_DM_RXLEV) { 467 u->ier &= ~UART_DM_RXLEV; 468 SETREG(bas, UART_DM_IMR, u->ier); 469 uart_barrier(bas); 470 ipend |= SER_INT_RXREADY; 471 } 472 473 /* Stale RX interrupt */ 474 if (isr & UART_DM_RXSTALE) { 475 /* Disable and reset it */ 476 SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_DISABLE); 477 SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT); 478 uart_barrier(bas); 479 ipend |= SER_INT_RXREADY; 480 } 481 482 /* TX READY interrupt */ 483 if (isr & UART_DM_TX_READY) { 484 /* Clear TX Ready */ 485 SETREG(bas, UART_DM_CR, UART_DM_CLEAR_TX_READY); 486 487 /* Disable TX_READY */ 488 u->ier &= ~UART_DM_TX_READY; 489 SETREG(bas, UART_DM_IMR, u->ier); 490 uart_barrier(bas); 491 492 if (sc->sc_txbusy != 0) 493 ipend |= SER_INT_TXIDLE; 494 } 495 496 if (isr & UART_DM_TXLEV) { 497 /* TX FIFO is empty */ 498 u->ier &= ~UART_DM_TXLEV; 499 SETREG(bas, UART_DM_IMR, u->ier); 500 uart_barrier(bas); 501 502 if (sc->sc_txbusy != 0) 503 ipend |= SER_INT_TXIDLE; 504 } 505 506 uart_unlock(sc->sc_hwmtx); 507 return (ipend); 508 } 509 510 static int 511 msm_bus_flush(struct uart_softc *sc, int what) 512 { 513 514 return (0); 515 } 516 517 static int 518 msm_bus_getsig(struct uart_softc *sc) 519 { 520 521 return (0); 522 } 523 524 static int 525 msm_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 526 { 527 528 return (EINVAL); 529 } 530 531 static void 532 msm_bus_grab(struct uart_softc *sc) 533 { 534 struct uart_bas *bas = &sc->sc_bas; 535 536 /* 537 * XXX: Turn off all interrupts to enter polling mode. Leave the 538 * saved mask alone. We'll restore whatever it was in ungrab. 539 */ 540 uart_lock(sc->sc_hwmtx); 541 SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT); 542 SETREG(bas, UART_DM_IMR, 0); 543 uart_barrier(bas); 544 uart_unlock(sc->sc_hwmtx); 545 } 546 547 static void 548 msm_bus_ungrab(struct uart_softc *sc) 549 { 550 struct msm_uart_softc *u = (struct msm_uart_softc *)sc; 551 struct uart_bas *bas = &sc->sc_bas; 552 553 /* 554 * Restore previous interrupt mask 555 */ 556 uart_lock(sc->sc_hwmtx); 557 SETREG(bas, UART_DM_IMR, u->ier); 558 uart_barrier(bas); 559 uart_unlock(sc->sc_hwmtx); 560 } 561 562 static struct uart_class uart_msm_class = { 563 "msm", 564 msm_methods, 565 sizeof(struct msm_uart_softc), 566 .uc_ops = &uart_msm_ops, 567 .uc_range = 8, 568 .uc_rclk = DEF_CLK, 569 .uc_rshift = 0 570 }; 571 572 static struct ofw_compat_data compat_data[] = { 573 {"qcom,msm-uartdm", (uintptr_t)&uart_msm_class}, 574 {NULL, (uintptr_t)NULL}, 575 }; 576 UART_FDT_CLASS_AND_DEVICE(compat_data); 577