summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJoshua Stein <jcs@cvs.openbsd.org>2020-08-14 18:14:12 +0000
committerJoshua Stein <jcs@cvs.openbsd.org>2020-08-14 18:14:12 +0000
commit271dc6fa42baca3befad7033990b1d6baa531f35 (patch)
treee7d80fd83191c7265cd9ce1a7303b51404c1d85d /sys
parent7292e1937bb24bc129dee724f17f70ad3d3c5a30 (diff)
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
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/com.c21
-rw-r--r--sys/dev/ic/comreg.h7
-rw-r--r--sys/dev/ic/comvar.h3
-rw-r--r--sys/dev/pci/puc.c40
-rw-r--r--sys/dev/pci/pucdata.c10
-rw-r--r--sys/dev/pci/pucvar.h9
-rw-r--r--sys/dev/puc/com_puc.c5
7 files changed, 79 insertions, 16 deletions
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 <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pucvar.h>
+#include <dev/pci/pcidevs.h>
#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
@@ -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);
}