pchb.c revision 1.22 1 /* $NetBSD: pchb.c,v 1.22 2010/06/16 03:35:01 riz 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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.22 2010/06/16 03:35:01 riz Exp $");
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
39
40 #include <machine/bus.h>
41
42 #include <dev/pci/pcivar.h>
43 #include <dev/pci/pcireg.h>
44
45 #include <dev/pci/pcidevs.h>
46
47 #include <dev/pci/agpreg.h>
48 #include <dev/pci/agpvar.h>
49
50 #include <arch/x86/pci/pchbvar.h>
51
52 #include "rnd.h"
53
54 #define PCISET_BRIDGETYPE_MASK 0x3
55 #define PCISET_TYPE_COMPAT 0x1
56 #define PCISET_TYPE_AUX 0x2
57
58 #define PCISET_BUSCONFIG_REG 0x48
59 #define PCISET_BRIDGE_NUMBER(reg) (((reg) >> 8) & 0xff)
60 #define PCISET_PCI_BUS_NUMBER(reg) (((reg) >> 16) & 0xff)
61
62 /* XXX should be in dev/ic/i82443reg.h */
63 #define I82443BX_SDRAMC_REG 0x74 /* upper 16 bits */
64
65 /* XXX should be in dev/ic/i82424{reg.var}.h */
66 #define I82424_CPU_BCTL_REG 0x53
67 #define I82424_PCI_BCTL_REG 0x54
68
69 #define I82424_BCTL_CPUMEM_POSTEN 0x01
70 #define I82424_BCTL_CPUPCI_POSTEN 0x02
71 #define I82424_BCTL_PCIMEM_BURSTEN 0x01
72 #define I82424_BCTL_PCI_BURSTEN 0x02
73
74 int pchbmatch(device_t, cfdata_t, void *);
75 void pchbattach(device_t, device_t, void *);
76 int pchbdetach(device_t, int);
77
78 static bool pchb_resume(device_t, const pmf_qual_t *);
79 static bool pchb_suspend(device_t, const pmf_qual_t *);
80
81 CFATTACH_DECL3_NEW(pchb, sizeof(struct pchb_softc),
82 pchbmatch, pchbattach, pchbdetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
83
84 int
85 pchbmatch(device_t parent, cfdata_t match, void *aux)
86 {
87 struct pci_attach_args *pa = aux;
88
89 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
90 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
91 return 1;
92
93 return 0;
94 }
95
96 int
97 pchb_get_bus_number(pci_chipset_tag_t pc, pcitag_t tag)
98 {
99 pcireg_t dev_id;
100 int bus, dev, func;
101 int bcreg, pbnum;
102
103 pci_decompose_tag(pc, tag, &bus, &dev, &func);
104
105 dev_id = pci_conf_read(pc, tag, PCI_ID_REG);
106 switch (PCI_VENDOR(dev_id)) {
107 case PCI_VENDOR_SERVERWORKS:
108 return pci_conf_read(pc, tag, 0x44) & 0xff;
109 case PCI_VENDOR_INTEL:
110 switch (PCI_PRODUCT(dev_id)) {
111 case PCI_PRODUCT_INTEL_82452_PB:
112 bcreg = pci_conf_read(pc, tag, 0x40);
113 pbnum = PCISET_BRIDGE_NUMBER(bcreg);
114 if (pbnum != 0xff)
115 return pbnum + 1;
116
117 break;
118 case PCI_PRODUCT_INTEL_PCI450_PB:
119 bcreg = pci_conf_read(pc, tag, PCISET_BUSCONFIG_REG);
120 return PCISET_PCI_BUS_NUMBER(bcreg);
121 case PCI_PRODUCT_INTEL_82451NX_PXB:
122 pbnum = 0;
123 switch (dev) {
124 case 18: /* PXB 0 bus A - primary bus */
125 break;
126 case 19: /* PXB 0 bus B */
127 /* read SUBA0 from MIOC */
128 tag = pci_make_tag(pc, 0, 16, 0);
129 bcreg = pci_conf_read(pc, tag, 0xd0);
130 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
131 break;
132 case 20: /* PXB 1 bus A */
133 /* read BUSNO1 from MIOC */
134 tag = pci_make_tag(pc, 0, 16, 0);
135 bcreg = pci_conf_read(pc, tag, 0xd0);
136 pbnum = (bcreg & 0xff000000) >> 24;
137 break;
138 case 21: /* PXB 1 bus B */
139 /* read SUBA1 from MIOC */
140 tag = pci_make_tag(pc, 0, 16, 0);
141 bcreg = pci_conf_read(pc, tag, 0xd4);
142 pbnum = (bcreg & 0x000000ff) + 1;
143 break;
144 }
145 return pbnum;
146 }
147 }
148 return -1;
149 }
150
151 void
152 pchbattach(device_t parent, device_t self, void *aux)
153 {
154 struct pchb_softc *sc = device_private(self);
155 struct pci_attach_args *pa = aux;
156 char devinfo[256];
157 struct pcibus_attach_args pba;
158 struct agpbus_attach_args apa;
159 pcireg_t bcreg;
160 u_char bdnum, pbnum = 0; /* XXX: gcc */
161 pcitag_t tag;
162 int doattach, attachflags, has_agp;
163
164 aprint_naive("\n");
165
166 doattach = 0;
167 has_agp = 0;
168 attachflags = pa->pa_flags;
169
170 sc->sc_dev = self;
171
172 /*
173 * Print out a description, and configure certain chipsets which
174 * have auxiliary PCI buses.
175 */
176
177 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
178 aprint_normal(": %s (rev. 0x%02x)\n", devinfo,
179 PCI_REVISION(pa->pa_class));
180
181 switch (PCI_VENDOR(pa->pa_id)) {
182 /*
183 * i386 stuff.
184 */
185 case PCI_VENDOR_SERVERWORKS:
186 pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff;
187
188 if (pbnum == 0)
189 break;
190
191 /*
192 * This host bridge has a second PCI bus.
193 * Configure it.
194 */
195 switch (PCI_PRODUCT(pa->pa_id)) {
196 case PCI_PRODUCT_SERVERWORKS_CSB5:
197 case PCI_PRODUCT_SERVERWORKS_CSB6:
198 /* These devices show up as host bridges, but are
199 really southbridges. */
200 break;
201 case PCI_PRODUCT_SERVERWORKS_CMIC_HE:
202 case PCI_PRODUCT_SERVERWORKS_CMIC_LE:
203 case PCI_PRODUCT_SERVERWORKS_CMIC_SL:
204 /* CNBs and CIOBs are connected to these using a
205 private bus. The bus number register is that of
206 the first PCI bus hanging off the CIOB. We let
207 the CIOB attachment handle configuring the PCI
208 buses. */
209 break;
210 default:
211 aprint_error_dev(self,
212 "unknown ServerWorks chip ID 0x%04x; trying "
213 "to attach PCI buses behind it\n",
214 PCI_PRODUCT(pa->pa_id));
215 /* FALLTHROUGH */
216 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP:
217 case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI:
218 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI:
219 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI:
220 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP:
221 case PCI_PRODUCT_SERVERWORKS_CIOB_X:
222 case PCI_PRODUCT_SERVERWORKS_CNB30_HE:
223 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2:
224 case PCI_PRODUCT_SERVERWORKS_CIOB_X2:
225 case PCI_PRODUCT_SERVERWORKS_CIOB_E:
226 switch (attachflags &
227 (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) {
228 case 0:
229 /* Doesn't smell like there's anything there. */
230 break;
231 case PCI_FLAGS_MEM_ENABLED:
232 attachflags |= PCI_FLAGS_IO_ENABLED;
233 /* FALLTHROUGH */
234 default:
235 doattach = 1;
236 break;
237 }
238 break;
239 }
240 break;
241 case PCI_VENDOR_INTEL:
242 switch (PCI_PRODUCT(pa->pa_id)) {
243 case PCI_PRODUCT_INTEL_82452_PB:
244 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
245 pbnum = PCISET_BRIDGE_NUMBER(bcreg);
246 if (pbnum != 0xff) {
247 pbnum++;
248 doattach = 1;
249 }
250 break;
251 case PCI_PRODUCT_INTEL_82443BX_AGP:
252 case PCI_PRODUCT_INTEL_82443BX_NOAGP:
253 /*
254 * http://www.intel.com/design/chipsets/specupdt/290639.htm
255 * says this bug is fixed in steppings >= C0 (erratum 11),
256 * so don't tweak the bits in that case.
257 */
258 if (!(PCI_REVISION(pa->pa_class) >= 0x03)) {
259 /*
260 * BIOS BUG WORKAROUND! The 82443BX
261 * datasheet indicates that the only
262 * legal setting for the "Idle/Pipeline
263 * DRAM Leadoff Timing (IPLDT)" parameter
264 * (bits 9:8) is 01. Unfortunately, some
265 * BIOSs do not set these bits properly.
266 */
267 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
268 I82443BX_SDRAMC_REG);
269 if ((bcreg & 0x03000000) != 0x01000000) {
270 aprint_verbose_dev(self, "fixing "
271 "Idle/Pipeline DRAM "
272 "Leadoff Timing\n");
273 bcreg &= ~0x03000000;
274 bcreg |= 0x01000000;
275 pci_conf_write(pa->pa_pc, pa->pa_tag,
276 I82443BX_SDRAMC_REG, bcreg);
277 }
278 }
279 break;
280
281 case PCI_PRODUCT_INTEL_PCI450_PB:
282 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
283 PCISET_BUSCONFIG_REG);
284 bdnum = PCISET_BRIDGE_NUMBER(bcreg);
285 pbnum = PCISET_PCI_BUS_NUMBER(bcreg);
286 switch (bdnum & PCISET_BRIDGETYPE_MASK) {
287 default:
288 aprint_error_dev(self, "bdnum=%x (reserved)\n",
289 bdnum);
290 break;
291 case PCISET_TYPE_COMPAT:
292 aprint_verbose_dev(self,
293 "Compatibility PB (bus %d)\n", pbnum);
294 break;
295 case PCISET_TYPE_AUX:
296 aprint_verbose_dev(self,
297 "Auxiliary PB (bus %d)\n",pbnum);
298 /*
299 * This host bridge has a second PCI bus.
300 * Configure it.
301 */
302 doattach = 1;
303 break;
304 }
305 break;
306 case PCI_PRODUCT_INTEL_CDC:
307 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
308 I82424_CPU_BCTL_REG);
309 if (bcreg & I82424_BCTL_CPUPCI_POSTEN) {
310 bcreg &= ~I82424_BCTL_CPUPCI_POSTEN;
311 pci_conf_write(pa->pa_pc, pa->pa_tag,
312 I82424_CPU_BCTL_REG, bcreg);
313 aprint_verbose_dev(self,
314 "disabled CPU-PCI write posting\n");
315 }
316 break;
317 case PCI_PRODUCT_INTEL_82451NX_PXB:
318 /*
319 * The NX chipset supports up to 2 "PXB" chips
320 * which can drive 2 PCI buses each. Each bus
321 * shows up as logical PCI device, with fixed
322 * device numbers between 18 and 21.
323 * See the datasheet at
324 ftp://download.intel.com/design/chipsets/datashts/24377102.pdf
325 * for details.
326 * (It would be easier to attach all the buses
327 * at the MIOC, but less aesthetical imho.)
328 */
329 if ((attachflags &
330 (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) ==
331 PCI_FLAGS_MEM_ENABLED)
332 attachflags |= PCI_FLAGS_IO_ENABLED;
333
334 pbnum = 0;
335 switch (pa->pa_device) {
336 case 18: /* PXB 0 bus A - primary bus */
337 break;
338 case 19: /* PXB 0 bus B */
339 /* read SUBA0 from MIOC */
340 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
341 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
342 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
343 break;
344 case 20: /* PXB 1 bus A */
345 /* read BUSNO1 from MIOC */
346 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
347 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
348 pbnum = (bcreg & 0xff000000) >> 24;
349 break;
350 case 21: /* PXB 1 bus B */
351 /* read SUBA1 from MIOC */
352 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
353 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4);
354 pbnum = (bcreg & 0x000000ff) + 1;
355 break;
356 }
357 if (pbnum != 0)
358 doattach = 1;
359 break;
360
361 /*
362 * i386 and amd64 stuff.
363 */
364 case PCI_PRODUCT_INTEL_82810_MCH:
365 case PCI_PRODUCT_INTEL_82810_DC100_MCH:
366 case PCI_PRODUCT_INTEL_82810E_MCH:
367 case PCI_PRODUCT_INTEL_82815_FULL_HUB:
368 case PCI_PRODUCT_INTEL_82830MP_IO_1:
369 case PCI_PRODUCT_INTEL_82845G_DRAM:
370 case PCI_PRODUCT_INTEL_82855GM_MCH:
371 case PCI_PRODUCT_INTEL_82865_HB:
372 case PCI_PRODUCT_INTEL_82915G_HB:
373 case PCI_PRODUCT_INTEL_82915GM_HB:
374 case PCI_PRODUCT_INTEL_82945P_MCH:
375 case PCI_PRODUCT_INTEL_82945GM_HB:
376 case PCI_PRODUCT_INTEL_82945GME_HB:
377 case PCI_PRODUCT_INTEL_82946GZ_HB:
378 case PCI_PRODUCT_INTEL_82965Q_HB:
379 case PCI_PRODUCT_INTEL_82965G_HB:
380 case PCI_PRODUCT_INTEL_82965PM_HB:
381 case PCI_PRODUCT_INTEL_82Q35_HB:
382 case PCI_PRODUCT_INTEL_82G33_HB:
383 case PCI_PRODUCT_INTEL_82Q33_HB:
384 case PCI_PRODUCT_INTEL_82G35_HB:
385 case PCI_PRODUCT_INTEL_82GM45_HB:
386 case PCI_PRODUCT_INTEL_82IGD_E_HB:
387 case PCI_PRODUCT_INTEL_82Q45_HB:
388 case PCI_PRODUCT_INTEL_82G45_HB:
389 case PCI_PRODUCT_INTEL_82G41_HB:
390 case PCI_PRODUCT_INTEL_E7221_HB:
391 case PCI_PRODUCT_INTEL_82965GME_HB:
392 case PCI_PRODUCT_INTEL_82B43_HB:
393 case PCI_PRODUCT_INTEL_IRONLAKE_D_HB:
394 case PCI_PRODUCT_INTEL_IRONLAKE_M_HB:
395 case PCI_PRODUCT_INTEL_IRONLAKE_MA_HB:
396 case PCI_PRODUCT_INTEL_IRONLAKE_MC2_HB:
397 /*
398 * The host bridge is either in GFX mode (internal
399 * graphics) or in AGP mode. In GFX mode, we pretend
400 * to have AGP because the graphics memory access
401 * is very similar and the AGP GATT code will
402 * deal with this. In the latter case, the
403 * pci_get_capability(PCI_CAP_AGP) test below will
404 * fire, so we do no harm by already setting the flag.
405 */
406 has_agp = 1;
407 break;
408 }
409 break;
410 }
411
412 #if NRND > 0
413 /*
414 * Attach a random number generator, if there is one.
415 */
416 pchb_attach_rnd(sc, pa);
417 #endif
418
419 if (!pmf_device_register(self, pchb_suspend, pchb_resume))
420 aprint_error_dev(self, "couldn't establish power handler\n");
421
422 /*
423 * If we haven't detected AGP yet (via a product ID),
424 * then check for AGP capability on the device.
425 */
426 if (has_agp ||
427 pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
428 NULL, NULL) != 0) {
429 apa.apa_pci_args = *pa;
430 config_found_ia(self, "agpbus", &apa, agpbusprint);
431 }
432
433 if (doattach) {
434 pba.pba_iot = pa->pa_iot;
435 pba.pba_memt = pa->pa_memt;
436 pba.pba_dmat = pa->pa_dmat;
437 pba.pba_dmat64 = pa->pa_dmat64;
438 pba.pba_pc = pa->pa_pc;
439 pba.pba_flags = attachflags;
440 pba.pba_bus = pbnum;
441 pba.pba_bridgetag = NULL;
442 pba.pba_pc = pa->pa_pc;
443 pba.pba_intrswiz = 0;
444 memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag));
445 config_found_ia(self, "pcibus", &pba, pcibusprint);
446 }
447 }
448
449 int
450 pchbdetach(device_t self, int flags)
451 {
452 int rc;
453 #if NRND > 0
454 struct pchb_softc *sc = device_private(self);
455 #endif
456
457 if ((rc = config_detach_children(self, flags)) != 0)
458 return rc;
459
460 pmf_device_deregister(self);
461
462 #if NRND > 0
463 /*
464 * Attach a random number generator, if there is one.
465 */
466 pchb_detach_rnd(sc);
467 #endif
468 return 0;
469 }
470
471 static bool
472 pchb_suspend(device_t dv, const pmf_qual_t *qual)
473 {
474 struct pchb_softc *sc = device_private(dv);
475 pci_chipset_tag_t pc;
476 pcitag_t tag;
477 int off;
478
479 pc = sc->sc_pc;
480 tag = sc->sc_tag;
481
482 for (off = 0x40; off <= 0xff; off += 4)
483 sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off);
484
485 return true;
486 }
487
488 static bool
489 pchb_resume(device_t dv, const pmf_qual_t *qual)
490 {
491 struct pchb_softc *sc = device_private(dv);
492 pci_chipset_tag_t pc;
493 pcitag_t tag;
494 int off;
495
496 pc = sc->sc_pc;
497 tag = sc->sc_tag;
498
499 for (off = 0x40; off <= 0xff; off += 4)
500 pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]);
501
502 return true;
503 }
504