From 271dc6fa42baca3befad7033990b1d6baa531f35 Mon Sep 17 00:00:00 2001 From: Joshua Stein Date: Fri, 14 Aug 2020 18:14:12 +0000 Subject: Re-commit Exar XR17V35x serial port support previously backed out: The Exar XR17V354 has 4 ports that have a 256-byte FIFO, use a frequency of 125Mhz, and have a unique sleep register. A custom interrupt handler is setup in puc for these ports so it can check a register which reports which ports triggered the interrupt, rather than having to run comintr for every port every time. To avoid probing for these ports in com_attach_subr which requires access to registers that may be reserved on certain platforms, pass the sc_uarttype from com_puc_attach since the port type is already known based on the puc device vendor/id. Input from kettenis, tested in snaps --- sys/dev/ic/com.c | 21 ++++++++++++++++++--- sys/dev/ic/comreg.h | 7 ++++++- sys/dev/ic/comvar.h | 3 ++- sys/dev/pci/puc.c | 40 +++++++++++++++++++++++++++++++++++++--- sys/dev/pci/pucdata.c | 10 +++++----- sys/dev/pci/pucvar.h | 9 +++++++-- sys/dev/puc/com_puc.c | 5 ++++- 7 files changed, 79 insertions(+), 16 deletions(-) (limited to 'sys') diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index 0659a9d0600..aa67cb359ec 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com.c,v 1.172 2020/03/09 04:38:46 yasuoka Exp $ */ +/* $OpenBSD: com.c,v 1.173 2020/08/14 18:14:11 jcs Exp $ */ /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */ /* @@ -306,6 +306,9 @@ comopen(dev_t dev, int flag, int mode, struct proc *p) case COM_UART_TI16750: com_write_reg(sc, com_ier, 0); break; + case COM_UART_XR17V35X: + com_write_reg(sc, UART_EXAR_SLEEP, 0); + break; } } @@ -498,6 +501,9 @@ compwroff(struct com_softc *sc) case COM_UART_TI16750: com_write_reg(sc, com_ier, IER_SLEEP); break; + case COM_UART_XR17V35X: + com_write_reg(sc, UART_EXAR_SLEEP, 0xff); + break; } } } @@ -533,6 +539,9 @@ com_resume(struct com_softc *sc) case COM_UART_TI16750: com_write_reg(sc, com_ier, 0); break; + case COM_UART_XR17V35X: + com_write_reg(sc, UART_EXAR_SLEEP, 0); + break; } } @@ -919,7 +928,7 @@ comstart(struct tty *tp) } if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { - u_char buffer[128]; /* largest fifo */ + u_char buffer[256]; /* largest fifo */ int i, n; n = q_to_b(&tp->t_outq, buffer, @@ -1466,6 +1475,11 @@ com_attach_subr(struct com_softc *sc) break; #endif #endif + case COM_UART_XR17V35X: + printf(": xr17v35x, 256 byte fifo\n"); + SET(sc->sc_hwflags, COM_HW_FIFO); + sc->sc_fifolen = 256; + break; default: panic("comattach: bad fifo type"); } @@ -1473,7 +1487,8 @@ com_attach_subr(struct com_softc *sc) #ifdef COM_CONSOLE if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) #endif - com_fifo_probe(sc); + if (sc->sc_fifolen < 256) + com_fifo_probe(sc); if (sc->sc_fifolen == 0) { CLR(sc->sc_hwflags, COM_HW_FIFO); diff --git a/sys/dev/ic/comreg.h b/sys/dev/ic/comreg.h index 21ea12b4cd9..627f3828389 100644 --- a/sys/dev/ic/comreg.h +++ b/sys/dev/ic/comreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: comreg.h,v 1.19 2018/05/02 13:20:12 kettenis Exp $ */ +/* $OpenBSD: comreg.h,v 1.20 2020/08/14 18:14:11 jcs Exp $ */ /* $NetBSD: comreg.h,v 1.8 1996/02/05 23:01:50 scottr Exp $ */ /* @@ -182,6 +182,11 @@ #define COM_NPORTS 8 +/* Exar XR17V35X */ +#define UART_EXAR_INT0 0x80 +#define UART_EXAR_SLEEP 0x8b /* Sleep mode */ +#define UART_EXAR_DVID 0x8d /* Device identification */ + /* * WARNING: Serial console is assumed to be at COM1 address */ diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h index 6598cde8bb4..c1a15f5d07f 100644 --- a/sys/dev/ic/comvar.h +++ b/sys/dev/ic/comvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: comvar.h,v 1.57 2018/05/14 19:25:54 kettenis Exp $ */ +/* $OpenBSD: comvar.h,v 1.58 2020/08/14 18:14:11 jcs Exp $ */ /* $NetBSD: comvar.h,v 1.5 1996/05/05 19:50:47 christos Exp $ */ /* @@ -103,6 +103,7 @@ struct com_softc { #define COM_UART_ST16C654 0x08 /* 64 bytes fifo */ #define COM_UART_XR16850 0x10 /* 128 byte fifo */ #define COM_UART_OX16C950 0x11 /* 128 byte fifo */ +#define COM_UART_XR17V35X 0x12 /* 256 byte fifo */ u_char sc_hwflags; #define COM_HW_NOIEN 0x01 diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c index 2123750945a..df680dae7af 100644 --- a/sys/dev/pci/puc.c +++ b/sys/dev/pci/puc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: puc.c,v 1.29 2020/03/02 19:45:42 patrick Exp $ */ +/* $OpenBSD: puc.c,v 1.30 2020/08/14 18:14:11 jcs Exp $ */ /* $NetBSD: puc.c,v 1.3 1999/02/06 06:29:54 cgd Exp $ */ /* @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -80,6 +81,7 @@ int puc_pci_detach(struct device *, int); const char *puc_pci_intr_string(struct puc_attach_args *); void *puc_pci_intr_establish(struct puc_attach_args *, int, int (*)(void *), void *, char *); +int puc_pci_xr17v35x_intr(void *arg); struct cfattach puc_pci_ca = { sizeof(struct puc_pci_softc), puc_pci_match, @@ -127,7 +129,17 @@ puc_pci_intr_establish(struct puc_attach_args *paa, int type, { struct puc_pci_softc *sc = paa->puc; struct puc_softc *psc = &sc->sc_psc; - + + if (psc->sc_xr17v35x) { + psc->sc_ports[paa->port].real_intrhand = func; + psc->sc_ports[paa->port].real_intrhand_arg = arg; + if (paa->port == 0) + psc->sc_ports[paa->port].intrhand = + pci_intr_establish(sc->pc, sc->ih, type, + puc_pci_xr17v35x_intr, sc, name); + return (psc->sc_ports[paa->port].real_intrhand); + } + psc->sc_ports[paa->port].intrhand = pci_intr_establish(sc->pc, sc->ih, type, func, arg, name); @@ -148,6 +160,10 @@ puc_pci_attach(struct device *parent, struct device *self, void *aux) sc->sc_desc = puc_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), PCI_VENDOR(subsys), PCI_PRODUCT(subsys)); + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_EXAR && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_EXAR_XR17V354) + sc->sc_xr17v35x = 1; + puc_print_ports(sc->sc_desc); for (i = 0; i < PUC_NBARS; i++) { @@ -328,7 +344,6 @@ puc_find_description(u_int16_t vend, u_int16_t prod, const char * puc_port_type_name(int type) { - if (PUC_IS_COM(type)) return "com"; if (PUC_IS_LPT(type)) @@ -357,3 +372,22 @@ puc_print_ports(const struct puc_device_description *desc) } printf("\n"); } + +int +puc_pci_xr17v35x_intr(void *arg) +{ + struct puc_pci_softc *sc = arg; + struct puc_softc *psc = &sc->sc_psc; + int ports, i; + + ports = bus_space_read_1(psc->sc_bar_mappings[0].t, + psc->sc_bar_mappings[0].h, UART_EXAR_INT0); + + for (i = 0; i < 8; i++) { + if ((ports & (1 << i)) && psc->sc_ports[i].real_intrhand) + (*(psc->sc_ports[i].real_intrhand))( + psc->sc_ports[i].real_intrhand_arg); + } + + return (1); +} diff --git a/sys/dev/pci/pucdata.c b/sys/dev/pci/pucdata.c index 0011d0ac2f7..51a41fa0e43 100644 --- a/sys/dev/pci/pucdata.c +++ b/sys/dev/pci/pucdata.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pucdata.c,v 1.111 2020/01/05 01:07:59 jsg Exp $ */ +/* $OpenBSD: pucdata.c,v 1.112 2020/08/14 18:14:11 jcs Exp $ */ /* $NetBSD: pucdata.c,v 1.6 1999/07/03 05:55:23 cgd Exp $ */ /* @@ -2083,10 +2083,10 @@ const struct puc_device_description puc_devs[] = { { PCI_VENDOR_EXAR, PCI_PRODUCT_EXAR_XR17V354, 0, 0 }, { 0xffff, 0xffff, 0, 0 }, { - { PUC_PORT_COM_MUL8, 0x10, 0x0000 }, - { PUC_PORT_COM_MUL8, 0x10, 0x0400 }, - { PUC_PORT_COM_MUL8, 0x10, 0x0800 }, - { PUC_PORT_COM_MUL8, 0x10, 0x0C00 }, + { PUC_PORT_COM_XR17V35X, 0x10, 0x0000 }, + { PUC_PORT_COM_XR17V35X, 0x10, 0x0400 }, + { PUC_PORT_COM_XR17V35X, 0x10, 0x0800 }, + { PUC_PORT_COM_XR17V35X, 0x10, 0x0C00 }, }, }, diff --git a/sys/dev/pci/pucvar.h b/sys/dev/pci/pucvar.h index da3d0784d9b..0756dd27650 100644 --- a/sys/dev/pci/pucvar.h +++ b/sys/dev/pci/pucvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pucvar.h,v 1.16 2018/05/02 19:11:01 phessler Exp $ */ +/* $OpenBSD: pucvar.h,v 1.17 2020/08/14 18:14:11 jcs Exp $ */ /* $NetBSD: pucvar.h,v 1.2 1999/02/06 06:29:54 cgd Exp $ */ /* @@ -60,7 +60,7 @@ struct puc_port_type { PUC_PORT_COM_MUL8, PUC_PORT_COM_MUL10, PUC_PORT_COM_MUL128, - PUC_PORT_COM_125MHZ, + PUC_PORT_COM_XR17V35X, } type; u_int32_t freq; }; @@ -72,6 +72,7 @@ static const struct puc_port_type puc_port_types[] = { { PUC_PORT_COM_MUL8, COM_FREQ * 8 }, { PUC_PORT_COM_MUL10, COM_FREQ * 10 }, { PUC_PORT_COM_MUL128, COM_FREQ * 128 }, + { PUC_PORT_COM_XR17V35X, 125000000 }, }; #define PUC_IS_LPT(type) ((type) == PUC_PORT_LPT) @@ -117,7 +118,11 @@ struct puc_softc { struct device *dev; /* filled in by port attachments */ void *intrhand; + int (*real_intrhand)(void *); + void *real_intrhand_arg; } sc_ports[PUC_MAX_PORTS]; + + int sc_xr17v35x; }; const struct puc_device_description * diff --git a/sys/dev/puc/com_puc.c b/sys/dev/puc/com_puc.c index 33a434fba23..a398427a83f 100644 --- a/sys/dev/puc/com_puc.c +++ b/sys/dev/puc/com_puc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_puc.c,v 1.24 2018/04/15 00:10:59 jcs Exp $ */ +/* $OpenBSD: com_puc.c,v 1.25 2020/08/14 18:14:11 jcs Exp $ */ /* * Copyright (c) 1997 - 1999, Jason Downs. All rights reserved. @@ -109,6 +109,9 @@ com_puc_attach(parent, self, aux) break; } + if (pa->type == PUC_PORT_COM_XR17V35X) + sc->sc_uarttype = COM_UART_XR17V35X; + com_attach_subr(sc); } -- cgit v1.2.3