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