1 /* $NetBSD: pchb.c,v 1.2 2007/10/30 12:20:03 jnemeth 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.2 2007/10/30 12:20:03 jnemeth Exp $"); 41 42 #include <sys/types.h> 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/device.h> 46 47 #include <machine/bus.h> 48 49 #include <dev/pci/pcivar.h> 50 #include <dev/pci/pcireg.h> 51 52 #include <dev/pci/pcidevs.h> 53 54 #include <dev/pci/agpreg.h> 55 #include <dev/pci/agpvar.h> 56 57 #include <arch/x86/pci/pchbvar.h> 58 59 #include "rnd.h" 60 61 #define PCISET_BRIDGETYPE_MASK 0x3 62 #define PCISET_TYPE_COMPAT 0x1 63 #define PCISET_TYPE_AUX 0x2 64 65 #define PCISET_BUSCONFIG_REG 0x48 66 #define PCISET_BRIDGE_NUMBER(reg) (((reg) >> 8) & 0xff) 67 #define PCISET_PCI_BUS_NUMBER(reg) (((reg) >> 16) & 0xff) 68 69 /* XXX should be in dev/ic/i82443reg.h */ 70 #define I82443BX_SDRAMC_REG 0x76 71 72 /* XXX should be in dev/ic/i82424{reg.var}.h */ 73 #define I82424_CPU_BCTL_REG 0x53 74 #define I82424_PCI_BCTL_REG 0x54 75 76 #define I82424_BCTL_CPUMEM_POSTEN 0x01 77 #define I82424_BCTL_CPUPCI_POSTEN 0x02 78 #define I82424_BCTL_PCIMEM_BURSTEN 0x01 79 #define I82424_BCTL_PCI_BURSTEN 0x02 80 81 int pchbmatch(struct device *, struct cfdata *, void *); 82 void pchbattach(struct device *, struct device *, void *); 83 84 CFATTACH_DECL(pchb, sizeof(struct pchb_softc), 85 pchbmatch, pchbattach, NULL, NULL); 86 87 int 88 pchbmatch(struct device *parent, struct cfdata *match, void *aux) 89 { 90 struct pci_attach_args *pa = aux; 91 92 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 93 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) 94 return 1; 95 96 return 0; 97 } 98 99 void 100 pchbattach(struct device *parent, struct device *self, void *aux) 101 { 102 #if NRND > 0 103 struct pchb_softc *sc = (void *) self; 104 #endif 105 struct pci_attach_args *pa = aux; 106 char devinfo[256]; 107 struct pcibus_attach_args pba; 108 struct agpbus_attach_args apa; 109 pcireg_t bcreg; 110 u_char bdnum, pbnum = 0; /* XXX: gcc */ 111 pcitag_t tag; 112 int doattach, attachflags, has_agp; 113 114 aprint_naive("\n"); 115 aprint_normal("\n"); 116 117 doattach = 0; 118 has_agp = 0; 119 attachflags = pa->pa_flags; 120 121 /* 122 * Print out a description, and configure certain chipsets which 123 * have auxiliary PCI buses. 124 */ 125 126 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 127 aprint_normal("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo, 128 PCI_REVISION(pa->pa_class)); 129 130 switch (PCI_VENDOR(pa->pa_id)) { 131 /* 132 * i386 stuff. 133 */ 134 case PCI_VENDOR_SERVERWORKS: 135 pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff; 136 137 if (pbnum == 0) 138 break; 139 140 /* 141 * This host bridge has a second PCI bus. 142 * Configure it. 143 */ 144 switch (PCI_PRODUCT(pa->pa_id)) { 145 case PCI_PRODUCT_SERVERWORKS_CSB5: 146 case PCI_PRODUCT_SERVERWORKS_CSB6: 147 /* These devices show up as host bridges, but are 148 really southbridges. */ 149 break; 150 case PCI_PRODUCT_SERVERWORKS_CMIC_HE: 151 case PCI_PRODUCT_SERVERWORKS_CMIC_LE: 152 case PCI_PRODUCT_SERVERWORKS_CMIC_SL: 153 /* CNBs and CIOBs are connected to these using a 154 private bus. The bus number register is that of 155 the first PCI bus hanging off the CIOB. We let 156 the CIOB attachment handle configuring the PCI 157 buses. */ 158 break; 159 default: 160 aprint_error("%s: unknown ServerWorks chip ID " 161 "0x%04x; trying to attach PCI buses behind it\n", 162 self->dv_xname, PCI_PRODUCT(pa->pa_id)); 163 /* FALLTHROUGH */ 164 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP: 165 case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI: 166 case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI: 167 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI: 168 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP: 169 case PCI_PRODUCT_SERVERWORKS_CIOB_X: 170 case PCI_PRODUCT_SERVERWORKS_CNB30_HE: 171 case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2: 172 case PCI_PRODUCT_SERVERWORKS_CIOB_X2: 173 case PCI_PRODUCT_SERVERWORKS_CIOB_E: 174 switch (attachflags & 175 (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) { 176 case 0: 177 /* Doesn't smell like there's anything there. */ 178 break; 179 case PCI_FLAGS_MEM_ENABLED: 180 attachflags |= PCI_FLAGS_IO_ENABLED; 181 /* FALLTHROUGH */ 182 default: 183 doattach = 1; 184 break; 185 } 186 break; 187 } 188 break; 189 case PCI_VENDOR_INTEL: 190 switch (PCI_PRODUCT(pa->pa_id)) { 191 case PCI_PRODUCT_INTEL_82452_PB: 192 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40); 193 pbnum = PCISET_BRIDGE_NUMBER(bcreg); 194 if (pbnum != 0xff) { 195 pbnum++; 196 doattach = 1; 197 } 198 break; 199 case PCI_PRODUCT_INTEL_82443BX_AGP: 200 case PCI_PRODUCT_INTEL_82443BX_NOAGP: 201 /* 202 * http://www.intel.com/design/chipsets/specupdt/290639.htm 203 * says this bug is fixed in steppings >= C0 (erratum 11), 204 * so don't tweak the bits in that case. 205 */ 206 if (!(PCI_REVISION(pa->pa_class) >= 0x03)) { 207 /* 208 * BIOS BUG WORKAROUND! The 82443BX 209 * datasheet indicates that the only 210 * legal setting for the "Idle/Pipeline 211 * DRAM Leadoff Timing (IPLDT)" parameter 212 * (bits 9:8) is 01. Unfortunately, some 213 * BIOSs do not set these bits properly. 214 */ 215 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 216 I82443BX_SDRAMC_REG); 217 if ((bcreg & 0x0300) != 0x0100) { 218 aprint_verbose("%s: fixing " 219 "Idle/Pipeline DRAM " 220 "Leadoff Timing\n", self->dv_xname); 221 bcreg &= ~0x0300; 222 bcreg |= 0x0100; 223 pci_conf_write(pa->pa_pc, pa->pa_tag, 224 I82443BX_SDRAMC_REG, bcreg); 225 } 226 } 227 break; 228 229 case PCI_PRODUCT_INTEL_PCI450_PB: 230 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 231 PCISET_BUSCONFIG_REG); 232 bdnum = PCISET_BRIDGE_NUMBER(bcreg); 233 pbnum = PCISET_PCI_BUS_NUMBER(bcreg); 234 switch (bdnum & PCISET_BRIDGETYPE_MASK) { 235 default: 236 aprint_error("%s: bdnum=%x (reserved)\n", 237 self->dv_xname, bdnum); 238 break; 239 case PCISET_TYPE_COMPAT: 240 aprint_verbose( 241 "%s: Compatibility PB (bus %d)\n", 242 self->dv_xname, pbnum); 243 break; 244 case PCISET_TYPE_AUX: 245 aprint_verbose("%s: Auxiliary PB (bus %d)\n", 246 self->dv_xname, pbnum); 247 /* 248 * This host bridge has a second PCI bus. 249 * Configure it. 250 */ 251 doattach = 1; 252 break; 253 } 254 break; 255 case PCI_PRODUCT_INTEL_CDC: 256 bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 257 I82424_CPU_BCTL_REG); 258 if (bcreg & I82424_BCTL_CPUPCI_POSTEN) { 259 bcreg &= ~I82424_BCTL_CPUPCI_POSTEN; 260 pci_conf_write(pa->pa_pc, pa->pa_tag, 261 I82424_CPU_BCTL_REG, bcreg); 262 aprint_verbose( 263 "%s: disabled CPU-PCI write posting\n", 264 self->dv_xname); 265 } 266 break; 267 case PCI_PRODUCT_INTEL_82451NX_PXB: 268 /* 269 * The NX chipset supports up to 2 "PXB" chips 270 * which can drive 2 PCI buses each. Each bus 271 * shows up as logical PCI device, with fixed 272 * device numbers between 18 and 21. 273 * See the datasheet at 274 ftp://download.intel.com/design/chipsets/datashts/24377102.pdf 275 * for details. 276 * (It would be easier to attach all the buses 277 * at the MIOC, but less aesthetical imho.) 278 */ 279 if ((attachflags & 280 (PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED)) == 281 PCI_FLAGS_MEM_ENABLED) 282 attachflags |= PCI_FLAGS_IO_ENABLED; 283 284 pbnum = 0; 285 switch (pa->pa_device) { 286 case 18: /* PXB 0 bus A - primary bus */ 287 break; 288 case 19: /* PXB 0 bus B */ 289 /* read SUBA0 from MIOC */ 290 tag = pci_make_tag(pa->pa_pc, 0, 16, 0); 291 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0); 292 pbnum = ((bcreg & 0x0000ff00) >> 8) + 1; 293 break; 294 case 20: /* PXB 1 bus A */ 295 /* read BUSNO1 from MIOC */ 296 tag = pci_make_tag(pa->pa_pc, 0, 16, 0); 297 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0); 298 pbnum = (bcreg & 0xff000000) >> 24; 299 break; 300 case 21: /* PXB 1 bus B */ 301 /* read SUBA1 from MIOC */ 302 tag = pci_make_tag(pa->pa_pc, 0, 16, 0); 303 bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4); 304 pbnum = (bcreg & 0x000000ff) + 1; 305 break; 306 } 307 if (pbnum != 0) 308 doattach = 1; 309 break; 310 311 /* 312 * i386 and amd64 stuff. 313 */ 314 case PCI_PRODUCT_INTEL_82810_MCH: 315 case PCI_PRODUCT_INTEL_82810_DC100_MCH: 316 case PCI_PRODUCT_INTEL_82810E_MCH: 317 case PCI_PRODUCT_INTEL_82815_FULL_HUB: 318 case PCI_PRODUCT_INTEL_82830MP_IO_1: 319 case PCI_PRODUCT_INTEL_82845G_DRAM: 320 case PCI_PRODUCT_INTEL_82855GM_MCH: 321 case PCI_PRODUCT_INTEL_82865_HB: 322 case PCI_PRODUCT_INTEL_82915G_HB: 323 case PCI_PRODUCT_INTEL_82915GM_HB: 324 case PCI_PRODUCT_INTEL_82945P_MCH: 325 case PCI_PRODUCT_INTEL_82945GM_HB: 326 case PCI_PRODUCT_INTEL_82965Q_HB: 327 case PCI_PRODUCT_INTEL_82965G_HB: 328 /* 329 * The host bridge is either in GFX mode (internal 330 * graphics) or in AGP mode. In GFX mode, we pretend 331 * to have AGP because the graphics memory access 332 * is very similar and the AGP GATT code will 333 * deal with this. In the latter case, the 334 * pci_get_capability(PCI_CAP_AGP) test below will 335 * fire, so we do no harm by already setting the flag. 336 */ 337 has_agp = 1; 338 break; 339 } 340 break; 341 } 342 343 #if NRND > 0 344 /* 345 * Attach a random number generator, if there is one. 346 */ 347 pchb_attach_rnd(sc, pa); 348 #endif 349 350 /* 351 * If we haven't detected AGP yet (via a product ID), 352 * then check for AGP capability on the device. 353 */ 354 if (has_agp || 355 pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, 356 NULL, NULL) != 0) { 357 apa.apa_pci_args = *pa; 358 config_found_ia(self, "agpbus", &apa, agpbusprint); 359 } 360 361 if (doattach) { 362 pba.pba_iot = pa->pa_iot; 363 pba.pba_memt = pa->pa_memt; 364 pba.pba_dmat = pa->pa_dmat; 365 pba.pba_dmat64 = pa->pa_dmat64; 366 pba.pba_pc = pa->pa_pc; 367 pba.pba_flags = attachflags; 368 pba.pba_bus = pbnum; 369 pba.pba_bridgetag = NULL; 370 pba.pba_pc = pa->pa_pc; 371 pba.pba_intrswiz = 0; 372 memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag)); 373 config_found_ia(self, "pcibus", &pba, pcibusprint); 374 } 375 } 376