cia.c revision 1.37
1/* $NetBSD: cia.c,v 1.37 1998/06/04 21:34:45 thorpej Exp $ */
2
3/*
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22 *  School of Computer Science
23 *  Carnegie Mellon University
24 *  Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30#include "opt_dec_eb164.h"
31#include "opt_dec_kn20aa.h"
32
33#include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
34
35__KERNEL_RCSID(0, "$NetBSD: cia.c,v 1.37 1998/06/04 21:34:45 thorpej Exp $");
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/malloc.h>
41#include <sys/device.h>
42#include <vm/vm.h>
43
44#include <machine/autoconf.h>
45#include <machine/rpb.h>
46
47#include <dev/isa/isareg.h>
48#include <dev/isa/isavar.h>
49
50#include <dev/pci/pcireg.h>
51#include <dev/pci/pcivar.h>
52#include <alpha/pci/ciareg.h>
53#include <alpha/pci/ciavar.h>
54#ifdef DEC_KN20AA
55#include <alpha/pci/pci_kn20aa.h>
56#endif
57#ifdef DEC_EB164
58#include <alpha/pci/pci_eb164.h>
59#endif
60
61int	ciamatch __P((struct device *, struct cfdata *, void *));
62void	ciaattach __P((struct device *, struct device *, void *));
63
64struct cfattach cia_ca = {
65	sizeof(struct cia_softc), ciamatch, ciaattach,
66};
67
68extern struct cfdriver cia_cd;
69
70static int	ciaprint __P((void *, const char *pnp));
71
72/* There can be only one. */
73int ciafound;
74struct cia_config cia_configuration;
75
76/*
77 * This determines if we attempt to use BWX for PCI bus and config space
78 * access.  Some systems, notably with Pyxis, don't fare so well unless
79 * BWX is used.
80 */
81#ifndef CIA_USE_BWX
82#define	CIA_USE_BWX	1
83#endif
84
85int	cia_use_bwx = CIA_USE_BWX;
86
87int
88ciamatch(parent, match, aux)
89	struct device *parent;
90	struct cfdata *match;
91	void *aux;
92{
93	struct mainbus_attach_args *ma = aux;
94
95	/* Make sure that we're looking for a CIA. */
96	if (strcmp(ma->ma_name, cia_cd.cd_name) != 0)
97		return (0);
98
99	if (ciafound)
100		return (0);
101
102	return (1);
103}
104
105/*
106 * Set up the chipset's function pointers.
107 */
108void
109cia_init(ccp, mallocsafe)
110	struct cia_config *ccp;
111	int mallocsafe;
112{
113
114	ccp->cc_hae_mem = REGVAL(CIA_CSR_HAE_MEM);
115	ccp->cc_hae_io = REGVAL(CIA_CSR_HAE_IO);
116	ccp->cc_rev = REGVAL(CIA_CSR_REV) & REV_MASK;
117
118	/*
119	 * Determine if we have a Pyxis.  Only two systypes can
120	 * have this: the EB164 systype (AlphaPC164LX and AlphaPC164SX)
121	 * and the DEC_550 systype (Miata).
122	 */
123	if ((hwrpb->rpb_type == ST_EB164 &&
124	     (hwrpb->rpb_variation & SV_ST_MASK) >= SV_ST_ALPHAPC164LX_400) ||
125	    hwrpb->rpb_type == ST_DEC_550)
126		ccp->cc_flags |= CCF_ISPYXIS;
127
128	/*
129	 * Revisions >= 2 have the CNFG register.
130	 */
131	if (ccp->cc_rev >= 2)
132		ccp->cc_cnfg = REGVAL(CIA_CSR_CNFG);
133	else
134		ccp->cc_cnfg = 0;
135
136	/*
137	 * Use BWX iff:
138	 *
139	 *	- It hasn't been disbled by the user,
140	 *	- it's enabled in CNFG,
141	 *	- we're implementation version ev5,
142	 *	- BWX is enabled in the CPU's capabilities mask (yes,
143	 *	  the bit is really cleared if the capability exists...)
144	 */
145	if (cia_use_bwx != 0 &&
146	    (ccp->cc_cnfg & CNFG_BWEN) != 0 &&
147	    alpha_implver() == ALPHA_IMPLVER_EV5 &&
148	    alpha_amask(ALPHA_AMASK_BWX) == 0)
149		ccp->cc_flags |= CCF_USEBWX;
150
151	if (!ccp->cc_initted) {
152		/* don't do these twice since they set up extents */
153		if (ccp->cc_flags & CCF_USEBWX) {
154			cia_bwx_bus_io_init(&ccp->cc_iot, ccp);
155			cia_bwx_bus_mem_init(&ccp->cc_memt, ccp);
156		} else {
157			cia_swiz_bus_io_init(&ccp->cc_iot, ccp);
158			cia_swiz_bus_mem_init(&ccp->cc_memt, ccp);
159		}
160	}
161	ccp->cc_mallocsafe = mallocsafe;
162
163	cia_pci_init(&ccp->cc_pc, ccp);
164
165	cia_dma_init(ccp);
166
167	ccp->cc_initted = 1;
168}
169
170void
171ciaattach(parent, self, aux)
172	struct device *parent, *self;
173	void *aux;
174{
175	struct cia_softc *sc = (struct cia_softc *)self;
176	struct cia_config *ccp;
177	struct pcibus_attach_args pba;
178	char bits[64];
179
180	/* note that we've attached the chipset; can't have 2 CIAs. */
181	ciafound = 1;
182
183	/*
184	 * set up the chipset's info; done once at console init time
185	 * (maybe), but we must do it here as well to take care of things
186	 * that need to use memory allocation.
187	 */
188	ccp = sc->sc_ccp = &cia_configuration;
189	cia_init(ccp, 1);
190
191	printf(": DECchip 2117x Core Logic Chipset (%s), pass %d\n",
192	    (ccp->cc_flags & CCF_ISPYXIS) ? "Pyxis" : "ALCOR/ALCOR2",
193	    ccp->cc_rev + 1);
194	if (ccp->cc_cnfg)
195		printf("%s: extended capabilities: %s\n", self->dv_xname,
196		    bitmask_snprintf(ccp->cc_cnfg, CIA_CSR_CNFG_BITS,
197		    bits, sizeof(bits)));
198#if 1
199	if (ccp->cc_flags & CCF_USEBWX)
200		printf("%s: using BWX for PCI config and device access\n",
201		    self->dv_xname);
202#endif
203
204	switch (hwrpb->rpb_type) {
205#ifdef DEC_KN20AA
206	case ST_DEC_KN20AA:
207		pci_kn20aa_pickintr(ccp);
208#ifdef EVCNT_COUNTERS
209		evcnt_attach(self, "intr", &kn20aa_intr_evcnt);
210#endif
211		break;
212#endif
213
214#ifdef DEC_EB164
215	case ST_EB164:
216		pci_eb164_pickintr(ccp);
217#ifdef EVCNT_COUNTERS
218		evcnt_attach(self, "intr", &eb164_intr_evcnt);
219#endif
220		break;
221#endif
222
223	default:
224		panic("ciaattach: shouldn't be here, really...");
225	}
226
227	pba.pba_busname = "pci";
228	pba.pba_iot = &ccp->cc_iot;
229	pba.pba_memt = &ccp->cc_memt;
230	pba.pba_dmat =
231	    alphabus_dma_get_tag(&ccp->cc_dmat_direct, ALPHA_BUS_PCI);
232	pba.pba_pc = &ccp->cc_pc;
233	pba.pba_bus = 0;
234	pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
235	config_found(self, &pba, ciaprint);
236}
237
238static int
239ciaprint(aux, pnp)
240	void *aux;
241	const char *pnp;
242{
243	register struct pcibus_attach_args *pba = aux;
244
245	/* only PCIs can attach to CIAs; easy. */
246	if (pnp)
247		printf("%s at %s", pba->pba_busname, pnp);
248	printf(" bus %d", pba->pba_bus);
249	return (UNCONF);
250}
251