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 #include "opt_ddb.h" 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/bus.h> 35 #include <sys/conf.h> 36 #include <sys/kdb.h> 37 #include <machine/bus.h> 38 39 #include <dev/uart/uart.h> 40 #include <dev/uart/uart_cpu.h> 41 #include <dev/uart/uart_cpu_fdt.h> 42 #include <dev/uart/uart_bus.h> 43 #include <dev/uart/uart_dev_msm.h> 44 45 #include "uart_if.h" 46 47 #define DEF_CLK 7372800 48 49 #define GETREG(bas, reg) \ 50 bus_space_read_4((bas)->bst, (bas)->bsh, (reg)) 51 #define SETREG(bas, reg, value) \ 52 bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value)) 53 54 static int msm_uart_param(struct uart_bas *, int, int, int, int); 55 56 /* 57 * Low-level UART interface. 58 */ 59 static int msm_probe(struct uart_bas *bas); 60 static void msm_init(struct uart_bas *bas, int, int, int, int); 61 static void msm_term(struct uart_bas *bas); 62 static void msm_putc(struct uart_bas *bas, int); 63 static int msm_rxready(struct uart_bas *bas); 64 static int msm_getc(struct uart_bas *bas, struct mtx *mtx); 65 66 extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; 67 68 static int 69 msm_uart_param(struct uart_bas *bas, int baudrate, int databits, 70 int stopbits, int parity) 71 { 72 int ulcon; 73 74 ulcon = 0; 75 76 switch (databits) { 77 case 5: 78 ulcon |= (UART_DM_5_BPS << 4); 79 break; 80 case 6: 81 ulcon |= (UART_DM_6_BPS << 4); 82 break; 83 case 7: 84 ulcon |= (UART_DM_7_BPS << 4); 85 break; 86 case 8: 87 ulcon |= (UART_DM_8_BPS << 4); 88 break; 89 default: 90 return (EINVAL); 91 } 92 93 switch (parity) { 94 case UART_PARITY_NONE: 95 ulcon |= UART_DM_NO_PARITY; 96 break; 97 case UART_PARITY_ODD: 98 ulcon |= UART_DM_ODD_PARITY; 99 break; 100 case UART_PARITY_EVEN: 101 ulcon |= UART_DM_EVEN_PARITY; 102 break; 103 case UART_PARITY_SPACE: 104 ulcon |= UART_DM_SPACE_PARITY; 105 break; 106 case UART_PARITY_MARK: 107 default: 108 return (EINVAL); 109 } 110 111 switch (stopbits) { 112 case 1: 113 ulcon |= (UART_DM_SBL_1 << 2); 114 break; 115 case 2: 116 ulcon |= (UART_DM_SBL_2 << 2); 117 break; 118 default: 119 return (EINVAL); 120 } 121 uart_setreg(bas, UART_DM_MR2, ulcon); 122 uart_barrier(bas); 123 124 return (0); 125 } 126 127 struct uart_ops uart_msm_ops = { 128 .probe = msm_probe, 129 .init = msm_init, 130 .term = msm_term, 131 .putc = msm_putc, 132 .rxready = msm_rxready, 133 .getc = msm_getc, 134 }; 135 136 static int 137 msm_probe(struct uart_bas *bas) 138 { 139 140 bas->regiowidth = 4; 141 142 return (0); 143 } 144 145 static void 146 msm_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 147 int parity) 148 { 149 150 if (bas->rclk == 0) 151 bas->rclk = DEF_CLK; 152 153 KASSERT(bas->rclk != 0, ("msm_init: Invalid rclk")); 154 155 /* Set default parameters */ 156 msm_uart_param(bas, baudrate, databits, stopbits, parity); 157 158 /* 159 * Configure UART mode registers MR1 and MR2. 160 * Hardware flow control isn't supported. 161 */ 162 uart_setreg(bas, UART_DM_MR1, 0x0); 163 164 /* Reset interrupt mask register. */ 165 uart_setreg(bas, UART_DM_IMR, 0); 166 167 /* 168 * Configure Tx and Rx watermarks configuration registers. 169 * TX watermark value is set to 0 - interrupt is generated when 170 * FIFO level is less than or equal to 0. 171 */ 172 uart_setreg(bas, UART_DM_TFWR, UART_DM_TFW_VALUE); 173 174 /* Set RX watermark value */ 175 uart_setreg(bas, UART_DM_RFWR, UART_DM_RFW_VALUE); 176 177 /* 178 * Configure Interrupt Programming Register. 179 * Set initial Stale timeout value. 180 */ 181 uart_setreg(bas, UART_DM_IPR, UART_DM_STALE_TIMEOUT_LSB); 182 183 /* Disable IRDA mode */ 184 uart_setreg(bas, UART_DM_IRDA, 0x0); 185 186 /* 187 * Configure and enable sim interface if required. 188 * Configure hunt character value in HCR register. 189 * Keep it in reset state. 190 */ 191 uart_setreg(bas, UART_DM_HCR, 0x0); 192 193 /* Issue soft reset command */ 194 SETREG(bas, UART_DM_CR, UART_DM_RESET_TX); 195 SETREG(bas, UART_DM_CR, UART_DM_RESET_RX); 196 SETREG(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS); 197 SETREG(bas, UART_DM_CR, UART_DM_RESET_BREAK_INT); 198 SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT); 199 200 /* Enable/Disable Rx/Tx DM interfaces */ 201 uart_setreg(bas, UART_DM_DMEN, UART_DM_DMEN_RX_SC_ENABLE); 202 203 /* Enable transmitter and receiver */ 204 uart_setreg(bas, UART_DM_CR, UART_DM_CR_RX_ENABLE); 205 uart_setreg(bas, UART_DM_CR, UART_DM_CR_TX_ENABLE); 206 207 uart_barrier(bas); 208 } 209 210 static void 211 msm_term(struct uart_bas *bas) 212 { 213 214 /* XXX */ 215 } 216 217 static void 218 msm_putc(struct uart_bas *bas, int c) 219 { 220 int limit; 221 222 /* 223 * Write to NO_CHARS_FOR_TX register the number of characters 224 * to be transmitted. However, before writing TX_FIFO must 225 * be empty as indicated by TX_READY interrupt in IMR register 226 */ 227 228 /* 229 * Check if transmit FIFO is empty. 230 * If not wait for TX_READY interrupt. 231 */ 232 limit = 1000; 233 if (!(uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXEMT)) { 234 while ((uart_getreg(bas, UART_DM_ISR) & UART_DM_TX_READY) == 0 235 && --limit) 236 DELAY(4); 237 SETREG(bas, UART_DM_CR, UART_DM_CLEAR_TX_READY); 238 } 239 /* FIFO is ready, write number of characters to be written */ 240 uart_setreg(bas, UART_DM_NO_CHARS_FOR_TX, 1); 241 242 /* Wait till TX FIFO has space */ 243 while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXRDY) == 0) 244 DELAY(4); 245 246 /* TX FIFO has space. Write char */ 247 SETREG(bas, UART_DM_TF(0), (c & 0xff)); 248 } 249 250 static int 251 msm_rxready(struct uart_bas *bas) 252 { 253 254 /* Wait for a character to come ready */ 255 return ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) == 256 UART_DM_SR_RXRDY); 257 } 258 259 static int 260 msm_getc(struct uart_bas *bas, struct mtx *mtx) 261 { 262 int c; 263 264 uart_lock(mtx); 265 266 /* Wait for a character to come ready */ 267 while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) != 268 UART_DM_SR_RXRDY) 269 DELAY(4); 270 271 /* Check for Overrun error. If so reset Error Status */ 272 if (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_UART_OVERRUN) 273 uart_setreg(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS); 274 275 /* Read char */ 276 c = uart_getreg(bas, UART_DM_RF(0)); 277 278 uart_unlock(mtx); 279 280 return (c); 281 } 282 283 /* 284 * High-level UART interface. 285 */ 286 struct msm_uart_softc { 287 struct uart_softc base; 288 uint32_t ier; 289 }; 290 291 static int msm_bus_probe(struct uart_softc *sc); 292 static int msm_bus_attach(struct uart_softc *sc); 293 static int msm_bus_flush(struct uart_softc *, int); 294 static int msm_bus_getsig(struct uart_softc *); 295 static int msm_bus_ioctl(struct uart_softc *, int, intptr_t); 296 static int msm_bus_ipend(struct uart_softc *); 297 static int msm_bus_param(struct uart_softc *, int, int, int, int); 298 static int msm_bus_receive(struct uart_softc *); 299 static int msm_bus_setsig(struct uart_softc *, int); 300 static int msm_bus_transmit(struct uart_softc *); 301 static void msm_bus_grab(struct uart_softc *); 302 static void msm_bus_ungrab(struct uart_softc *); 303 304 static kobj_method_t msm_methods[] = { 305 KOBJMETHOD(uart_probe, msm_bus_probe), 306 KOBJMETHOD(uart_attach, msm_bus_attach), 307 KOBJMETHOD(uart_flush, msm_bus_flush), 308 KOBJMETHOD(uart_getsig, msm_bus_getsig), 309 KOBJMETHOD(uart_ioctl, msm_bus_ioctl), 310 KOBJMETHOD(uart_ipend, msm_bus_ipend), 311 KOBJMETHOD(uart_param, msm_bus_param), 312 KOBJMETHOD(uart_receive, msm_bus_receive), 313 KOBJMETHOD(uart_setsig, msm_bus_setsig), 314 KOBJMETHOD(uart_transmit, msm_bus_transmit), 315 KOBJMETHOD(uart_grab, msm_bus_grab), 316 KOBJMETHOD(uart_ungrab, msm_bus_ungrab), 317 {0, 0 } 318 }; 319 320 int 321 msm_bus_probe(struct uart_softc *sc) 322 { 323 struct uart_bas *bas; 324 325 bas = &sc->sc_bas; 326 bas->regiowidth = 4; 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-v1.4", (uintptr_t)&uart_msm_class}, 574 {"qcom,msm-uartdm", (uintptr_t)&uart_msm_class}, 575 {NULL, (uintptr_t)NULL}, 576 }; 577 UART_FDT_CLASS_AND_DEVICE(compat_data); 578