From c44af5cbeeb50a931560fd43f229aa81fb00165c Mon Sep 17 00:00:00 2001 From: uaa Date: Tue, 11 Jan 2022 11:51:14 +0000 Subject: [PATCH] add Synopsys Degisnware UART (dw-apb-uart) support To fix Allwinner H6's UART problem, need to add dw-apb-uart special code. ok kettenis@ --- sys/dev/fdt/com_fdt.c | 8 ++++---- sys/dev/ic/com.c | 33 +++++++++++++++++++++++++++++---- sys/dev/ic/comreg.h | 5 ++++- sys/dev/ic/comvar.h | 3 ++- sys/dev/ic/ns16550reg.h | 8 +++++++- 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/sys/dev/fdt/com_fdt.c b/sys/dev/fdt/com_fdt.c index 5ee3b6d3c0c..473658a3957 100644 --- a/sys/dev/fdt/com_fdt.c +++ b/sys/dev/fdt/com_fdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_fdt.c,v 1.6 2021/10/24 17:52:26 mpi Exp $ */ +/* $OpenBSD: com_fdt.c,v 1.7 2022/01/11 11:51:14 uaa Exp $ */ /* * Copyright (c) 2016 Patrick Wildt * @@ -33,8 +33,6 @@ #include #include -#define com_usr 31 /* Synopsys DesignWare UART */ - int com_fdt_match(struct device *, void *, void *); void com_fdt_attach(struct device *, struct device *, void *); int com_fdt_intr_designware(void *); @@ -144,8 +142,10 @@ com_fdt_attach(struct device *parent, struct device *self, void *aux) sc->sc_reg_shift = OF_getpropint(faa->fa_node, "reg-shift", shift); if (OF_is_compatible(faa->fa_node, "snps,dw-apb-uart") || - OF_is_compatible(faa->fa_node, "marvell,armada-38x-uart")) + OF_is_compatible(faa->fa_node, "marvell,armada-38x-uart")) { + sc->sc_uarttype = COM_UART_DW_APB; intr = com_fdt_intr_designware; + } if (OF_is_compatible(faa->fa_node, "ti,omap3-uart") || OF_is_compatible(faa->fa_node, "ti,omap4-uart")) diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index e1aa05e61cb..a5ecfdef514 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com.c,v 1.174 2021/05/06 20:35:21 kettenis Exp $ */ +/* $OpenBSD: com.c,v 1.175 2022/01/11 11:51:14 uaa Exp $ */ /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */ /* @@ -1300,7 +1300,8 @@ void com_attach_subr(struct com_softc *sc) { int probe = 0; - u_int8_t lcr; + u_int8_t lcr, fifo; + u_int32_t cpr; sc->sc_ier = 0; /* disable interrupts */ @@ -1480,6 +1481,27 @@ com_attach_subr(struct com_softc *sc) SET(sc->sc_hwflags, COM_HW_FIFO); sc->sc_fifolen = 256; break; + case COM_UART_DW_APB: + printf(": dw16550"); + SET(sc->sc_hwflags, COM_HW_FIFO); + cpr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, com_cpr << 2); + sc->sc_fifolen = CPR_FIFO_MODE(cpr) * 16; + if (sc->sc_fifolen) { + printf(", %d byte fifo\n", sc->sc_fifolen); + } else { + printf("\n"); + /* + * The DW-APB configuration on the Allwinner H6 SoC + * does not provide the CPR register and will be + * detected as having no FIFO. But it does have a + * 256-byte FIFO and with the FIFO disabled the + * LSR_RXRDY bit remains set even if the input + * buffer is empty. As a workaround, treat as a + * 1-byte FIFO. + */ + sc->sc_fifolen = 1; + } + break; default: panic("comattach: bad fifo type"); } @@ -1496,10 +1518,13 @@ com_attach_subr(struct com_softc *sc) } /* clear and disable fifo */ - com_write_reg(sc, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST); + /* DW-APB UART cannot turn off FIFO here (ddb will not work) */ + fifo = (sc->sc_uarttype == COM_UART_DW_APB) ? + (FIFO_ENABLE | FIFO_TRIGGER_1) : 0; + com_write_reg(sc, com_fifo, fifo | FIFO_RCV_RST | FIFO_XMT_RST); if (ISSET(com_read_reg(sc, com_lsr), LSR_RXRDY)) (void)com_read_reg(sc, com_data); - com_write_reg(sc, com_fifo, 0); + com_write_reg(sc, com_fifo, fifo); sc->sc_mcr = 0; com_write_reg(sc, com_mcr, sc->sc_mcr); diff --git a/sys/dev/ic/comreg.h b/sys/dev/ic/comreg.h index 627f3828389..c49cbbea623 100644 --- a/sys/dev/ic/comreg.h +++ b/sys/dev/ic/comreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: comreg.h,v 1.20 2020/08/14 18:14:11 jcs Exp $ */ +/* $OpenBSD: comreg.h,v 1.21 2022/01/11 11:51:14 uaa Exp $ */ /* $NetBSD: comreg.h,v 1.8 1996/02/05 23:01:50 scottr Exp $ */ /* @@ -180,6 +180,9 @@ #define ISR_TXPL 0x08 /* negative transmit data polarity */ #define ISR_RXPL 0x10 /* negative receive data polarity */ +/* component parameter register (Synopsys DesignWare APB UART) */ +#define CPR_FIFO_MODE(x) (((x) >> 16) & 0xff) + #define COM_NPORTS 8 /* Exar XR17V35X */ diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h index c1a15f5d07f..8641a97de65 100644 --- a/sys/dev/ic/comvar.h +++ b/sys/dev/ic/comvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: comvar.h,v 1.58 2020/08/14 18:14:11 jcs Exp $ */ +/* $OpenBSD: comvar.h,v 1.59 2022/01/11 11:51:14 uaa Exp $ */ /* $NetBSD: comvar.h,v 1.5 1996/05/05 19:50:47 christos Exp $ */ /* @@ -104,6 +104,7 @@ struct com_softc { #define COM_UART_XR16850 0x10 /* 128 byte fifo */ #define COM_UART_OX16C950 0x11 /* 128 byte fifo */ #define COM_UART_XR17V35X 0x12 /* 256 byte fifo */ +#define COM_UART_DW_APB 0x13 /* configurable */ u_char sc_hwflags; #define COM_HW_NOIEN 0x01 diff --git a/sys/dev/ic/ns16550reg.h b/sys/dev/ic/ns16550reg.h index 5db1a27473b..d9f2d58f5ef 100644 --- a/sys/dev/ic/ns16550reg.h +++ b/sys/dev/ic/ns16550reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ns16550reg.h,v 1.5 2003/06/02 23:28:02 millert Exp $ */ +/* $OpenBSD: ns16550reg.h,v 1.6 2022/01/11 11:51:14 uaa Exp $ */ /* $NetBSD: ns16550reg.h,v 1.4 1994/10/27 04:18:43 cgd Exp $ */ /*- @@ -50,3 +50,9 @@ #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) */ + +/* + * Synopsys DesignWare APB UART additional registers + */ +#define com_usr 31 /* UART status register (R) */ +#define com_cpr 61 /* component parameter register (R) */ -- 2.20.1