mcpcia.c revision 1.2 1 1.2 thorpej /* $NetBSD: mcpcia.c,v 1.2 1998/05/14 00:01:31 thorpej Exp $ */
2 1.1 mjacob
3 1.1 mjacob /*
4 1.1 mjacob * Copyright (c) 1998 by Matthew Jacob
5 1.1 mjacob * NASA AMES Research Center.
6 1.1 mjacob * All rights reserved.
7 1.1 mjacob *
8 1.1 mjacob * Redistribution and use in source and binary forms, with or without
9 1.1 mjacob * modification, are permitted provided that the following conditions
10 1.1 mjacob * are met:
11 1.1 mjacob * 1. Redistributions of source code must retain the above copyright
12 1.1 mjacob * notice immediately at the beginning of the file, without modification,
13 1.1 mjacob * this list of conditions, and the following disclaimer.
14 1.1 mjacob * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 mjacob * notice, this list of conditions and the following disclaimer in the
16 1.1 mjacob * documentation and/or other materials provided with the distribution.
17 1.1 mjacob * 3. The name of the author may not be used to endorse or promote products
18 1.1 mjacob * derived from this software without specific prior written permission.
19 1.1 mjacob *
20 1.1 mjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 1.1 mjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 1.1 mjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 1.1 mjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 1.1 mjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 1.1 mjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 1.1 mjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 1.1 mjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 1.1 mjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 1.1 mjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 1.1 mjacob * SUCH DAMAGE.
31 1.1 mjacob */
32 1.1 mjacob
33 1.1 mjacob /*
34 1.1 mjacob * MCPCIA mcbus to PCI bus adapter
35 1.1 mjacob * found on AlphaServer 4100 systems.
36 1.1 mjacob */
37 1.1 mjacob
38 1.1 mjacob #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
39 1.1 mjacob
40 1.2 thorpej __KERNEL_RCSID(0, "$NetBSD: mcpcia.c,v 1.2 1998/05/14 00:01:31 thorpej Exp $");
41 1.1 mjacob
42 1.1 mjacob #include <sys/param.h>
43 1.1 mjacob #include <sys/systm.h>
44 1.1 mjacob #include <sys/device.h>
45 1.1 mjacob #include <sys/malloc.h>
46 1.1 mjacob
47 1.1 mjacob #include <machine/autoconf.h>
48 1.1 mjacob #include <machine/rpb.h>
49 1.1 mjacob #include <machine/pte.h>
50 1.1 mjacob
51 1.1 mjacob #include <alpha/mcbus/mcbusreg.h>
52 1.1 mjacob #include <alpha/mcbus/mcbusvar.h>
53 1.1 mjacob #include <alpha/pci/mcpciareg.h>
54 1.1 mjacob #include <alpha/pci/mcpciavar.h>
55 1.1 mjacob #include <alpha/pci/pci_kn300.h>
56 1.1 mjacob
57 1.1 mjacob struct mcpcia_softc *mcpcias = NULL;
58 1.1 mjacob static struct mcpcia_softc *mcpcia_lt = NULL;
59 1.1 mjacob
60 1.1 mjacob #define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
61 1.1 mjacob #define MCPCIA_SYSBASE(sc) \
62 1.1 mjacob ((((unsigned long) (sc)->mcpcia_gid) << MCBUS_GID_SHIFT) | \
63 1.1 mjacob (((unsigned long) (sc)->mcpcia_mid) << MCBUS_MID_SHIFT) | \
64 1.1 mjacob (MCBUS_IOSPACE))
65 1.1 mjacob
66 1.1 mjacob static int mcpciamatch __P((struct device *, struct cfdata *, void *));
67 1.1 mjacob static void mcpciaattach __P((struct device *, struct device *, void *));
68 1.1 mjacob struct cfattach mcpcia_ca = {
69 1.1 mjacob sizeof(struct mcpcia_softc), mcpciamatch, mcpciaattach
70 1.1 mjacob };
71 1.1 mjacob
72 1.1 mjacob static int mcpciaprint __P((void *, const char *));
73 1.1 mjacob
74 1.1 mjacob static int
75 1.1 mjacob mcpciaprint(aux, pnp)
76 1.1 mjacob void *aux;
77 1.1 mjacob const char *pnp;
78 1.1 mjacob {
79 1.1 mjacob register struct pcibus_attach_args *pba = aux;
80 1.1 mjacob /* only PCIs can attach to MCPCIA for now */
81 1.1 mjacob if (pnp)
82 1.1 mjacob printf("%s at %s", pba->pba_busname, pnp);
83 1.1 mjacob printf(" bus %d", pba->pba_bus);
84 1.1 mjacob return (UNCONF);
85 1.1 mjacob }
86 1.1 mjacob
87 1.1 mjacob static int
88 1.1 mjacob mcpciamatch(parent, cf, aux)
89 1.1 mjacob struct device *parent;
90 1.1 mjacob struct cfdata *cf;
91 1.1 mjacob void *aux;
92 1.1 mjacob {
93 1.1 mjacob struct mcbus_dev_attach_args *ma = aux;
94 1.1 mjacob if (ma->ma_type == MCBUS_TYPE_PCI)
95 1.1 mjacob return (1);
96 1.1 mjacob return (0);
97 1.1 mjacob }
98 1.1 mjacob
99 1.1 mjacob static void
100 1.1 mjacob mcpciaattach(parent, self, aux)
101 1.1 mjacob struct device *parent;
102 1.1 mjacob struct device *self;
103 1.1 mjacob void *aux;
104 1.1 mjacob {
105 1.1 mjacob static int first = 1;
106 1.1 mjacob struct mcbus_dev_attach_args *ma = aux;
107 1.1 mjacob struct mcpcia_softc *mcp = (struct mcpcia_softc *)self;
108 1.1 mjacob struct pcibus_attach_args pba;
109 1.1 mjacob
110 1.1 mjacob mcp->mcpcia_dev = *self;
111 1.1 mjacob mcp->mcpcia_mid = ma->ma_mid;
112 1.1 mjacob mcp->mcpcia_gid = ma->ma_gid;
113 1.1 mjacob
114 1.1 mjacob printf("\n");
115 1.1 mjacob
116 1.1 mjacob mcpcia_init(mcp);
117 1.1 mjacob
118 1.1 mjacob
119 1.1 mjacob mcp->mcpcia_next = NULL;
120 1.1 mjacob if (mcpcia_lt == NULL) {
121 1.1 mjacob mcpcias = mcp;
122 1.1 mjacob } else {
123 1.1 mjacob mcpcia_lt->mcpcia_next = mcp;
124 1.1 mjacob }
125 1.1 mjacob mcpcia_lt = mcp;
126 1.1 mjacob
127 1.1 mjacob /*
128 1.1 mjacob * Set up interrupts
129 1.1 mjacob */
130 1.1 mjacob pci_kn300_pickintr(&mcp->mcpcia_cc, first);
131 1.1 mjacob #ifdef EVCNT_COUNTERS
132 1.1 mjacob if (first == 1) {
133 1.1 mjacob evcnt_attach(self, "intr", kn300_intr_evcnt);
134 1.1 mjacob first = 0;
135 1.1 mjacob }
136 1.1 mjacob #else
137 1.1 mjacob first = 0;
138 1.1 mjacob #endif
139 1.1 mjacob
140 1.1 mjacob /*
141 1.1 mjacob * Attach PCI bus
142 1.1 mjacob */
143 1.1 mjacob pba.pba_busname = "pci";
144 1.1 mjacob pba.pba_iot = &mcp->mcpcia_cc.cc_iot;
145 1.1 mjacob pba.pba_memt = &mcp->mcpcia_cc.cc_memt;
146 1.1 mjacob pba.pba_dmat = /* start with direct, may change... */
147 1.1 mjacob alphabus_dma_get_tag(&mcp->mcpcia_cc.cc_dmat_direct, ALPHA_BUS_PCI);
148 1.1 mjacob pba.pba_pc = &mcp->mcpcia_cc.cc_pc;
149 1.1 mjacob pba.pba_bus = 0;
150 1.1 mjacob pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
151 1.1 mjacob config_found(self, &pba, mcpciaprint);
152 1.1 mjacob }
153 1.1 mjacob
154 1.1 mjacob void
155 1.1 mjacob mcpcia_init(mcp)
156 1.1 mjacob struct mcpcia_softc *mcp;
157 1.1 mjacob {
158 1.1 mjacob u_int32_t ctl;
159 1.1 mjacob struct mcpcia_config *ccp = &mcp->mcpcia_cc;
160 1.1 mjacob
161 1.1 mjacob if (ccp->cc_initted == 0) {
162 1.1 mjacob mcpcia_bus_io_init(&ccp->cc_iot, ccp);
163 1.1 mjacob mcpcia_bus_mem_init(&ccp->cc_memt, ccp);
164 1.1 mjacob }
165 1.1 mjacob mcpcia_pci_init(&ccp->cc_pc, ccp);
166 1.1 mjacob ccp->cc_sc = mcp;
167 1.1 mjacob
168 1.1 mjacob /*
169 1.1 mjacob * Establish a precalculated base for convenience's sake.
170 1.1 mjacob */
171 1.1 mjacob ccp->cc_sysbase = MCPCIA_SYSBASE(mcp);
172 1.1 mjacob
173 1.1 mjacob
174 1.1 mjacob ctl = REGVAL(MCPCIA_PCI_REV(mcp));
175 1.1 mjacob printf("%s: Horse Revision %d, %s Handed Saddle Revision %d,"
176 1.1 mjacob " CAP Revision %d\n", mcp->mcpcia_dev.dv_xname, HORSE_REV(ctl),
177 1.1 mjacob (SADDLE_TYPE(ctl) & 1)? "Right": "Left", SADDLE_REV(ctl),
178 1.1 mjacob CAP_REV(ctl));
179 1.1 mjacob
180 1.1 mjacob /*
181 1.1 mjacob * Disable interrupts and clear errors prior to probing
182 1.1 mjacob */
183 1.1 mjacob REGVAL(MCPCIA_INT_MASK0(mcp)) = 0;
184 1.1 mjacob REGVAL(MCPCIA_INT_MASK1(mcp)) = 0;
185 1.1 mjacob REGVAL(MCPCIA_CAP_ERR(mcp)) = 0xFFFFFFFF;
186 1.1 mjacob alpha_mb();
187 1.1 mjacob
188 1.1 mjacob /*
189 1.1 mjacob * Set up DMA stuff for this MCPCIA.
190 1.1 mjacob */
191 1.1 mjacob mcpcia_dma_init(ccp);
192 1.1 mjacob
193 1.1 mjacob /*
194 1.1 mjacob * Clean up any post probe errors (W1TC).
195 1.1 mjacob */
196 1.1 mjacob REGVAL(MCPCIA_CAP_ERR(mcp)) = 0xFFFFFFFF;
197 1.1 mjacob alpha_mb();
198 1.1 mjacob
199 1.1 mjacob /*
200 1.1 mjacob * Use this opportunity to also find out the MID and CPU
201 1.1 mjacob * type of the currently running CPU (that's us, billybob....)
202 1.1 mjacob */
203 1.1 mjacob ctl = REGVAL(MCPCIA_WHOAMI(mcp));
204 1.1 mjacob mcbus_primary.mcbus_cpu_mid = MCBUS_CPU_MID(ctl);
205 1.1 mjacob if ((ctl & CPU_Fill_Err) == 0 && mcbus_primary.mcbus_valid == 0) {
206 1.1 mjacob mcbus_primary.mcbus_bcache =
207 1.1 mjacob MCBUS_CPU_INFO(ctl) & CPU_BCacheMask;
208 1.1 mjacob mcbus_primary.mcbus_valid = 1;
209 1.1 mjacob }
210 1.1 mjacob alpha_mb();
211 1.1 mjacob ccp->cc_initted = 1;
212 1.1 mjacob }
213 1.1 mjacob
214 1.1 mjacob void
215 1.1 mjacob mcpcia_config_cleanup()
216 1.1 mjacob {
217 1.1 mjacob volatile u_int32_t ctl;
218 1.1 mjacob struct mcpcia_softc *mcp;
219 1.1 mjacob
220 1.1 mjacob /*
221 1.1 mjacob * Turn on Hard, Soft error interrupts. Maybe i2c too.
222 1.1 mjacob */
223 1.1 mjacob for (mcp = mcpcias; mcp; mcp = mcp->mcpcia_next) {
224 1.1 mjacob ctl = REGVAL(MCPCIA_INT_MASK0(mcp));
225 1.1 mjacob ctl |= MCPCIA_GEN_IENABL;
226 1.1 mjacob REGVAL(MCPCIA_INT_MASK0(mcp)) = ctl;
227 1.1 mjacob alpha_mb();
228 1.1 mjacob /* force stall while write completes */
229 1.1 mjacob ctl = REGVAL(MCPCIA_INT_MASK0(mcp));
230 1.1 mjacob }
231 1.1 mjacob }
232