Fix bugs exposed by the recent enabling of FIFOs in the pl011 uart. These

have been in the code all along, but were masked by having a fifo depth of
one byte at the hardware level, so everything kinda worked by accident.

The hardware interrupts when the TX fifo is half empty, so set
sc->sc_txfifosz to 8 bytes (half the hardware fifo size) to match.  This
eliminates dropped characters on output.

Restructure the read loop to consume all the bytes in the fifo by using
the "rx fifo empty" bit of the flags register rather than the "rx ready"
bit of the interrupt status register.  The rx-ready interrupt is cleared
when the number of bytes in the fifo fall below the interrupt trigger
level, leaving the fifo half full every time receive routine was called.
Now it loops until the fifo is completely empty every time (including
when the function is called due to a receive timeout as well as for
fifo-full).
This commit is contained in:
Ian Lepore 2017-03-04 21:47:43 +00:00
parent 8844cec8f3
commit 752e8c08fb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=314681

View file

@ -419,7 +419,7 @@ uart_pl011_bus_probe(struct uart_softc *sc)
device_set_desc(sc->sc_dev, "PrimeCell UART (PL011)");
sc->sc_rxfifosz = 16;
sc->sc_txfifosz = 16;
sc->sc_txfifosz = 8;
return (0);
}
@ -434,8 +434,10 @@ uart_pl011_bus_receive(struct uart_softc *sc)
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
ints = __uart_getreg(bas, UART_MIS);
while (ints & (UART_RXREADY | RIS_RTIM)) {
for (;;) {
ints = __uart_getreg(bas, UART_FR);
if (ints & FR_RXFE)
break;
if (uart_rx_full(sc)) {
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
break;
@ -450,7 +452,6 @@ uart_pl011_bus_receive(struct uart_softc *sc)
rx |= UART_STAT_PARERR;
uart_rx_put(sc, rx);
ints = __uart_getreg(bas, UART_MIS);
}
uart_unlock(sc->sc_hwmtx);