xref: /openbsd/sys/arch/alpha/pci/sio.c (revision 6aef9a4e)
1*6aef9a4eSmpi /*	$OpenBSD: sio.c,v 1.41 2022/03/13 08:04:13 mpi Exp $	*/
23a630e3fSniklas /*	$NetBSD: sio.c,v 1.15 1996/12/05 01:39:36 cgd Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5417eba8cSderaadt  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
6df930be7Sderaadt  * All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Author: Chris G. Demetriou
9df930be7Sderaadt  *
10df930be7Sderaadt  * Permission to use, copy, modify and distribute this software and
11df930be7Sderaadt  * its documentation is hereby granted, provided that both the copyright
12df930be7Sderaadt  * notice and this permission notice appear in all copies of the
13df930be7Sderaadt  * software, derivative works or modified versions, and any portions
14df930be7Sderaadt  * thereof, and that both notices appear in supporting documentation.
15df930be7Sderaadt  *
16df930be7Sderaadt  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17df930be7Sderaadt  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18df930be7Sderaadt  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19df930be7Sderaadt  *
20df930be7Sderaadt  * Carnegie Mellon requests users of this software to return to
21df930be7Sderaadt  *
22df930be7Sderaadt  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23df930be7Sderaadt  *  School of Computer Science
24df930be7Sderaadt  *  Carnegie Mellon University
25df930be7Sderaadt  *  Pittsburgh PA 15213-3890
26df930be7Sderaadt  *
27df930be7Sderaadt  * any improvements or extensions that they make and grant Carnegie the
28df930be7Sderaadt  * rights to redistribute these changes.
29df930be7Sderaadt  */
30df930be7Sderaadt 
31df930be7Sderaadt #include <sys/param.h>
32df930be7Sderaadt #include <sys/systm.h>
33df930be7Sderaadt #include <sys/kernel.h>
34df930be7Sderaadt #include <sys/device.h>
35df930be7Sderaadt 
36417eba8cSderaadt #include <machine/intr.h>
37e464495eSniklas #include <machine/bus.h>
38417eba8cSderaadt 
3934fbf6deSderaadt #include <dev/isa/isavar.h>
4034fbf6deSderaadt #include <dev/eisa/eisavar.h>
4134fbf6deSderaadt 
42df930be7Sderaadt #include <dev/pci/pcireg.h>
43df930be7Sderaadt #include <dev/pci/pcivar.h>
44df930be7Sderaadt #include <dev/pci/pcidevs.h>
45df930be7Sderaadt 
4634fbf6deSderaadt #include <alpha/pci/siovar.h>
47df930be7Sderaadt 
4822e73efaSmiod #include "eisa.h"
4933ba0896Sart #include "isadma.h"
5033ba0896Sart 
513a630e3fSniklas struct sio_softc {
523a630e3fSniklas 	struct device			sc_dv;
533a630e3fSniklas 
543a630e3fSniklas 	bus_space_tag_t			sc_iot, sc_memt;
55d1688987Snate 	bus_dma_tag_t			sc_dmat;
563a630e3fSniklas 	int				sc_haseisa;
570087ab59Smiod 
580087ab59Smiod 	struct alpha_eisa_chipset	sc_ec;
590087ab59Smiod 	struct alpha_isa_chipset	sc_ic;
603a630e3fSniklas };
613a630e3fSniklas 
62c4071fd1Smillert int	siomatch(struct device *, void *, void *);
63c4071fd1Smillert void	sioattach(struct device *, struct device *, void *);
64acd48a0eSmiod int	sioactivate(struct device *, int);
65df930be7Sderaadt 
66578428abSmiod extern int sio_intr_alloc(isa_chipset_tag_t, int, int, int *);
67578428abSmiod extern int sio_intr_check(isa_chipset_tag_t, int, int);
68d1688987Snate 
690087ab59Smiod const struct cfattach sio_ca = {
70acd48a0eSmiod 	.ca_devsize = sizeof(struct sio_softc),
71acd48a0eSmiod 	.ca_match = siomatch,
72acd48a0eSmiod 	.ca_attach = sioattach,
73acd48a0eSmiod 	.ca_activate = sioactivate
74417eba8cSderaadt };
75417eba8cSderaadt 
76417eba8cSderaadt struct cfdriver sio_cd = {
77417eba8cSderaadt 	NULL, "sio", DV_DULL,
78df930be7Sderaadt };
79df930be7Sderaadt 
80c4071fd1Smillert int	pcebmatch(struct device *, void *, void *);
8134fbf6deSderaadt 
82*6aef9a4eSmpi const struct cfattach pceb_ca = {
83835a491cSart 	sizeof(struct sio_softc), pcebmatch, sioattach,
8434fbf6deSderaadt };
8534fbf6deSderaadt 
86417eba8cSderaadt struct cfdriver pceb_cd = {
87417eba8cSderaadt 	NULL, "pceb", DV_DULL,
88417eba8cSderaadt };
89417eba8cSderaadt 
90417eba8cSderaadt union sio_attach_args {
91417eba8cSderaadt 	const char *sa_name;			/* XXX should be common */
92417eba8cSderaadt 	struct isabus_attach_args sa_iba;
93417eba8cSderaadt 	struct eisabus_attach_args sa_eba;
94417eba8cSderaadt };
95417eba8cSderaadt 
96c4071fd1Smillert int	sioprint(void *, const char *pnp);
97c4071fd1Smillert void	sio_isa_attach_hook(struct device *, struct device *,
98c4071fd1Smillert 	    struct isabus_attach_args *);
99c4071fd1Smillert void	sio_eisa_attach_hook(struct device *, struct device *,
100c4071fd1Smillert 	    struct eisabus_attach_args *);
101c4071fd1Smillert int	sio_eisa_intr_map(void *, u_int, eisa_intr_handle_t *);
102712c6871Sbrad void	sio_bridge_callback(struct device *);
1033a630e3fSniklas 
104df930be7Sderaadt int
siomatch(parent,match,aux)105df930be7Sderaadt siomatch(parent, match, aux)
106df930be7Sderaadt 	struct device *parent;
1073a630e3fSniklas 	void *match;
1083a630e3fSniklas 	void *aux;
109df930be7Sderaadt {
110417eba8cSderaadt 	struct pci_attach_args *pa = aux;
111df930be7Sderaadt 
1126a30a1c1Smillert 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CONTAQ &&
113e6dd45c8Smillert 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CONTAQ_82C693 &&
1146a30a1c1Smillert 	    pa->pa_function == 0)
11534fbf6deSderaadt 		return (1);
1166a30a1c1Smillert 
1176a30a1c1Smillert 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
1186a30a1c1Smillert 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_SIO)
1196a30a1c1Smillert 		return (1);
1206a30a1c1Smillert 
121e9c60ed0Sericj 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALI &&
122fcb50aabSderaadt 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALI_M1533)
123fcb50aabSderaadt 		return(1);
124fcb50aabSderaadt 
125fcb50aabSderaadt 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALI &&
126e9c60ed0Sericj 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALI_M1543)
127e9c60ed0Sericj 		return(1);
1286a30a1c1Smillert 	return (0);
12934fbf6deSderaadt }
13034fbf6deSderaadt 
13134fbf6deSderaadt int
pcebmatch(parent,match,aux)13234fbf6deSderaadt pcebmatch(parent, match, aux)
13334fbf6deSderaadt 	struct device *parent;
1343a630e3fSniklas 	void *match;
1353a630e3fSniklas 	void *aux;
13634fbf6deSderaadt {
137417eba8cSderaadt 	struct pci_attach_args *pa = aux;
13834fbf6deSderaadt 
1394887a701Sart 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
1404887a701Sart 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PCEB)
141df930be7Sderaadt 		return (1);
1424887a701Sart 
1434887a701Sart 	return (0);
144df930be7Sderaadt }
145df930be7Sderaadt 
146df930be7Sderaadt void
sioattach(parent,self,aux)147df930be7Sderaadt sioattach(parent, self, aux)
148df930be7Sderaadt 	struct device *parent, *self;
149df930be7Sderaadt 	void *aux;
150df930be7Sderaadt {
1513a630e3fSniklas 	struct sio_softc *sc = (struct sio_softc *)self;
152417eba8cSderaadt 	struct pci_attach_args *pa = aux;
153df930be7Sderaadt 
15450c9667dSderaadt 	printf("\n");
15534fbf6deSderaadt 
1563a630e3fSniklas 	sc->sc_iot = pa->pa_iot;
1573a630e3fSniklas 	sc->sc_memt = pa->pa_memt;
158d1688987Snate         sc->sc_dmat = pa->pa_dmat;
1595d7756c0Sart 	sc->sc_haseisa = (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
160f87980b9Sart 		PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PCEB);
161df930be7Sderaadt 
162712c6871Sbrad 	config_defer(self, sio_bridge_callback);
1633a630e3fSniklas }
1643a630e3fSniklas 
165acd48a0eSmiod int
sioactivate(struct device * self,int act)166acd48a0eSmiod sioactivate(struct device *self, int act)
167acd48a0eSmiod {
168acd48a0eSmiod 	int rv = 0;
169acd48a0eSmiod 
170acd48a0eSmiod 	switch (act) {
171acd48a0eSmiod 	case DVACT_POWERDOWN:
172acd48a0eSmiod 		rv = config_activate_children(self, act);
173acd48a0eSmiod 		sio_intr_shutdown();
174acd48a0eSmiod 		break;
175acd48a0eSmiod 	default:
176acd48a0eSmiod 		rv = config_activate_children(self, act);
177acd48a0eSmiod 		break;
178acd48a0eSmiod 	}
179acd48a0eSmiod 	return (rv);
180acd48a0eSmiod }
181acd48a0eSmiod 
1823a630e3fSniklas void
sio_bridge_callback(self)183712c6871Sbrad sio_bridge_callback(self)
184712c6871Sbrad 	struct device *self;
1853a630e3fSniklas {
186712c6871Sbrad 	struct sio_softc *sc = (struct sio_softc *)self;
1873a630e3fSniklas 	union sio_attach_args sa;
1883a630e3fSniklas 
1893a630e3fSniklas 	if (sc->sc_haseisa) {
1900087ab59Smiod 		sc->sc_ec.ec_v = NULL;
1910087ab59Smiod 		sc->sc_ec.ec_maxslots = 0; /* will be filled by attach_hook */
1920087ab59Smiod 		sc->sc_ec.ec_attach_hook = sio_eisa_attach_hook;
1930087ab59Smiod 		sc->sc_ec.ec_intr_map = sio_eisa_intr_map;
1940087ab59Smiod 		sc->sc_ec.ec_intr_string = sio_intr_string;
1950087ab59Smiod 		sc->sc_ec.ec_intr_establish = sio_intr_establish;
1960087ab59Smiod 		sc->sc_ec.ec_intr_disestablish = sio_intr_disestablish;
197417eba8cSderaadt 
198417eba8cSderaadt 		sa.sa_eba.eba_busname = "eisa";
1993a630e3fSniklas 		sa.sa_eba.eba_iot = sc->sc_iot;
2003a630e3fSniklas 		sa.sa_eba.eba_memt = sc->sc_memt;
2013b17992dSmiod 		sa.sa_eba.eba_dmat =
2023b17992dSmiod 		    alphabus_dma_get_tag(sc->sc_dmat, ALPHA_BUS_EISA);
2030087ab59Smiod 		sa.sa_eba.eba_ec = &sc->sc_ec;
2043a630e3fSniklas 		config_found(&sc->sc_dv, &sa.sa_eba, sioprint);
205df930be7Sderaadt 	}
206df930be7Sderaadt 
2070087ab59Smiod 	sc->sc_ic.ic_v = NULL;
2080087ab59Smiod 	sc->sc_ic.ic_attach_hook = sio_isa_attach_hook;
2090087ab59Smiod 	sc->sc_ic.ic_intr_establish = sio_intr_establish;
2100087ab59Smiod 	sc->sc_ic.ic_intr_disestablish = sio_intr_disestablish;
2110087ab59Smiod 	sc->sc_ic.ic_intr_alloc = sio_intr_alloc;
2120087ab59Smiod 	sc->sc_ic.ic_intr_check = sio_intr_check;
213417eba8cSderaadt 
214417eba8cSderaadt 	sa.sa_iba.iba_busname = "isa";
2153a630e3fSniklas 	sa.sa_iba.iba_iot = sc->sc_iot;
2163a630e3fSniklas 	sa.sa_iba.iba_memt = sc->sc_memt;
21733ba0896Sart #if NISADMA > 0
218d1688987Snate 	sa.sa_iba.iba_dmat =
219d1688987Snate 		alphabus_dma_get_tag(sc->sc_dmat, ALPHA_BUS_ISA);
22033ba0896Sart #endif
2210087ab59Smiod 	sa.sa_iba.iba_ic = &sc->sc_ic;
2223a630e3fSniklas 	config_found(&sc->sc_dv, &sa.sa_iba, sioprint);
223417eba8cSderaadt }
224417eba8cSderaadt 
225417eba8cSderaadt int
sioprint(aux,pnp)226df930be7Sderaadt sioprint(aux, pnp)
227df930be7Sderaadt 	void *aux;
228833613b2Skstailey 	const char *pnp;
229df930be7Sderaadt {
230417eba8cSderaadt         register union sio_attach_args *sa = aux;
231df930be7Sderaadt 
232df930be7Sderaadt         if (pnp)
233417eba8cSderaadt                 printf("%s at %s", sa->sa_name, pnp);
234df930be7Sderaadt         return (UNCONF);
235df930be7Sderaadt }
236417eba8cSderaadt 
237417eba8cSderaadt void
sio_isa_attach_hook(parent,self,iba)238417eba8cSderaadt sio_isa_attach_hook(parent, self, iba)
239417eba8cSderaadt 	struct device *parent, *self;
240417eba8cSderaadt 	struct isabus_attach_args *iba;
241417eba8cSderaadt {
2429cf4a814Sart 	/* Nothing to do. */
243417eba8cSderaadt }
244417eba8cSderaadt 
245417eba8cSderaadt void
sio_eisa_attach_hook(parent,self,eba)246417eba8cSderaadt sio_eisa_attach_hook(parent, self, eba)
247417eba8cSderaadt 	struct device *parent, *self;
248417eba8cSderaadt 	struct eisabus_attach_args *eba;
249417eba8cSderaadt {
25022e73efaSmiod #if NEISA > 0
25122e73efaSmiod 	eisa_init(eba->eba_ec);
25222e73efaSmiod #endif
253417eba8cSderaadt }
254417eba8cSderaadt 
255417eba8cSderaadt int
sio_eisa_intr_map(v,irq,ihp)256417eba8cSderaadt sio_eisa_intr_map(v, irq, ihp)
257417eba8cSderaadt 	void *v;
258417eba8cSderaadt 	u_int irq;
259417eba8cSderaadt 	eisa_intr_handle_t *ihp;
260417eba8cSderaadt {
261417eba8cSderaadt 
262417eba8cSderaadt #define	ICU_LEN		16	/* number of ISA IRQs (XXX) */
263417eba8cSderaadt 
264417eba8cSderaadt 	if (irq >= ICU_LEN) {
265417eba8cSderaadt 		printf("sio_eisa_intr_map: bad IRQ %d\n", irq);
266417eba8cSderaadt 		*ihp = -1;
267417eba8cSderaadt 		return 1;
268417eba8cSderaadt 	}
269417eba8cSderaadt 	if (irq == 2) {
270417eba8cSderaadt 		printf("sio_eisa_intr_map: changed IRQ 2 to IRQ 9\n");
271417eba8cSderaadt 		irq = 9;
272417eba8cSderaadt 	}
273417eba8cSderaadt 
274417eba8cSderaadt 	*ihp = irq;
275417eba8cSderaadt 	return 0;
276417eba8cSderaadt }
277