uart_dev_pl011.c (283321) | uart_dev_pl011.c (283324) |
---|---|
1/*- 2 * Copyright (c) 2012 Semihalf. 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 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2012 Semihalf. 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 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_pl011.c 283321 2015-05-23 19:27:04Z ian $"); | 28__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_pl011.c 283324 2015-05-23 20:01:20Z ian $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/bus.h> 34#include <machine/bus.h> 35 36#include <dev/uart/uart.h> --- 36 unchanged lines hidden (view full) --- 73#define CR_UARTEN (1 << 0) /* UART enable */ 74 75#define UART_IMSC 0x0e /* Interrupt mask set/clear register */ 76#define IMSC_MASK_ALL 0x7ff /* Mask all interrupts */ 77 78#define UART_RIS 0x0f /* Raw interrupt status register */ 79#define UART_RXREADY (1 << 4) /* RX buffer full */ 80#define UART_TXEMPTY (1 << 5) /* TX buffer empty */ | 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/bus.h> 34#include <machine/bus.h> 35 36#include <dev/uart/uart.h> --- 36 unchanged lines hidden (view full) --- 73#define CR_UARTEN (1 << 0) /* UART enable */ 74 75#define UART_IMSC 0x0e /* Interrupt mask set/clear register */ 76#define IMSC_MASK_ALL 0x7ff /* Mask all interrupts */ 77 78#define UART_RIS 0x0f /* Raw interrupt status register */ 79#define UART_RXREADY (1 << 4) /* RX buffer full */ 80#define UART_TXEMPTY (1 << 5) /* TX buffer empty */ |
81#define RIS_RTIM (1 << 6) /* Receive timeout */ |
|
81#define RIS_FE (1 << 7) /* Framing error interrupt status */ 82#define RIS_PE (1 << 8) /* Parity error interrupt status */ 83#define RIS_BE (1 << 9) /* Break error interrupt status */ 84#define RIS_OE (1 << 10) /* Overrun interrupt status */ 85 86#define UART_MIS 0x10 /* Masked interrupt status register */ 87#define UART_ICR 0x11 /* Interrupt clear register */ 88 --- 184 unchanged lines hidden (view full) --- 273 .uc_range = 0x48, 274 .uc_rclk = 0 275}; 276 277static int 278uart_pl011_bus_attach(struct uart_softc *sc) 279{ 280 struct uart_bas *bas; | 82#define RIS_FE (1 << 7) /* Framing error interrupt status */ 83#define RIS_PE (1 << 8) /* Parity error interrupt status */ 84#define RIS_BE (1 << 9) /* Break error interrupt status */ 85#define RIS_OE (1 << 10) /* Overrun interrupt status */ 86 87#define UART_MIS 0x10 /* Masked interrupt status register */ 88#define UART_ICR 0x11 /* Interrupt clear register */ 89 --- 184 unchanged lines hidden (view full) --- 274 .uc_range = 0x48, 275 .uc_rclk = 0 276}; 277 278static int 279uart_pl011_bus_attach(struct uart_softc *sc) 280{ 281 struct uart_bas *bas; |
282 int reg; |
|
281 282 bas = &sc->sc_bas; | 283 284 bas = &sc->sc_bas; |
283 /* Enable RX & TX interrupts */ 284 __uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY)); 285 /* Clear RX & TX interrupts */ | 285 286 /* Enable interrupts */ 287 reg = (UART_RXREADY | RIS_RTIM | UART_TXEMPTY); 288 __uart_setreg(bas, UART_IMSC, reg); 289 290 /* Clear interrupts */ |
286 __uart_setreg(bas, UART_ICR, IMSC_MASK_ALL); 287 288 return (0); 289} 290 291static int 292uart_pl011_bus_detach(struct uart_softc *sc) 293{ --- 38 unchanged lines hidden (view full) --- 332 333 return (error); 334} 335 336static int 337uart_pl011_bus_ipend(struct uart_softc *sc) 338{ 339 struct uart_bas *bas; | 291 __uart_setreg(bas, UART_ICR, IMSC_MASK_ALL); 292 293 return (0); 294} 295 296static int 297uart_pl011_bus_detach(struct uart_softc *sc) 298{ --- 38 unchanged lines hidden (view full) --- 337 338 return (error); 339} 340 341static int 342uart_pl011_bus_ipend(struct uart_softc *sc) 343{ 344 struct uart_bas *bas; |
340 int ipend; | |
341 uint32_t ints; | 345 uint32_t ints; |
346 int ipend; 347 int reg; |
|
342 343 bas = &sc->sc_bas; 344 uart_lock(sc->sc_hwmtx); 345 ints = __uart_getreg(bas, UART_MIS); 346 ipend = 0; 347 | 348 349 bas = &sc->sc_bas; 350 uart_lock(sc->sc_hwmtx); 351 ints = __uart_getreg(bas, UART_MIS); 352 ipend = 0; 353 |
348 if (ints & UART_RXREADY) | 354 if (ints & (UART_RXREADY | RIS_RTIM)) |
349 ipend |= SER_INT_RXREADY; 350 if (ints & RIS_BE) 351 ipend |= SER_INT_BREAK; 352 if (ints & RIS_OE) 353 ipend |= SER_INT_OVERRUN; 354 if (ints & UART_TXEMPTY) { 355 if (sc->sc_txbusy) 356 ipend |= SER_INT_TXIDLE; 357 | 355 ipend |= SER_INT_RXREADY; 356 if (ints & RIS_BE) 357 ipend |= SER_INT_BREAK; 358 if (ints & RIS_OE) 359 ipend |= SER_INT_OVERRUN; 360 if (ints & UART_TXEMPTY) { 361 if (sc->sc_txbusy) 362 ipend |= SER_INT_TXIDLE; 363 |
358 __uart_setreg(bas, UART_IMSC, UART_RXREADY); | 364 /* Disable TX interrupt */ 365 reg = __uart_getreg(bas, UART_IMSC); 366 reg &= ~(UART_TXEMPTY); 367 __uart_setreg(bas, UART_IMSC, reg); |
359 } 360 361 uart_unlock(sc->sc_hwmtx); 362 363 return (ipend); 364} 365 366static int --- 19 unchanged lines hidden (view full) --- 386 387 return (0); 388} 389 390static int 391uart_pl011_bus_receive(struct uart_softc *sc) 392{ 393 struct uart_bas *bas; | 368 } 369 370 uart_unlock(sc->sc_hwmtx); 371 372 return (ipend); 373} 374 375static int --- 19 unchanged lines hidden (view full) --- 395 396 return (0); 397} 398 399static int 400uart_pl011_bus_receive(struct uart_softc *sc) 401{ 402 struct uart_bas *bas; |
394 int rx; | |
395 uint32_t ints, xc; | 403 uint32_t ints, xc; |
404 int rx; |
|
396 397 bas = &sc->sc_bas; 398 uart_lock(sc->sc_hwmtx); 399 400 ints = __uart_getreg(bas, UART_MIS); | 405 406 bas = &sc->sc_bas; 407 uart_lock(sc->sc_hwmtx); 408 409 ints = __uart_getreg(bas, UART_MIS); |
401 while (ints & UART_RXREADY) { | 410 while (ints & (UART_RXREADY | RIS_RTIM)) { |
402 if (uart_rx_full(sc)) { 403 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 404 break; 405 } 406 xc = __uart_getreg(bas, UART_DR); 407 rx = xc & 0xff; 408 409 if (xc & DR_FE) 410 rx |= UART_STAT_FRAMERR; 411 if (xc & DR_PE) 412 rx |= UART_STAT_PARERR; 413 | 411 if (uart_rx_full(sc)) { 412 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 413 break; 414 } 415 xc = __uart_getreg(bas, UART_DR); 416 rx = xc & 0xff; 417 418 if (xc & DR_FE) 419 rx |= UART_STAT_FRAMERR; 420 if (xc & DR_PE) 421 rx |= UART_STAT_PARERR; 422 |
414 __uart_setreg(bas, UART_ICR, UART_RXREADY); | 423 __uart_setreg(bas, UART_ICR, (UART_RXREADY | RIS_RTIM)); |
415 416 uart_rx_put(sc, rx); 417 ints = __uart_getreg(bas, UART_MIS); 418 } 419 420 uart_unlock(sc->sc_hwmtx); 421 422 return (0); --- 5 unchanged lines hidden (view full) --- 428 429 return (0); 430} 431 432static int 433uart_pl011_bus_transmit(struct uart_softc *sc) 434{ 435 struct uart_bas *bas; | 424 425 uart_rx_put(sc, rx); 426 ints = __uart_getreg(bas, UART_MIS); 427 } 428 429 uart_unlock(sc->sc_hwmtx); 430 431 return (0); --- 5 unchanged lines hidden (view full) --- 437 438 return (0); 439} 440 441static int 442uart_pl011_bus_transmit(struct uart_softc *sc) 443{ 444 struct uart_bas *bas; |
445 int reg; |
|
436 int i; 437 438 bas = &sc->sc_bas; 439 uart_lock(sc->sc_hwmtx); 440 441 for (i = 0; i < sc->sc_txdatasz; i++) { 442 __uart_setreg(bas, UART_DR, sc->sc_txbuf[i]); 443 uart_barrier(bas); 444 } 445 sc->sc_txbusy = 1; | 446 int i; 447 448 bas = &sc->sc_bas; 449 uart_lock(sc->sc_hwmtx); 450 451 for (i = 0; i < sc->sc_txdatasz; i++) { 452 __uart_setreg(bas, UART_DR, sc->sc_txbuf[i]); 453 uart_barrier(bas); 454 } 455 sc->sc_txbusy = 1; |
446 __uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY)); | 456 457 /* Enable TX interrupt */ 458 reg = __uart_getreg(bas, UART_IMSC); 459 reg |= (UART_TXEMPTY); 460 __uart_setreg(bas, UART_IMSC, reg); 461 |
447 uart_unlock(sc->sc_hwmtx); 448 449 return (0); 450} 451 452static void 453uart_pl011_bus_grab(struct uart_softc *sc) 454{ --- 20 unchanged lines hidden --- | 462 uart_unlock(sc->sc_hwmtx); 463 464 return (0); 465} 466 467static void 468uart_pl011_bus_grab(struct uart_softc *sc) 469{ --- 20 unchanged lines hidden --- |