xref: /openbsd/sys/dev/pci/cy_pci.c (revision 8d2c75e4)
1*8d2c75e4Smpi /*	$OpenBSD: cy_pci.c,v 1.16 2022/03/11 18:00:45 mpi Exp $	*/
234879126Sart /*
334879126Sart  * Copyright (c) 1996 Timo Rossi.
434879126Sart  * All rights reserved.
534879126Sart  *
634879126Sart  * Redistribution and use in source and binary forms, with or without
734879126Sart  * modification, are permitted provided that the following conditions
834879126Sart  * are met:
934879126Sart  * 1. Redistributions of source code must retain the above copyright
1034879126Sart  *    notice, this list of conditions and the following disclaimer.
1134879126Sart  * 2. Redistributions in binary form must reproduce the above copyright
1234879126Sart  *    notice, this list of conditions and the following disclaimer in the
1334879126Sart  *    documentation and/or other materials provided with the distribution.
1434879126Sart  * 3. Neither the name of the author nor the names of contributors
1534879126Sart  *    may be used to endorse or promote products derived from this software
1634879126Sart  *    without specific prior written permission.
1734879126Sart  *
1834879126Sart  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1934879126Sart  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2034879126Sart  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2134879126Sart  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2234879126Sart  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2334879126Sart  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2434879126Sart  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2534879126Sart  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2634879126Sart  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2734879126Sart  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2834879126Sart  * SUCH DAMAGE.
2934879126Sart  */
30ded20a09Sderaadt 
31ded20a09Sderaadt /*
32efe22d86Ssmart  * cy_pci.c
33ded20a09Sderaadt  *
34ded20a09Sderaadt  * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
35ded20a09Sderaadt  * (currently not tested with Cyclom-32 cards)
36ded20a09Sderaadt  *
37ded20a09Sderaadt  * Timo Rossi, 1996
38ded20a09Sderaadt  */
39ded20a09Sderaadt 
40ded20a09Sderaadt #include <sys/param.h>
41ded20a09Sderaadt #include <sys/systm.h>
42efe22d86Ssmart #include <sys/device.h>
43efe22d86Ssmart 
44c0981ad2Sniklas #include <machine/bus.h>
45efe22d86Ssmart 
46ded20a09Sderaadt #include <dev/pci/pcivar.h>
47ded20a09Sderaadt #include <dev/pci/pcireg.h>
48ded20a09Sderaadt #include <dev/pci/pcidevs.h>
49ded20a09Sderaadt 
50ded20a09Sderaadt #include <dev/ic/cd1400reg.h>
51ded20a09Sderaadt #include <dev/ic/cyreg.h>
52ded20a09Sderaadt 
53c4071fd1Smillert int cy_pci_match(struct device *, void *, void *);
54c4071fd1Smillert void cy_pci_attach(struct device *, struct device *, void *);
55ded20a09Sderaadt 
5699f5af5aSart struct cy_pci_softc {
5799f5af5aSart 	struct cy_softc 	sc_cy;		/* real softc */
5899f5af5aSart 
5999f5af5aSart 	bus_space_tag_t		sc_iot;		/* PLX i/o tag */
6099f5af5aSart 	bus_space_handle_t	sc_ioh;		/* PLX i/o handle */
61ded20a09Sderaadt };
62ded20a09Sderaadt 
63*8d2c75e4Smpi const struct cfattach cy_pci_ca = {
6499f5af5aSart 	sizeof(struct cy_pci_softc), cy_pci_match, cy_pci_attach
6599f5af5aSart };
6699f5af5aSart 
6799f5af5aSart #define CY_PLX_9050_ICS_IENABLE		0x040
6899f5af5aSart #define CY_PLX_9050_ICS_LOCAL_IENABLE	0x001
6999f5af5aSart #define CY_PLX_9050_ICS_LOCAL_IPOLARITY	0x002
7099f5af5aSart #define CY_PLX_9060_ICS_IENABLE		0x100
7199f5af5aSart #define CY_PLX_9060_ICS_LOCAL_IENABLE	0x800
7299f5af5aSart 
736f90920fSjason const struct pci_matchid cy_pci_devices[] = {
746f90920fSjason 	{ PCI_VENDOR_CYCLADES, PCI_PRODUCT_CYCLADES_CYCLOMY_1 },
756f90920fSjason 	{ PCI_VENDOR_CYCLADES, PCI_PRODUCT_CYCLADES_CYCLOMY_2 },
766f90920fSjason 	{ PCI_VENDOR_CYCLADES, PCI_PRODUCT_CYCLADES_CYCLOM4Y_1 },
776f90920fSjason 	{ PCI_VENDOR_CYCLADES, PCI_PRODUCT_CYCLADES_CYCLOM4Y_2 },
786f90920fSjason 	{ PCI_VENDOR_CYCLADES, PCI_PRODUCT_CYCLADES_CYCLOM8Y_1 },
796f90920fSjason 	{ PCI_VENDOR_CYCLADES, PCI_PRODUCT_CYCLADES_CYCLOM8Y_2 },
806f90920fSjason };
816f90920fSjason 
82ded20a09Sderaadt int
cy_pci_match(struct device * parent,void * match,void * aux)83c42d7d40Sjsg cy_pci_match(struct device *parent, void *match, void *aux)
84ded20a09Sderaadt {
856f90920fSjason 	return (pci_matchbyid((struct pci_attach_args *)aux, cy_pci_devices,
86299fb045Sjasper 	    nitems(cy_pci_devices)));
87efe22d86Ssmart }
88efe22d86Ssmart 
89efe22d86Ssmart void
cy_pci_attach(struct device * parent,struct device * self,void * aux)90c42d7d40Sjsg cy_pci_attach(struct device *parent, struct device *self, void *aux)
91efe22d86Ssmart {
9299f5af5aSart 	struct cy_pci_softc *psc = (struct cy_pci_softc *)self;
93efe22d86Ssmart 	struct cy_softc *sc = (struct cy_softc *)self;
94efe22d86Ssmart 	struct pci_attach_args *pa = aux;
95c9aafe11Spvalchev 	const char *intrstr = NULL;
96efe22d86Ssmart 	pci_intr_handle_t ih;
9799f5af5aSart 	pcireg_t memtype;
987a52a123Sderaadt 	int plx_ver;
99ded20a09Sderaadt 
10099f5af5aSart 	sc->sc_bustype = CY_BUSTYPE_PCI;
101ded20a09Sderaadt 
10299f5af5aSart 	switch (PCI_PRODUCT(pa->pa_id)) {
10399f5af5aSart 	case PCI_PRODUCT_CYCLADES_CYCLOMY_1:
10499f5af5aSart 	case PCI_PRODUCT_CYCLADES_CYCLOM4Y_1:
10599f5af5aSart 	case PCI_PRODUCT_CYCLADES_CYCLOM8Y_1:
10699f5af5aSart 		memtype = PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT_1M;
1077a52a123Sderaadt 		break;
10899f5af5aSart 	case PCI_PRODUCT_CYCLADES_CYCLOMY_2:
10999f5af5aSart 	case PCI_PRODUCT_CYCLADES_CYCLOM4Y_2:
11099f5af5aSart 	case PCI_PRODUCT_CYCLADES_CYCLOM8Y_2:
11199f5af5aSart 		memtype = PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT;
11299f5af5aSart 		break;
1137a52a123Sderaadt 	}
114efe22d86Ssmart 
11599f5af5aSart 	if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_IO, 0,
11699f5af5aSart 	    &psc->sc_iot, &psc->sc_ioh, NULL, NULL, 0) != 0) {
117c9aafe11Spvalchev 		printf(": unable to map PLX registers\n");
11899f5af5aSart 		return;
11999f5af5aSart 	}
12099f5af5aSart 
12199f5af5aSart 	if (pci_mapreg_map(pa, 0x18, memtype, 0, &sc->sc_memt,
12299f5af5aSart 	    &sc->sc_memh, NULL, NULL, 0) != 0) {
123c9aafe11Spvalchev                 printf(": couldn't map device registers\n");
12499f5af5aSart                 return;
12599f5af5aSart         }
12699f5af5aSart 
12799f5af5aSart 	if ((sc->sc_nr_cd1400s = cy_probe_common(sc->sc_memt, sc->sc_memh,
12899f5af5aSart 	    CY_BUSTYPE_PCI)) == 0) {
129c9aafe11Spvalchev 		printf(": PCI Cyclom card with no CD1400s\n");
13099f5af5aSart 		return;
13199f5af5aSart 	}
13299f5af5aSart 
133c9aafe11Spvalchev 	if (pci_intr_map(pa, &ih) != 0) {
134c9aafe11Spvalchev 		printf(": couldn't map interrupt\n");
135c9aafe11Spvalchev 		return;
136c9aafe11Spvalchev 	}
137efe22d86Ssmart 
138c9aafe11Spvalchev 	intrstr = pci_intr_string(pa->pa_pc, ih);
139efe22d86Ssmart 	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, cy_intr,
140efe22d86Ssmart 	    sc, sc->sc_dev.dv_xname);
141c9aafe11Spvalchev 	if (sc->sc_ih == NULL) {
142c9aafe11Spvalchev 		printf(": couldn't establish interrupt");
143c9aafe11Spvalchev 		if (intrstr != NULL)
144c9aafe11Spvalchev 			printf(" at %s", intrstr);
145c9aafe11Spvalchev 		printf("\n");
146c9aafe11Spvalchev 		return;
147c9aafe11Spvalchev 	}
148c9aafe11Spvalchev 	printf(": %s", intrstr);
14999f5af5aSart 
15099f5af5aSart 	cy_attach(parent, self);
15199f5af5aSart 
15299f5af5aSart 	/* Get PLX version */
15399f5af5aSart 	plx_ver = bus_space_read_1(sc->sc_memt, sc->sc_memh, CY_PLX_VER) & 0x0f;
15499f5af5aSart 
15599f5af5aSart 	/* Enable PCI card interrupts */
15699f5af5aSart 	switch (plx_ver) {
15799f5af5aSart 	case CY_PLX_9050:
15899f5af5aSart 		bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA_9050,
15999f5af5aSart 		    CY_PLX_9050_ICS_IENABLE | CY_PLX_9050_ICS_LOCAL_IENABLE |
16099f5af5aSart 		    CY_PLX_9050_ICS_LOCAL_IPOLARITY);
16199f5af5aSart 		break;
16299f5af5aSart 
16399f5af5aSart 	case CY_PLX_9060:
16499f5af5aSart 	case CY_PLX_9080:
16599f5af5aSart 	default:
16699f5af5aSart 		bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA,
16799f5af5aSart 		    bus_space_read_2(psc->sc_iot, psc->sc_ioh,
16899f5af5aSart 		    CY_PCI_INTENA) | CY_PLX_9060_ICS_IENABLE |
16999f5af5aSart 		    CY_PLX_9060_ICS_LOCAL_IENABLE);
17099f5af5aSart 	}
171ded20a09Sderaadt }
172