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