Add support for UART found in the Ingenic XBurst system on chips.

These CPUs has non-standard UART enable bit hidden in the UART FIFO
Control Register.

Sponsored by:	DARPA, AFRL
This commit is contained in:
Ruslan Bukin 2016-11-17 14:41:22 +00:00
parent 310dc5a403
commit b192bae67e
2 changed files with 40 additions and 6 deletions

View File

@ -156,6 +156,9 @@
#define FIFO_XMT_RST FCR_XMT_RST #define FIFO_XMT_RST FCR_XMT_RST
#define FCR_DMA 0x08 #define FCR_DMA 0x08
#define FIFO_DMA_MODE FCR_DMA #define FIFO_DMA_MODE FCR_DMA
#ifdef CPU_XBURST
#define FCR_UART_ON 0x10
#endif
#define FCR_RX_LOW 0x00 #define FCR_RX_LOW 0x00
#define FIFO_RX_LOW FCR_RX_LOW #define FIFO_RX_LOW FCR_RX_LOW
#define FCR_RX_MEDL 0x40 #define FCR_RX_MEDL 0x40

View File

@ -198,6 +198,9 @@ ns8250_flush(struct uart_bas *bas, int what)
uint8_t fcr; uint8_t fcr;
fcr = FCR_ENABLE; fcr = FCR_ENABLE;
#ifdef CPU_XBURST
fcr |= FCR_UART_ON;
#endif
if (what & UART_FLUSH_TRANSMITTER) if (what & UART_FLUSH_TRANSMITTER)
fcr |= FCR_XMT_RST; fcr |= FCR_XMT_RST;
if (what & UART_FLUSH_RECEIVER) if (what & UART_FLUSH_RECEIVER)
@ -268,6 +271,10 @@ ns8250_probe(struct uart_bas *bas)
{ {
u_char val; u_char val;
#ifdef CPU_XBURST
uart_setreg(bas, REG_FCR, FCR_UART_ON);
#endif
/* Check known 0 bits that don't depend on DLAB. */ /* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR); val = uart_getreg(bas, REG_IIR);
if (val & 0x30) if (val & 0x30)
@ -289,7 +296,7 @@ static void
ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int parity) int parity)
{ {
u_char ier; u_char ier, val;
if (bas->rclk == 0) if (bas->rclk == 0)
bas->rclk = DEFAULT_RCLK; bas->rclk = DEFAULT_RCLK;
@ -306,7 +313,11 @@ ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
uart_barrier(bas); uart_barrier(bas);
/* Disable the FIFO (if present). */ /* Disable the FIFO (if present). */
uart_setreg(bas, REG_FCR, 0); val = 0;
#ifdef CPU_XBURST
val = FCR_UART_ON;
#endif
uart_setreg(bas, REG_FCR, val);
uart_barrier(bas); uart_barrier(bas);
/* Set RTS & DTR. */ /* Set RTS & DTR. */
@ -461,6 +472,9 @@ ns8250_bus_attach(struct uart_softc *sc)
ns8250->mcr = uart_getreg(bas, REG_MCR); ns8250->mcr = uart_getreg(bas, REG_MCR);
ns8250->fcr = FCR_ENABLE; ns8250->fcr = FCR_ENABLE;
#ifdef CPU_XBURST
ns8250->fcr |= FCR_UART_ON;
#endif
if (!resource_int_value("uart", device_get_unit(sc->sc_dev), "flags", if (!resource_int_value("uart", device_get_unit(sc->sc_dev), "flags",
&ivar)) { &ivar)) {
if (UART_FLAGS_FCR_RX_LOW(ivar)) if (UART_FLAGS_FCR_RX_LOW(ivar))
@ -753,6 +767,7 @@ ns8250_bus_probe(struct uart_softc *sc)
struct uart_bas *bas; struct uart_bas *bas;
int count, delay, error, limit; int count, delay, error, limit;
uint8_t lsr, mcr, ier; uint8_t lsr, mcr, ier;
uint8_t val;
ns8250 = (struct ns8250_softc *)sc; ns8250 = (struct ns8250_softc *)sc;
bas = &sc->sc_bas; bas = &sc->sc_bas;
@ -786,7 +801,11 @@ ns8250_bus_probe(struct uart_softc *sc)
* done. Since this is the first time we enable the FIFOs, we reset * done. Since this is the first time we enable the FIFOs, we reset
* them. * them.
*/ */
uart_setreg(bas, REG_FCR, FCR_ENABLE); val = FCR_ENABLE;
#ifdef CPU_XBURST
val |= FCR_UART_ON;
#endif
uart_setreg(bas, REG_FCR, val);
uart_barrier(bas); uart_barrier(bas);
if (!(uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) { if (!(uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) {
/* /*
@ -800,7 +819,11 @@ ns8250_bus_probe(struct uart_softc *sc)
return (0); return (0);
} }
uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); val = FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST;
#ifdef CPU_XBURST
val |= FCR_UART_ON;
#endif
uart_setreg(bas, REG_FCR, val);
uart_barrier(bas); uart_barrier(bas);
count = 0; count = 0;
@ -810,7 +833,11 @@ ns8250_bus_probe(struct uart_softc *sc)
error = ns8250_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER); error = ns8250_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER);
if (error) { if (error) {
uart_setreg(bas, REG_MCR, mcr); uart_setreg(bas, REG_MCR, mcr);
uart_setreg(bas, REG_FCR, 0); val = 0;
#ifdef CPU_XBURST
val |= FCR_UART_ON;
#endif
uart_setreg(bas, REG_FCR, val);
uart_barrier(bas); uart_barrier(bas);
goto describe; goto describe;
} }
@ -840,7 +867,11 @@ ns8250_bus_probe(struct uart_softc *sc)
ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask;
uart_setreg(bas, REG_IER, ier); uart_setreg(bas, REG_IER, ier);
uart_setreg(bas, REG_MCR, mcr); uart_setreg(bas, REG_MCR, mcr);
uart_setreg(bas, REG_FCR, 0); val = 0;
#ifdef CPU_XBURST
val |= FCR_UART_ON;
#endif
uart_setreg(bas, REG_FCR, val);
uart_barrier(bas); uart_barrier(bas);
count = 0; count = 0;
goto describe; goto describe;