pchb.c revision 1.3 1 /* $NetBSD: pchb.c,v 1.3 2007/11/12 19:40:49 joerg Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1998, 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.3 2007/11/12 19:40:49 joerg Exp $");
41
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
46
47 #include <machine/bus.h>
48
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pcireg.h>
51
52 #include <dev/pci/pcidevs.h>
53
54 #include <dev/pci/agpreg.h>
55 #include <dev/pci/agpvar.h>
56
57 #include <arch/x86/pci/pchbvar.h>
58
59 #include "rnd.h"
60
61 #define PCISET_BRIDGETYPE_MASK 0x3
62 #define PCISET_TYPE_COMPAT 0x1
63 #define PCISET_TYPE_AUX 0x2
64
65 #define PCISET_BUSCONFIG_REG 0x48
66 #define PCISET_BRIDGE_NUMBER(reg) (((reg) >> 8) & 0xff)
67 #define PCISET_PCI_BUS_NUMBER(reg) (((reg) >> 16) & 0xff)
68
69 /* XXX should be in dev/ic/i82443reg.h */
70 #define I82443BX_SDRAMC_REG 0x76
71
72 /* XXX should be in dev/ic/i82424{reg.var}.h */
73 #define I82424_CPU_BCTL_REG 0x53
74 #define I82424_PCI_BCTL_REG 0x54
75
76 #define I82424_BCTL_CPUMEM_POSTEN 0x01
77 #define I82424_BCTL_CPUPCI_POSTEN 0x02
78 #define I82424_BCTL_PCIMEM_BURSTEN 0x01
79 #define I82424_BCTL_PCI_BURSTEN 0x02
80
81 int pchbmatch(struct device *, struct cfdata *, void *);
82 void pchbattach(struct device *, struct device *, void *);
83
84 CFATTACH_DECL(pchb, sizeof(struct pchb_softc),
85 pchbmatch, pchbattach, NULL, NULL);
86
87 int
88 pchbmatch(struct device *parent, struct cfdata *match, void *aux)
89 {
90 struct pci_attach_args *pa = aux;
91
92 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
93 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
94 return 1;
95
96 return 0;
97 }
98
99 void
100 pchbattach(struct device *parent, struct device *self, void *aux)
101 {
102 #if NRND > 0
103 struct pchb_softc *sc = (void *) self;
104 #endif
105 struct pci_attach_args *pa = aux;
106 char devinfo[256];
107 struct pcibus_attach_args pba;
108 struct agpbus_attach_args apa;
109 pcireg_t bcreg;
110 u_char bdnum, pbnum = 0; /* XXX: gcc */
111 pcitag_t tag;
112 int doattach, attachflags, has_agp;
113
114 aprint_naive("\n");
115 aprint_normal("\n");
116
117 doattach = 0;
118 has_agp = 0;
119 attachflags = pa->pa_flags;
120
121 /*
122 * Print out a description, and configure certain chipsets which
123 * have auxiliary PCI buses.
124 */
125
126 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
127 aprint_normal("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo,
128 PCI_REVISION(pa->pa_class));
129
130 switch (PCI_VENDOR(pa->pa_id)) {
131 /*
132 * i386 stuff.
133 */
134 case PCI_VENDOR_SERVERWORKS:
135 pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff;
136
137 if (pbnum == 0)
138 break;
139
140 /*
141 * This host bridge has a second PCI bus.
142 * Configure it.
143 */
144 switch (PCI_PRODUCT(pa->pa_id)) {
145 case PCI_PRODUCT_SERVERWORKS_CSB5:
146 case PCI_PRODUCT_SERVERWORKS_CSB6:
147 /* These devices show up as host bridges, but are
148 really southbridges. */
149 break;
150 case PCI_PRODUCT_SERVERWORKS_CMIC_HE:
151 case PCI_PRODUCT_SERVERWORKS_CMIC_LE:
152 case PCI_PRODUCT_SERVERWORKS_CMIC_SL:
153 /* CNBs and CIOBs are connected to these using a
154 private bus. The bus number register is that of
155 the first PCI bus hanging off the CIOB. We let
156 the CIOB attachment handle configuring the PCI
157 buses. */
158 break;
159 default:
160 aprint_error("%s: unknown ServerWorks chip ID "
161 "0x%04x; trying to attach PCI buses behind it\n",
162 self->dv_xname, PCI_PRODUCT(pa->pa_id));
163 /* FALLTHROUGH */
164 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP:
165 case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI:
166 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI:
167 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI:
168 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP:
169 case PCI_PRODUCT_SERVERWORKS_CIOB_X:
170 case PCI_PRODUCT_SERVERWORKS_CNB30_HE:
171 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2:
172 case PCI_PRODUCT_SERVERWORKS_CIOB_X2:
173 case PCI_PRODUCT_SERVERWORKS_CIOB_E:
174 switch (attachflags &
175 (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) {
176 case 0:
177 /* Doesn't smell like there's anything there. */
178 break;
179 case PCI_FLAGS_MEM_ENABLED:
180 attachflags |= PCI_FLAGS_IO_ENABLED;
181 /* FALLTHROUGH */
182 default:
183 doattach = 1;
184 break;
185 }
186 break;
187 }
188 break;
189 case PCI_VENDOR_INTEL:
190 switch (PCI_PRODUCT(pa->pa_id)) {
191 case PCI_PRODUCT_INTEL_82452_PB:
192 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
193 pbnum = PCISET_BRIDGE_NUMBER(bcreg);
194 if (pbnum != 0xff) {
195 pbnum++;
196 doattach = 1;
197 }
198 break;
199 case PCI_PRODUCT_INTEL_82443BX_AGP:
200 case PCI_PRODUCT_INTEL_82443BX_NOAGP:
201 /*
202 * http://www.intel.com/design/chipsets/specupdt/290639.htm
203 * says this bug is fixed in steppings >= C0 (erratum 11),
204 * so don't tweak the bits in that case.
205 */
206 if (!(PCI_REVISION(pa->pa_class) >= 0x03)) {
207 /*
208 * BIOS BUG WORKAROUND! The 82443BX
209 * datasheet indicates that the only
210 * legal setting for the "Idle/Pipeline
211 * DRAM Leadoff Timing (IPLDT)" parameter
212 * (bits 9:8) is 01. Unfortunately, some
213 * BIOSs do not set these bits properly.
214 */
215 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
216 I82443BX_SDRAMC_REG);
217 if ((bcreg & 0x0300) != 0x0100) {
218 aprint_verbose("%s: fixing "
219 "Idle/Pipeline DRAM "
220 "Leadoff Timing\n", self->dv_xname);
221 bcreg &= ~0x0300;
222 bcreg |= 0x0100;
223 pci_conf_write(pa->pa_pc, pa->pa_tag,
224 I82443BX_SDRAMC_REG, bcreg);
225 }
226 }
227 break;
228
229 case PCI_PRODUCT_INTEL_PCI450_PB:
230 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
231 PCISET_BUSCONFIG_REG);
232 bdnum = PCISET_BRIDGE_NUMBER(bcreg);
233 pbnum = PCISET_PCI_BUS_NUMBER(bcreg);
234 switch (bdnum & PCISET_BRIDGETYPE_MASK) {
235 default:
236 aprint_error("%s: bdnum=%x (reserved)\n",
237 self->dv_xname, bdnum);
238 break;
239 case PCISET_TYPE_COMPAT:
240 aprint_verbose(
241 "%s: Compatibility PB (bus %d)\n",
242 self->dv_xname, pbnum);
243 break;
244 case PCISET_TYPE_AUX:
245 aprint_verbose("%s: Auxiliary PB (bus %d)\n",
246 self->dv_xname, pbnum);
247 /*
248 * This host bridge has a second PCI bus.
249 * Configure it.
250 */
251 doattach = 1;
252 break;
253 }
254 break;
255 case PCI_PRODUCT_INTEL_CDC:
256 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
257 I82424_CPU_BCTL_REG);
258 if (bcreg & I82424_BCTL_CPUPCI_POSTEN) {
259 bcreg &= ~I82424_BCTL_CPUPCI_POSTEN;
260 pci_conf_write(pa->pa_pc, pa->pa_tag,
261 I82424_CPU_BCTL_REG, bcreg);
262 aprint_verbose(
263 "%s: disabled CPU-PCI write posting\n",
264 self->dv_xname);
265 }
266 break;
267 case PCI_PRODUCT_INTEL_82451NX_PXB:
268 /*
269 * The NX chipset supports up to 2 "PXB" chips
270 * which can drive 2 PCI buses each. Each bus
271 * shows up as logical PCI device, with fixed
272 * device numbers between 18 and 21.
273 * See the datasheet at
274 ftp://download.intel.com/design/chipsets/datashts/24377102.pdf
275 * for details.
276 * (It would be easier to attach all the buses
277 * at the MIOC, but less aesthetical imho.)
278 */
279 if ((attachflags &
280 (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) ==
281 PCI_FLAGS_MEM_ENABLED)
282 attachflags |= PCI_FLAGS_IO_ENABLED;
283
284 pbnum = 0;
285 switch (pa->pa_device) {
286 case 18: /* PXB 0 bus A - primary bus */
287 break;
288 case 19: /* PXB 0 bus B */
289 /* read SUBA0 from MIOC */
290 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
291 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
292 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
293 break;
294 case 20: /* PXB 1 bus A */
295 /* read BUSNO1 from MIOC */
296 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
297 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
298 pbnum = (bcreg & 0xff000000) >> 24;
299 break;
300 case 21: /* PXB 1 bus B */
301 /* read SUBA1 from MIOC */
302 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
303 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4);
304 pbnum = (bcreg & 0x000000ff) + 1;
305 break;
306 }
307 if (pbnum != 0)
308 doattach = 1;
309 break;
310
311 /*
312 * i386 and amd64 stuff.
313 */
314 case PCI_PRODUCT_INTEL_82810_MCH:
315 case PCI_PRODUCT_INTEL_82810_DC100_MCH:
316 case PCI_PRODUCT_INTEL_82810E_MCH:
317 case PCI_PRODUCT_INTEL_82815_FULL_HUB:
318 case PCI_PRODUCT_INTEL_82830MP_IO_1:
319 case PCI_PRODUCT_INTEL_82845G_DRAM:
320 case PCI_PRODUCT_INTEL_82855GM_MCH:
321 case PCI_PRODUCT_INTEL_82865_HB:
322 case PCI_PRODUCT_INTEL_82915G_HB:
323 case PCI_PRODUCT_INTEL_82915GM_HB:
324 case PCI_PRODUCT_INTEL_82945P_MCH:
325 case PCI_PRODUCT_INTEL_82945GM_HB:
326 case PCI_PRODUCT_INTEL_82965Q_HB:
327 case PCI_PRODUCT_INTEL_82965G_HB:
328 case PCI_PRODUCT_INTEL_82965PM_HB:
329 /*
330 * The host bridge is either in GFX mode (internal
331 * graphics) or in AGP mode. In GFX mode, we pretend
332 * to have AGP because the graphics memory access
333 * is very similar and the AGP GATT code will
334 * deal with this. In the latter case, the
335 * pci_get_capability(PCI_CAP_AGP) test below will
336 * fire, so we do no harm by already setting the flag.
337 */
338 has_agp = 1;
339 break;
340 }
341 break;
342 }
343
344 #if NRND > 0
345 /*
346 * Attach a random number generator, if there is one.
347 */
348 pchb_attach_rnd(sc, pa);
349 #endif
350
351 /*
352 * If we haven't detected AGP yet (via a product ID),
353 * then check for AGP capability on the device.
354 */
355 if (has_agp ||
356 pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
357 NULL, NULL) != 0) {
358 apa.apa_pci_args = *pa;
359 config_found_ia(self, "agpbus", &apa, agpbusprint);
360 }
361
362 if (doattach) {
363 pba.pba_iot = pa->pa_iot;
364 pba.pba_memt = pa->pa_memt;
365 pba.pba_dmat = pa->pa_dmat;
366 pba.pba_dmat64 = pa->pa_dmat64;
367 pba.pba_pc = pa->pa_pc;
368 pba.pba_flags = attachflags;
369 pba.pba_bus = pbnum;
370 pba.pba_bridgetag = NULL;
371 pba.pba_pc = pa->pa_pc;
372 pba.pba_intrswiz = 0;
373 memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag));
374 config_found_ia(self, "pcibus", &pba, pcibusprint);
375 }
376 }
377