Home | History | Annotate | Line # | Download | only in pci
pchb.c revision 1.13
      1 /*	$NetBSD: pchb.c,v 1.13 2008/08/19 10:05:40 matthias 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.13 2008/08/19 10:05:40 matthias 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 PMF_FN_ARGS);
     79 static bool	pchb_suspend(device_t PMF_FN_ARGS);
     80 
     81 CFATTACH_DECL_NEW(pchb, sizeof(struct pchb_softc),
     82     pchbmatch, pchbattach, pchbdetach, NULL);
     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 	aprint_normal("\n");
    166 
    167 	doattach = 0;
    168 	has_agp = 0;
    169 	attachflags = pa->pa_flags;
    170 
    171 	sc->sc_dev = self;
    172 
    173 	/*
    174 	 * Print out a description, and configure certain chipsets which
    175 	 * have auxiliary PCI buses.
    176 	 */
    177 
    178 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
    179 	aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo,
    180 	    PCI_REVISION(pa->pa_class));
    181 
    182 	switch (PCI_VENDOR(pa->pa_id)) {
    183 	/*
    184 	 * i386 stuff.
    185 	 */
    186 	case PCI_VENDOR_SERVERWORKS:
    187 		pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff;
    188 
    189 		if (pbnum == 0)
    190 			break;
    191 
    192 		/*
    193 		 * This host bridge has a second PCI bus.
    194 		 * Configure it.
    195 		 */
    196 		switch (PCI_PRODUCT(pa->pa_id)) {
    197 		case PCI_PRODUCT_SERVERWORKS_CSB5:
    198 		case PCI_PRODUCT_SERVERWORKS_CSB6:
    199 			/* These devices show up as host bridges, but are
    200 			   really southbridges. */
    201 			break;
    202 		case PCI_PRODUCT_SERVERWORKS_CMIC_HE:
    203 		case PCI_PRODUCT_SERVERWORKS_CMIC_LE:
    204 		case PCI_PRODUCT_SERVERWORKS_CMIC_SL:
    205 			/* CNBs and CIOBs are connected to these using a
    206 			   private bus.  The bus number register is that of
    207 			   the first PCI bus hanging off the CIOB.  We let
    208 			   the CIOB attachment handle configuring the PCI
    209 			   buses. */
    210 			break;
    211 		default:
    212 			aprint_error_dev(self,
    213 			    "unknown ServerWorks chip ID 0x%04x; trying "
    214 			    "to attach PCI buses behind it\n",
    215 			    PCI_PRODUCT(pa->pa_id));
    216 			/* FALLTHROUGH */
    217 		case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP:
    218 		case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI:
    219 		case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI:
    220 		case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI:
    221 		case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP:
    222 		case PCI_PRODUCT_SERVERWORKS_CIOB_X:
    223 		case PCI_PRODUCT_SERVERWORKS_CNB30_HE:
    224 		case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2:
    225 		case PCI_PRODUCT_SERVERWORKS_CIOB_X2:
    226 		case PCI_PRODUCT_SERVERWORKS_CIOB_E:
    227 			switch (attachflags &
    228 			    (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) {
    229 			case 0:
    230 				/* Doesn't smell like there's anything there. */
    231 				break;
    232 			case PCI_FLAGS_MEM_ENABLED:
    233 				attachflags |= PCI_FLAGS_IO_ENABLED;
    234 				/* FALLTHROUGH */
    235 			default:
    236 				doattach = 1;
    237 				break;
    238 			}
    239 			break;
    240 		}
    241 		break;
    242 	case PCI_VENDOR_INTEL:
    243 		switch (PCI_PRODUCT(pa->pa_id)) {
    244 		case PCI_PRODUCT_INTEL_82452_PB:
    245 			bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
    246 			pbnum = PCISET_BRIDGE_NUMBER(bcreg);
    247 			if (pbnum != 0xff) {
    248 				pbnum++;
    249 				doattach = 1;
    250 			}
    251 			break;
    252 		case PCI_PRODUCT_INTEL_82443BX_AGP:
    253 		case PCI_PRODUCT_INTEL_82443BX_NOAGP:
    254 		/*
    255 		 * http://www.intel.com/design/chipsets/specupdt/290639.htm
    256 		 * says this bug is fixed in steppings >= C0 (erratum 11),
    257 		 * so don't tweak the bits in that case.
    258 		 */
    259 			if (!(PCI_REVISION(pa->pa_class) >= 0x03)) {
    260 				/*
    261 				 * BIOS BUG WORKAROUND!  The 82443BX
    262 				 * datasheet indicates that the only
    263 				 * legal setting for the "Idle/Pipeline
    264 				 * DRAM Leadoff Timing (IPLDT)" parameter
    265 				 * (bits 9:8) is 01.  Unfortunately, some
    266 				 * BIOSs do not set these bits properly.
    267 				 */
    268 				bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
    269 				    I82443BX_SDRAMC_REG);
    270 				if ((bcreg & 0x03000000) != 0x01000000) {
    271 					aprint_verbose_dev(self, "fixing "
    272 					    "Idle/Pipeline DRAM "
    273 					    "Leadoff Timing\n");
    274 					bcreg &= ~0x03000000;
    275 					bcreg |=  0x01000000;
    276 					pci_conf_write(pa->pa_pc, pa->pa_tag,
    277 					    I82443BX_SDRAMC_REG, bcreg);
    278 				}
    279 			}
    280 			break;
    281 
    282 		case PCI_PRODUCT_INTEL_PCI450_PB:
    283 			bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
    284 					      PCISET_BUSCONFIG_REG);
    285 			bdnum = PCISET_BRIDGE_NUMBER(bcreg);
    286 			pbnum = PCISET_PCI_BUS_NUMBER(bcreg);
    287 			switch (bdnum & PCISET_BRIDGETYPE_MASK) {
    288 			default:
    289 				aprint_error_dev(self, "bdnum=%x (reserved)\n",
    290 				       bdnum);
    291 				break;
    292 			case PCISET_TYPE_COMPAT:
    293 				aprint_verbose_dev(self,
    294 				    "Compatibility PB (bus %d)\n", pbnum);
    295 				break;
    296 			case PCISET_TYPE_AUX:
    297 				aprint_verbose_dev(self,
    298 				    "Auxiliary PB (bus %d)\n",pbnum);
    299 				/*
    300 				 * This host bridge has a second PCI bus.
    301 				 * Configure it.
    302 				 */
    303 				doattach = 1;
    304 				break;
    305 			}
    306 			break;
    307 		case PCI_PRODUCT_INTEL_CDC:
    308 			bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
    309 					      I82424_CPU_BCTL_REG);
    310 			if (bcreg & I82424_BCTL_CPUPCI_POSTEN) {
    311 				bcreg &= ~I82424_BCTL_CPUPCI_POSTEN;
    312 				pci_conf_write(pa->pa_pc, pa->pa_tag,
    313 					       I82424_CPU_BCTL_REG, bcreg);
    314 				aprint_verbose_dev(self,
    315 				    "disabled CPU-PCI write posting\n");
    316 			}
    317 			break;
    318 		case PCI_PRODUCT_INTEL_82451NX_PXB:
    319 			/*
    320 			 * The NX chipset supports up to 2 "PXB" chips
    321 			 * which can drive 2 PCI buses each. Each bus
    322 			 * shows up as logical PCI device, with fixed
    323 			 * device numbers between 18 and 21.
    324 			 * See the datasheet at
    325 		ftp://download.intel.com/design/chipsets/datashts/24377102.pdf
    326 			 * for details.
    327 			 * (It would be easier to attach all the buses
    328 			 * at the MIOC, but less aesthetical imho.)
    329 			 */
    330 			if ((attachflags &
    331 			    (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) ==
    332 			    PCI_FLAGS_MEM_ENABLED)
    333 				attachflags |= PCI_FLAGS_IO_ENABLED;
    334 
    335 			pbnum = 0;
    336 			switch (pa->pa_device) {
    337 			case 18: /* PXB 0 bus A - primary bus */
    338 				break;
    339 			case 19: /* PXB 0 bus B */
    340 				/* read SUBA0 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 & 0x0000ff00) >> 8) + 1;
    344 				break;
    345 			case 20: /* PXB 1 bus A */
    346 				/* read BUSNO1 from MIOC */
    347 				tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
    348 				bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
    349 				pbnum = (bcreg & 0xff000000) >> 24;
    350 				break;
    351 			case 21: /* PXB 1 bus B */
    352 				/* read SUBA1 from MIOC */
    353 				tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
    354 				bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4);
    355 				pbnum = (bcreg & 0x000000ff) + 1;
    356 				break;
    357 			}
    358 			if (pbnum != 0)
    359 				doattach = 1;
    360 			break;
    361 
    362 		/*
    363 		 * i386 and amd64 stuff.
    364 		 */
    365 		case PCI_PRODUCT_INTEL_82810_MCH:
    366 		case PCI_PRODUCT_INTEL_82810_DC100_MCH:
    367 		case PCI_PRODUCT_INTEL_82810E_MCH:
    368 		case PCI_PRODUCT_INTEL_82815_FULL_HUB:
    369 		case PCI_PRODUCT_INTEL_82830MP_IO_1:
    370 		case PCI_PRODUCT_INTEL_82845G_DRAM:
    371 		case PCI_PRODUCT_INTEL_82855GM_MCH:
    372 		case PCI_PRODUCT_INTEL_82865_HB:
    373 		case PCI_PRODUCT_INTEL_82915G_HB:
    374 		case PCI_PRODUCT_INTEL_82915GM_HB:
    375 		case PCI_PRODUCT_INTEL_82945P_MCH:
    376 		case PCI_PRODUCT_INTEL_82945GM_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 			/*
    385 			 * The host bridge is either in GFX mode (internal
    386 			 * graphics) or in AGP mode. In GFX mode, we pretend
    387 			 * to have AGP because the graphics memory access
    388 			 * is very similar and the AGP GATT code will
    389 			 * deal with this. In the latter case, the
    390 			 * pci_get_capability(PCI_CAP_AGP) test below will
    391 			 * fire, so we do no harm by already setting the flag.
    392 			 */
    393 			has_agp = 1;
    394 			break;
    395 		}
    396 		break;
    397 	}
    398 
    399 #if NRND > 0
    400 	/*
    401 	 * Attach a random number generator, if there is one.
    402 	 */
    403 	pchb_attach_rnd(sc, pa);
    404 #endif
    405 
    406 	if (!pmf_device_register(self, pchb_suspend, pchb_resume))
    407 		aprint_error_dev(self, "couldn't establish power handler\n");
    408 
    409 	/*
    410 	 * If we haven't detected AGP yet (via a product ID),
    411 	 * then check for AGP capability on the device.
    412 	 */
    413 	if (has_agp ||
    414 	    pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
    415 			       NULL, NULL) != 0) {
    416 		apa.apa_pci_args = *pa;
    417 		config_found_ia(self, "agpbus", &apa, agpbusprint);
    418 	}
    419 
    420 	if (doattach) {
    421 		pba.pba_iot = pa->pa_iot;
    422 		pba.pba_memt = pa->pa_memt;
    423 		pba.pba_dmat = pa->pa_dmat;
    424 		pba.pba_dmat64 = pa->pa_dmat64;
    425 		pba.pba_pc = pa->pa_pc;
    426 		pba.pba_flags = attachflags;
    427 		pba.pba_bus = pbnum;
    428 		pba.pba_bridgetag = NULL;
    429 		pba.pba_pc = pa->pa_pc;
    430 		pba.pba_intrswiz = 0;
    431 		memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag));
    432 		config_found_ia(self, "pcibus", &pba, pcibusprint);
    433 	}
    434 }
    435 
    436 int
    437 pchbdetach(device_t self, int flags)
    438 {
    439 	int rc;
    440 #if NRND > 0
    441 	struct pchb_softc *sc = device_private(self);
    442 #endif
    443 
    444 	if ((rc = config_detach_children(self, flags)) != 0)
    445 		return rc;
    446 
    447 	pmf_device_deregister(self);
    448 
    449 #if NRND > 0
    450 	/*
    451 	 * Attach a random number generator, if there is one.
    452 	 */
    453 	pchb_detach_rnd(sc);
    454 #endif
    455 	return 0;
    456 }
    457 
    458 static bool
    459 pchb_suspend(device_t dv PMF_FN_ARGS)
    460 {
    461 	struct pchb_softc *sc = device_private(dv);
    462 	pci_chipset_tag_t pc;
    463 	pcitag_t tag;
    464 	int off;
    465 
    466 	pc = sc->sc_pc;
    467 	tag = sc->sc_tag;
    468 
    469 	for (off = 0x40; off <= 0xff; off += 4)
    470 		sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off);
    471 
    472 	return true;
    473 }
    474 
    475 static bool
    476 pchb_resume(device_t dv PMF_FN_ARGS)
    477 {
    478 	struct pchb_softc *sc = device_private(dv);
    479 	pci_chipset_tag_t pc;
    480 	pcitag_t tag;
    481 	int off;
    482 
    483 	pc = sc->sc_pc;
    484 	tag = sc->sc_tag;
    485 
    486 	for (off = 0x40; off <= 0xff; off += 4)
    487 		pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]);
    488 
    489 	return true;
    490 }
    491