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