pchb.c revision 1.33 1 /* $NetBSD: pchb.c,v 1.33 2012/01/30 19:41:18 drochner 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.33 2012/01/30 19:41:18 drochner 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 struct pcibus_attach_args pba;
159 struct agpbus_attach_args apa;
160 pcireg_t bcreg;
161 u_char bdnum, pbnum = 0; /* XXX: gcc */
162 pcitag_t tag;
163 int doattach, attachflags, has_agp;
164
165 doattach = 0;
166 has_agp = 0;
167 attachflags = pa->pa_flags;
168
169 sc->sc_dev = self;
170 sc->sc_pa = *pa;
171
172 /*
173 * Print out a description, and configure certain chipsets which
174 * have auxiliary PCI buses.
175 */
176
177 pci_aprint_devinfo(pa, NULL);
178
179 switch (PCI_VENDOR(pa->pa_id)) {
180 /*
181 * i386 stuff.
182 */
183 case PCI_VENDOR_SERVERWORKS:
184 pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff;
185
186 if (pbnum == 0)
187 break;
188
189 /*
190 * This host bridge has a second PCI bus.
191 * Configure it.
192 */
193 switch (PCI_PRODUCT(pa->pa_id)) {
194 case PCI_PRODUCT_SERVERWORKS_CSB5:
195 case PCI_PRODUCT_SERVERWORKS_CSB6:
196 /* These devices show up as host bridges, but are
197 really southbridges. */
198 break;
199 case PCI_PRODUCT_SERVERWORKS_CMIC_HE:
200 case PCI_PRODUCT_SERVERWORKS_CMIC_LE:
201 case PCI_PRODUCT_SERVERWORKS_CMIC_SL:
202 /* CNBs and CIOBs are connected to these using a
203 private bus. The bus number register is that of
204 the first PCI bus hanging off the CIOB. We let
205 the CIOB attachment handle configuring the PCI
206 buses. */
207 break;
208 default:
209 aprint_error_dev(self,
210 "unknown ServerWorks chip ID 0x%04x; trying "
211 "to attach PCI buses behind it\n",
212 PCI_PRODUCT(pa->pa_id));
213 /* FALLTHROUGH */
214 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP:
215 case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI:
216 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI:
217 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI:
218 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP:
219 case PCI_PRODUCT_SERVERWORKS_CIOB_X:
220 case PCI_PRODUCT_SERVERWORKS_CNB30_HE:
221 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2:
222 case PCI_PRODUCT_SERVERWORKS_CIOB_X2:
223 case PCI_PRODUCT_SERVERWORKS_CIOB_E:
224 switch (attachflags &
225 (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) {
226 case 0:
227 /* Doesn't smell like there's anything there. */
228 break;
229 case PCI_FLAGS_MEM_OKAY:
230 attachflags |= PCI_FLAGS_IO_OKAY;
231 /* FALLTHROUGH */
232 default:
233 doattach = 1;
234 break;
235 }
236 break;
237 }
238 break;
239 case PCI_VENDOR_INTEL:
240 switch (PCI_PRODUCT(pa->pa_id)) {
241 case PCI_PRODUCT_INTEL_82452_PB:
242 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
243 pbnum = PCISET_BRIDGE_NUMBER(bcreg);
244 if (pbnum != 0xff) {
245 pbnum++;
246 doattach = 1;
247 }
248 break;
249 case PCI_PRODUCT_INTEL_82443BX_AGP:
250 case PCI_PRODUCT_INTEL_82443BX_NOAGP:
251 /*
252 * http://www.intel.com/design/chipsets/specupdt/290639.htm
253 * says this bug is fixed in steppings >= C0 (erratum 11),
254 * so don't tweak the bits in that case.
255 */
256 if (!(PCI_REVISION(pa->pa_class) >= 0x03)) {
257 /*
258 * BIOS BUG WORKAROUND! The 82443BX
259 * datasheet indicates that the only
260 * legal setting for the "Idle/Pipeline
261 * DRAM Leadoff Timing (IPLDT)" parameter
262 * (bits 9:8) is 01. Unfortunately, some
263 * BIOSs do not set these bits properly.
264 */
265 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
266 I82443BX_SDRAMC_REG);
267 if ((bcreg & 0x03000000) != 0x01000000) {
268 aprint_verbose_dev(self, "fixing "
269 "Idle/Pipeline DRAM "
270 "Leadoff Timing\n");
271 bcreg &= ~0x03000000;
272 bcreg |= 0x01000000;
273 pci_conf_write(pa->pa_pc, pa->pa_tag,
274 I82443BX_SDRAMC_REG, bcreg);
275 }
276 }
277 break;
278
279 case PCI_PRODUCT_INTEL_PCI450_PB:
280 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
281 PCISET_BUSCONFIG_REG);
282 bdnum = PCISET_BRIDGE_NUMBER(bcreg);
283 pbnum = PCISET_PCI_BUS_NUMBER(bcreg);
284 switch (bdnum & PCISET_BRIDGETYPE_MASK) {
285 default:
286 aprint_error_dev(self, "bdnum=%x (reserved)\n",
287 bdnum);
288 break;
289 case PCISET_TYPE_COMPAT:
290 aprint_verbose_dev(self,
291 "Compatibility PB (bus %d)\n", pbnum);
292 break;
293 case PCISET_TYPE_AUX:
294 aprint_verbose_dev(self,
295 "Auxiliary PB (bus %d)\n",pbnum);
296 /*
297 * This host bridge has a second PCI bus.
298 * Configure it.
299 */
300 doattach = 1;
301 break;
302 }
303 break;
304 case PCI_PRODUCT_INTEL_CDC:
305 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
306 I82424_CPU_BCTL_REG);
307 if (bcreg & I82424_BCTL_CPUPCI_POSTEN) {
308 bcreg &= ~I82424_BCTL_CPUPCI_POSTEN;
309 pci_conf_write(pa->pa_pc, pa->pa_tag,
310 I82424_CPU_BCTL_REG, bcreg);
311 aprint_verbose_dev(self,
312 "disabled CPU-PCI write posting\n");
313 }
314 break;
315 case PCI_PRODUCT_INTEL_82451NX_PXB:
316 /*
317 * The NX chipset supports up to 2 "PXB" chips
318 * which can drive 2 PCI buses each. Each bus
319 * shows up as logical PCI device, with fixed
320 * device numbers between 18 and 21.
321 * See the datasheet at
322 ftp://download.intel.com/design/chipsets/datashts/24377102.pdf
323 * for details.
324 * (It would be easier to attach all the buses
325 * at the MIOC, but less aesthetical imho.)
326 */
327 if ((attachflags &
328 (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) ==
329 PCI_FLAGS_MEM_OKAY)
330 attachflags |= PCI_FLAGS_IO_OKAY;
331
332 pbnum = 0;
333 switch (pa->pa_device) {
334 case 18: /* PXB 0 bus A - primary bus */
335 break;
336 case 19: /* PXB 0 bus B */
337 /* read SUBA0 from MIOC */
338 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
339 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
340 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
341 break;
342 case 20: /* PXB 1 bus A */
343 /* read BUSNO1 from MIOC */
344 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
345 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
346 pbnum = (bcreg & 0xff000000) >> 24;
347 break;
348 case 21: /* PXB 1 bus B */
349 /* read SUBA1 from MIOC */
350 tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
351 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4);
352 pbnum = (bcreg & 0x000000ff) + 1;
353 break;
354 }
355 if (pbnum != 0)
356 doattach = 1;
357 break;
358
359 /*
360 * i386 and amd64 stuff.
361 */
362 case PCI_PRODUCT_INTEL_82810_MCH:
363 case PCI_PRODUCT_INTEL_82810_DC100_MCH:
364 case PCI_PRODUCT_INTEL_82810E_MCH:
365 case PCI_PRODUCT_INTEL_82815_FULL_HUB:
366 case PCI_PRODUCT_INTEL_82830MP_IO_1:
367 case PCI_PRODUCT_INTEL_82845G_DRAM:
368 case PCI_PRODUCT_INTEL_82855GM_MCH:
369 case PCI_PRODUCT_INTEL_82865_HB:
370 case PCI_PRODUCT_INTEL_82915G_HB:
371 case PCI_PRODUCT_INTEL_82915GM_HB:
372 case PCI_PRODUCT_INTEL_82945P_MCH:
373 case PCI_PRODUCT_INTEL_82945GM_HB:
374 case PCI_PRODUCT_INTEL_82945GME_HB:
375 case PCI_PRODUCT_INTEL_82946GZ_HB:
376 case PCI_PRODUCT_INTEL_82965Q_HB:
377 case PCI_PRODUCT_INTEL_82965G_HB:
378 case PCI_PRODUCT_INTEL_82965PM_HB:
379 case PCI_PRODUCT_INTEL_82Q35_HB:
380 case PCI_PRODUCT_INTEL_82G33_HB:
381 case PCI_PRODUCT_INTEL_82Q33_HB:
382 case PCI_PRODUCT_INTEL_82G35_HB:
383 case PCI_PRODUCT_INTEL_82GM45_HB:
384 case PCI_PRODUCT_INTEL_82IGD_E_HB:
385 case PCI_PRODUCT_INTEL_82Q45_HB:
386 case PCI_PRODUCT_INTEL_82G45_HB:
387 case PCI_PRODUCT_INTEL_82G41_HB:
388 case PCI_PRODUCT_INTEL_E7221_HB:
389 case PCI_PRODUCT_INTEL_82965GME_HB:
390 case PCI_PRODUCT_INTEL_82B43_HB:
391 case PCI_PRODUCT_INTEL_IRONLAKE_D_HB:
392 case PCI_PRODUCT_INTEL_IRONLAKE_M_HB:
393 case PCI_PRODUCT_INTEL_IRONLAKE_MA_HB:
394 case PCI_PRODUCT_INTEL_IRONLAKE_MC2_HB:
395 case PCI_PRODUCT_INTEL_PINEVIEW_HB:
396 case PCI_PRODUCT_INTEL_PINEVIEW_M_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 (!pmf_device_register(self, pchb_suspend, pchb_resume))
413 aprint_error_dev(self, "couldn't establish power handler\n");
414
415 /*
416 * If we haven't detected AGP yet (via a product ID),
417 * then check for AGP capability on the device.
418 */
419 if (has_agp ||
420 pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
421 NULL, NULL) != 0) {
422 apa.apa_pci_args = *pa;
423 config_found_ia(self, "agpbus", &apa, agpbusprint);
424 }
425
426 if (doattach) {
427 pba.pba_iot = pa->pa_iot;
428 pba.pba_memt = pa->pa_memt;
429 pba.pba_dmat = pa->pa_dmat;
430 pba.pba_dmat64 = pa->pa_dmat64;
431 pba.pba_pc = pa->pa_pc;
432 pba.pba_flags = attachflags;
433 pba.pba_bus = pbnum;
434 pba.pba_bridgetag = NULL;
435 pba.pba_pc = pa->pa_pc;
436 pba.pba_intrswiz = 0;
437 memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag));
438 config_found_ia(self, "pcibus", &pba, pcibusprint);
439 }
440
441 pchb_amdtempbus_configure(sc);
442 }
443
444 static int
445 pchbdetach(device_t self, int flags)
446 {
447 int rc;
448
449 if ((rc = config_detach_children(self, flags)) != 0)
450 return rc;
451
452 pmf_device_deregister(self);
453
454 return 0;
455 }
456
457 static int
458 pchbrescan(device_t self, const char *ifattr, const int *locators)
459 {
460 struct pchb_softc *sc = device_private(self);
461
462 if (ifattr_match(ifattr, "amdtempbus"))
463 pchb_amdtempbus_configure(sc);
464
465 return 0;
466 }
467
468 static void
469 pchbchilddet(device_t self, device_t child)
470 {
471 struct pchb_softc *sc = device_private(self);
472
473 if (sc->sc_amdtempbus == child) {
474 sc->sc_amdtempbus = NULL;
475 return;
476 }
477 }
478
479 static bool
480 pchb_suspend(device_t dv, const pmf_qual_t *qual)
481 {
482 struct pchb_softc *sc = device_private(dv);
483 pci_chipset_tag_t pc;
484 pcitag_t tag;
485 int off;
486
487 pc = sc->sc_pa.pa_pc;
488 tag = sc->sc_pa.pa_tag;
489
490 for (off = 0x40; off <= 0xff; off += 4)
491 sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off);
492
493 return true;
494 }
495
496 static bool
497 pchb_resume(device_t dv, const pmf_qual_t *qual)
498 {
499 struct pchb_softc *sc = device_private(dv);
500 pci_chipset_tag_t pc;
501 pcitag_t tag;
502 int off;
503
504 pc = sc->sc_pa.pa_pc;
505 tag = sc->sc_pa.pa_tag;
506
507 for (off = 0x40; off <= 0xff; off += 4)
508 pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]);
509
510 return true;
511 }
512
513 static void
514 pchb_amdtempbus_configure(struct pchb_softc *sc)
515 {
516 if (sc->sc_amdtempbus != NULL)
517 return;
518
519 sc->sc_amdtempbus = config_found_ia(sc->sc_dev, "amdtempbus", &sc->sc_pa, NULL);
520 }
521