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 56static int msm_uart_param(struct uart_bas *, int, int, int, int); 57 58/* 59 * Low-level UART interface. 60 */ 61static int msm_probe(struct uart_bas *bas); 62static void msm_init(struct uart_bas *bas, int, int, int, int); 63static void msm_term(struct uart_bas *bas); 64static void msm_putc(struct uart_bas *bas, int); 65static int msm_rxready(struct uart_bas *bas); 66static int msm_getc(struct uart_bas *bas, struct mtx *mtx); 67 68extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; 69 70static int 71msm_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 132struct 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 141static int 142msm_probe(struct uart_bas *bas) 143{ 144 145 return (0); 146} 147 148static void 149msm_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 214static void 215msm_term(struct uart_bas *bas) 216{ 217 218 /* XXX */ 219} 220 221static void 222msm_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 253static int 254msm_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 262static int 263msm_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 */ 289struct msm_uart_softc { 290 struct uart_softc base; 291 uint32_t ier; 292}; 293 294static int msm_bus_probe(struct uart_softc *sc); 295static int msm_bus_attach(struct uart_softc *sc); 296static int msm_bus_flush(struct uart_softc *, int); 297static int msm_bus_getsig(struct uart_softc *); 298static int msm_bus_ioctl(struct uart_softc *, int, intptr_t); 299static int msm_bus_ipend(struct uart_softc *); 300static int msm_bus_param(struct uart_softc *, int, int, int, int); 301static int msm_bus_receive(struct uart_softc *); 302static int msm_bus_setsig(struct uart_softc *, int); 303static int msm_bus_transmit(struct uart_softc *); 304static void msm_bus_grab(struct uart_softc *); 305static void msm_bus_ungrab(struct uart_softc *); 306 307static 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 323int 324msm_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 335static int 336msm_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 */ 356static int 357msm_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 387static int 388msm_bus_setsig(struct uart_softc *sc, int sig) 389{ 390 391 return (0); 392} 393 394static int 395msm_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 430static int 431msm_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 449static int 450msm_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 509static int 510msm_bus_flush(struct uart_softc *sc, int what) 511{ 512 513 return (0); 514} 515 516static int 517msm_bus_getsig(struct uart_softc *sc) 518{ 519 520 return (0); 521} 522 523static int 524msm_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 525{ 526 527 return (EINVAL); 528} 529 530static void 531msm_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 546static void 547msm_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 561struct 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};
| 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 56static int msm_uart_param(struct uart_bas *, int, int, int, int); 57 58/* 59 * Low-level UART interface. 60 */ 61static int msm_probe(struct uart_bas *bas); 62static void msm_init(struct uart_bas *bas, int, int, int, int); 63static void msm_term(struct uart_bas *bas); 64static void msm_putc(struct uart_bas *bas, int); 65static int msm_rxready(struct uart_bas *bas); 66static int msm_getc(struct uart_bas *bas, struct mtx *mtx); 67 68extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; 69 70static int 71msm_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 132struct 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 141static int 142msm_probe(struct uart_bas *bas) 143{ 144 145 return (0); 146} 147 148static void 149msm_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 214static void 215msm_term(struct uart_bas *bas) 216{ 217 218 /* XXX */ 219} 220 221static void 222msm_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 253static int 254msm_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 262static int 263msm_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 */ 289struct msm_uart_softc { 290 struct uart_softc base; 291 uint32_t ier; 292}; 293 294static int msm_bus_probe(struct uart_softc *sc); 295static int msm_bus_attach(struct uart_softc *sc); 296static int msm_bus_flush(struct uart_softc *, int); 297static int msm_bus_getsig(struct uart_softc *); 298static int msm_bus_ioctl(struct uart_softc *, int, intptr_t); 299static int msm_bus_ipend(struct uart_softc *); 300static int msm_bus_param(struct uart_softc *, int, int, int, int); 301static int msm_bus_receive(struct uart_softc *); 302static int msm_bus_setsig(struct uart_softc *, int); 303static int msm_bus_transmit(struct uart_softc *); 304static void msm_bus_grab(struct uart_softc *); 305static void msm_bus_ungrab(struct uart_softc *); 306 307static 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 323int 324msm_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 335static int 336msm_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 */ 356static int 357msm_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 387static int 388msm_bus_setsig(struct uart_softc *sc, int sig) 389{ 390 391 return (0); 392} 393 394static int 395msm_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 430static int 431msm_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 449static int 450msm_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 509static int 510msm_bus_flush(struct uart_softc *sc, int what) 511{ 512 513 return (0); 514} 515 516static int 517msm_bus_getsig(struct uart_softc *sc) 518{ 519 520 return (0); 521} 522 523static int 524msm_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 525{ 526 527 return (EINVAL); 528} 529 530static void 531msm_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 546static void 547msm_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 561struct 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};
|