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