xref: /netbsd/sys/arch/x86/pci/pchb.c (revision 6550d01e)
1 /*	$NetBSD: pchb.c,v 1.23 2010/07/23 00:43:21 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.23 2010/07/23 00:43:21 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 <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 (!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 
442 int
443 pchbdetach(device_t self, int flags)
444 {
445 	int rc;
446 
447 	if ((rc = config_detach_children(self, flags)) != 0)
448 		return rc;
449 
450 	pmf_device_deregister(self);
451 
452 	return 0;
453 }
454 
455 static bool
456 pchb_suspend(device_t dv, const pmf_qual_t *qual)
457 {
458 	struct pchb_softc *sc = device_private(dv);
459 	pci_chipset_tag_t pc;
460 	pcitag_t tag;
461 	int off;
462 
463 	pc = sc->sc_pc;
464 	tag = sc->sc_tag;
465 
466 	for (off = 0x40; off <= 0xff; off += 4)
467 		sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off);
468 
469 	return true;
470 }
471 
472 static bool
473 pchb_resume(device_t dv, const pmf_qual_t *qual)
474 {
475 	struct pchb_softc *sc = device_private(dv);
476 	pci_chipset_tag_t pc;
477 	pcitag_t tag;
478 	int off;
479 
480 	pc = sc->sc_pc;
481 	tag = sc->sc_tag;
482 
483 	for (off = 0x40; off <= 0xff; off += 4)
484 		pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]);
485 
486 	return true;
487 }
488