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