|
@@ -1717,41 +1717,92 @@ static const struct agp_bridge_driver intel_7505_driver = {
|
|
|
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
|
|
|
};
|
|
|
|
|
|
-static int find_i810(u16 device)
|
|
|
-{
|
|
|
- struct pci_dev *i810_dev;
|
|
|
|
|
|
- i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
|
|
|
- if (!i810_dev)
|
|
|
- return 0;
|
|
|
- intel_private.pcidev = i810_dev;
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-static int find_i830(u16 device)
|
|
|
+static int find_gmch(u16 device)
|
|
|
{
|
|
|
- struct pci_dev *i830_dev;
|
|
|
+ struct pci_dev *gmch_device;
|
|
|
|
|
|
- i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
|
|
|
- if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
|
|
|
- i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
|
|
- device, i830_dev);
|
|
|
+ gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
|
|
|
+ if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
|
|
|
+ gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
|
|
|
+ device, gmch_device);
|
|
|
}
|
|
|
|
|
|
- if (!i830_dev)
|
|
|
+ if (!gmch_device)
|
|
|
return 0;
|
|
|
|
|
|
- intel_private.pcidev = i830_dev;
|
|
|
+ intel_private.pcidev = gmch_device;
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
|
|
|
+ * driver and gmch_driver must be non-null, and find_gmch will determine
|
|
|
+ * which one should be used if a gmch_chip_id is present.
|
|
|
+ */
|
|
|
+static const struct intel_driver_description {
|
|
|
+ unsigned int chip_id;
|
|
|
+ unsigned int gmch_chip_id;
|
|
|
+ char *name;
|
|
|
+ const struct agp_bridge_driver *driver;
|
|
|
+ const struct agp_bridge_driver *gmch_driver;
|
|
|
+} intel_agp_chipsets[] = {
|
|
|
+ { PCI_DEVICE_ID_INTEL_82443LX_0, 0, "440LX", &intel_generic_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82443BX_0, 0, "440BX", &intel_generic_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82443GX_0, 0, "440GX", &intel_generic_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, "i810",
|
|
|
+ NULL, &intel_810_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, "i810",
|
|
|
+ NULL, &intel_810_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, "i810",
|
|
|
+ NULL, &intel_810_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, "i815",
|
|
|
+ &intel_810_driver, &intel_815_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82820_HB, 0, "i820", &intel_820_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, "i820", &intel_820_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, "830M",
|
|
|
+ &intel_830mp_driver, &intel_830_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82840_HB, 0, "i840", &intel_840_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82845_HB, 0, "845G", &intel_845_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, "830M",
|
|
|
+ &intel_845_driver, &intel_830_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82850_HB, 0, "i850", &intel_850_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, "855PM", &intel_845_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM",
|
|
|
+ &intel_845_driver, &intel_830_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82860_HB, 0, "i860", &intel_860_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, "865",
|
|
|
+ &intel_845_driver, &intel_830_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82875_HB, 0, "i875", &intel_845_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, "915G",
|
|
|
+ &intel_845_driver, &intel_915_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM",
|
|
|
+ &intel_845_driver, &intel_915_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, "945G",
|
|
|
+ &intel_845_driver, &intel_915_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM",
|
|
|
+ &intel_845_driver, &intel_915_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ",
|
|
|
+ &intel_845_driver, &intel_i965_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82965G_1_HB, PCI_DEVICE_ID_INTEL_82965G_1_IG, "965G",
|
|
|
+ &intel_845_driver, &intel_i965_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q",
|
|
|
+ &intel_845_driver, &intel_i965_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, "965G",
|
|
|
+ &intel_845_driver, &intel_i965_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM",
|
|
|
+ &intel_845_driver, &intel_i965_driver },
|
|
|
+ { PCI_DEVICE_ID_INTEL_7505_0, 0, "E7505", &intel_7505_driver, NULL },
|
|
|
+ { PCI_DEVICE_ID_INTEL_7205_0, 0, "E7205", &intel_7505_driver, NULL },
|
|
|
+ { 0, 0, NULL, NULL, NULL }
|
|
|
+};
|
|
|
+
|
|
|
static int __devinit agp_intel_probe(struct pci_dev *pdev,
|
|
|
const struct pci_device_id *ent)
|
|
|
{
|
|
|
struct agp_bridge_data *bridge;
|
|
|
- char *name = "(unknown)";
|
|
|
u8 cap_ptr = 0;
|
|
|
struct resource *r;
|
|
|
+ int i;
|
|
|
|
|
|
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
|
|
|
|
|
@@ -1759,191 +1810,42 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
|
|
|
if (!bridge)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- switch (pdev->device) {
|
|
|
- case PCI_DEVICE_ID_INTEL_82443LX_0:
|
|
|
- bridge->driver = &intel_generic_driver;
|
|
|
- name = "440LX";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82443BX_0:
|
|
|
- bridge->driver = &intel_generic_driver;
|
|
|
- name = "440BX";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82443GX_0:
|
|
|
- bridge->driver = &intel_generic_driver;
|
|
|
- name = "440GX";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82810_MC1:
|
|
|
- name = "i810";
|
|
|
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
|
|
|
- goto fail;
|
|
|
- bridge->driver = &intel_810_driver;
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82810_MC3:
|
|
|
- name = "i810 DC100";
|
|
|
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
|
|
|
- goto fail;
|
|
|
- bridge->driver = &intel_810_driver;
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82810E_MC:
|
|
|
- name = "i810 E";
|
|
|
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
|
|
|
- goto fail;
|
|
|
- bridge->driver = &intel_810_driver;
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82815_MC:
|
|
|
- /*
|
|
|
- * The i815 can operate either as an i810 style
|
|
|
- * integrated device, or as an AGP4X motherboard.
|
|
|
- */
|
|
|
- if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
|
|
|
- bridge->driver = &intel_810_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_815_driver;
|
|
|
- name = "i815";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82820_HB:
|
|
|
- case PCI_DEVICE_ID_INTEL_82820_UP_HB:
|
|
|
- bridge->driver = &intel_820_driver;
|
|
|
- name = "i820";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82830_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
|
|
|
- bridge->driver = &intel_830_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_830mp_driver;
|
|
|
- name = "830M";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82840_HB:
|
|
|
- bridge->driver = &intel_840_driver;
|
|
|
- name = "i840";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82845_HB:
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "i845";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82845G_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
|
|
|
- bridge->driver = &intel_830_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "845G";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82850_HB:
|
|
|
- bridge->driver = &intel_850_driver;
|
|
|
- name = "i850";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82855PM_HB:
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "855PM";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82855GM_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
|
|
|
- bridge->driver = &intel_830_driver;
|
|
|
- name = "855";
|
|
|
- } else {
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "855GM";
|
|
|
- }
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82860_HB:
|
|
|
- bridge->driver = &intel_860_driver;
|
|
|
- name = "i860";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82865_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
|
|
|
- bridge->driver = &intel_830_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "865";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82875_HB:
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "i875";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82915G_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
|
|
|
- bridge->driver = &intel_915_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "915G";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82915GM_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
|
|
|
- bridge->driver = &intel_915_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "915GM";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82945G_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
|
|
|
- bridge->driver = &intel_915_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "945G";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82945GM_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
|
|
|
- bridge->driver = &intel_915_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "945GM";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82946GZ_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
|
|
|
- bridge->driver = &intel_i965_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "946GZ";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82965G_1_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
|
|
|
- bridge->driver = &intel_i965_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "965G";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82965Q_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
|
|
|
- bridge->driver = &intel_i965_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "965Q";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82965G_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
|
|
|
- bridge->driver = &intel_i965_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "965G";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_82965GM_HB:
|
|
|
- if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
|
|
|
- bridge->driver = &intel_i965_driver;
|
|
|
- else
|
|
|
- bridge->driver = &intel_845_driver;
|
|
|
- name = "965GM";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_7505_0:
|
|
|
- bridge->driver = &intel_7505_driver;
|
|
|
- name = "E7505";
|
|
|
- break;
|
|
|
- case PCI_DEVICE_ID_INTEL_7205_0:
|
|
|
- bridge->driver = &intel_7505_driver;
|
|
|
- name = "E7205";
|
|
|
- break;
|
|
|
- default:
|
|
|
+ for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
|
|
|
+ /* In case that multiple models of gfx chip may
|
|
|
+ stand on same host bridge type, this can be
|
|
|
+ sure we detect the right IGD. */
|
|
|
+ if ((pdev->device == intel_agp_chipsets[i].chip_id) &&
|
|
|
+ ((intel_agp_chipsets[i].gmch_chip_id == 0) ||
|
|
|
+ find_gmch(intel_agp_chipsets[i].gmch_chip_id)))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (intel_agp_chipsets[i].name == NULL) {
|
|
|
if (cap_ptr)
|
|
|
- printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
|
|
|
- pdev->device);
|
|
|
+ printk(KERN_WARNING PFX "Unsupported Intel chipset"
|
|
|
+ "(device id: %04x)\n", pdev->device);
|
|
|
agp_put_bridge(bridge);
|
|
|
return -ENODEV;
|
|
|
- };
|
|
|
+ }
|
|
|
+
|
|
|
+ if (intel_agp_chipsets[i].gmch_chip_id != 0)
|
|
|
+ bridge->driver = intel_agp_chipsets[i].gmch_driver;
|
|
|
+ else
|
|
|
+ bridge->driver = intel_agp_chipsets[i].driver;
|
|
|
+
|
|
|
+ if (bridge->driver == NULL) {
|
|
|
+ printk(KERN_WARNING PFX "Failed to find bridge device "
|
|
|
+ "(chip_id: %04x)\n", intel_agp_chipsets[i].gmch_chip_id);
|
|
|
+ agp_put_bridge(bridge);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
|
|
|
bridge->dev = pdev;
|
|
|
bridge->capndx = cap_ptr;
|
|
|
bridge->dev_private_data = &intel_private;
|
|
|
|
|
|
- printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
|
|
|
+ printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n",
|
|
|
+ intel_agp_chipsets[i].name);
|
|
|
|
|
|
/*
|
|
|
* The following fixes the case where the BIOS has "forgotten" to
|
|
@@ -1979,12 +1881,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
|
|
|
|
|
|
pci_set_drvdata(pdev, bridge);
|
|
|
return agp_add_bridge(bridge);
|
|
|
-
|
|
|
-fail:
|
|
|
- printk(KERN_ERR PFX "Detected an Intel %s chipset, "
|
|
|
- "but could not find the secondary device.\n", name);
|
|
|
- agp_put_bridge(bridge);
|
|
|
- return -ENODEV;
|
|
|
}
|
|
|
|
|
|
static void __devexit agp_intel_remove(struct pci_dev *pdev)
|