> Date: Wed, 3 Aug 2016 22:36:02 +0200 > From: Patrick Wildt <patr...@blueri.se> > > Hi, > > the Synopsys Designware UART, which is used on a bunch of SoCs, is > mostly compatible to com(4). Currently we use sxiuart, a driver based > on another driver, modified to work on sunxi. I would like to replace > sxiuart with com(4). This diff disables sxiuart and implements the > Allwinner and Synopsys specific code in the existing com(4) wrapper > for OMAP. In a follow up diff we can remove sxiuart completely. Also, > we might want to move it to some other folder and/or rename it. That > should be part of a follow up diff. > > There's only a slight twist: The controller has a busy interrupt we > need to handle. Otherwise we will get flooded with interrupts. > mglocker@ is currently experiencing that issue with the sxiuart driver > as well. This diff also implements this busy indicator in com(4). > > ok? Comments?
Documentation for the Designware IP can be found at: http://read.pudn.com/downloads163/doc/741013/dw_apb_uart_db.pdf I don't think the com(4) part of the diff is quite right. This busy indicator feature seems to be specific to the Designware core. I can't find the original NS16750 datasheet (was there ever one?), but it isn't present on any of the true 16750 clones. So I think that instead of adding a COM_HW_IIR_BUSY flag, we should add a COM_UART_DWAPB type and use that to signal the presence of this feature. The comments should certainly not mention the NS16750. But I'd also like to look at the documentation to see if there way to work around this issue. It seems that the interrupt handlers is simply waiting for the FIFO to drain. It would really surprise me if that is really necessary. > --- a/sys/dev/ic/com.c > +++ b/sys/dev/ic/com.c > @@ -1219,12 +1219,30 @@ comintr(void *arg) > bus_space_tag_t iot = sc->sc_iot; > bus_space_handle_t ioh = sc->sc_ioh; > struct tty *tp; > - u_char lsr, data, msr, delta; > + u_char iir, lsr, data, msr, delta; > + int timeout; > + > + iir = bus_space_read_1(iot, ioh, com_iir); > + > + /* Handle ns16750-specific busy interrupt. */ > + if (ISSET(sc->sc_hwflags, COM_HW_IIR_BUSY) && > + (iir & IIR_BUSY) == IIR_BUSY) { > + for (timeout = 10000; > + (bus_space_read_1(iot, ioh, com_usr) & 0x1) != 0; > + timeout--) > + if (timeout <= 0) { > + printf("%s: timeout while waiting for BUSY " > + "interrupt acknowledge\n", > + sc->sc_dev.dv_xname); > + return (0); > + } > + iir = bus_space_read_1(iot, ioh, com_iir); > + } > > if (!sc->sc_tty) > return (0); /* Can't do squat. */ > > - if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND)) > + if (ISSET(iir, IIR_NOPEND)) > return (0); > > tp = sc->sc_tty; > diff --git a/sys/dev/ic/comreg.h b/sys/dev/ic/comreg.h > index 6084698..d2e52a0 100644 > --- a/sys/dev/ic/comreg.h > +++ b/sys/dev/ic/comreg.h > @@ -82,6 +82,7 @@ > #define IIR_MLSC 0x0 /* Modem status */ > #define IIR_NOPEND 0x1 /* No pending interrupts */ > #define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ > +#define IIR_BUSY 0x7 /* NS16750: Busy indicator */ > > /* fifo control register */ > #define FIFO_ENABLE 0x01 /* Turn the FIFO on */ > diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h > index 893ffde..5f7e5fe 100644 > --- a/sys/dev/ic/comvar.h > +++ b/sys/dev/ic/comvar.h > @@ -106,6 +106,7 @@ struct com_softc { > u_char sc_hwflags; > #define COM_HW_NOIEN 0x01 > #define COM_HW_FIFO 0x02 > +#define COM_HW_IIR_BUSY 0x04 > #define COM_HW_SIR 0x20 > #define COM_HW_CONSOLE 0x40 > #define COM_HW_KGDB 0x80 > @@ -117,7 +118,7 @@ struct com_softc { > #define COM_SW_PPS 0x10 > #define COM_SW_DEAD 0x20 > int sc_fifolen; > - u_char sc_msr, sc_mcr, sc_lcr, sc_ier; > + u_char sc_msr, sc_mcr, sc_lcr, sc_ier, sc_iir; > u_char sc_dtr; > > u_char sc_cua; > diff --git a/sys/dev/ic/ns16550reg.h b/sys/dev/ic/ns16550reg.h > index 5db1a27..d8eb8b3 100644 > --- a/sys/dev/ic/ns16550reg.h > +++ b/sys/dev/ic/ns16550reg.h > @@ -50,3 +50,4 @@ > #define com_lsr 5 /* line status register (R/W) */ > #define com_msr 6 /* modem status register (R/W) */ > #define com_scratch 7 /* scratch register (R/W) */ > +#define com_usr 31 /* NS16750: status register (R) */ > >