summaryrefslogtreecommitdiff
path: root/src/ati.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ati.c')
-rw-r--r--src/ati.c361
1 files changed, 112 insertions, 249 deletions
diff --git a/src/ati.c b/src/ati.c
index 89e62dc..b3f07ca 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -66,11 +66,8 @@
#include "ativersion.h"
/* names duplicated from version headers */
-#define MACH64_NAME "MACH64"
#define MACH64_DRIVER_NAME "mach64"
-#define R128_NAME "R128"
#define R128_DRIVER_NAME "r128"
-#define RADEON_NAME "RADEON"
#define RADEON_DRIVER_NAME "radeon"
enum
@@ -81,304 +78,170 @@ enum
ATI_CHIP_FAMILY_Radeon
};
-/*
- * Record which sub-drivers have already been loaded, and thus have called
- * xf86AddDriver(). For those sub-drivers, cause the ati wrapper later to fail
- * when probing.
- *
- * The check is only called once when the ati wrapper is loaded and depends on
- * the X server loading all drivers before doing any probes.
- */
-static Bool mach64_drv_added = FALSE;
-static Bool r128_drv_added = FALSE;
-static Bool radeon_drv_added = FALSE;
-
-void
-ati_check_subdriver_added()
-{
- if (LoaderSymbol(MACH64_NAME))
- mach64_drv_added = TRUE;
- if (LoaderSymbol(R128_NAME))
- r128_drv_added = TRUE;
- if (LoaderSymbol(RADEON_NAME))
- radeon_drv_added = TRUE;
-}
-
static int ATIChipID(const CARD16);
#ifdef XSERVER_LIBPCIACCESS
-static const struct pci_id_match ati_device_match = {
- PCI_VENDOR_ATI, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0
-};
-/* Stolen from xf86pciBus.c */
-/* PCI classes that get included in xf86PciVideoInfo */
-#define PCIINFOCLASSES(c) \
- ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) || \
- (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) || \
- ((((c) & 0x00ffff00) == ((PCI_CLASS_MULTIMEDIA << 16) | \
- (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) || \
- ((((c) & 0x00ffff00) == ((PCI_CLASS_PROCESSOR << 16) | \
- (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
+/* domain defines (stolen from xserver) */
+#if (defined(__alpha__) || defined(__ia64__)) && defined (linux)
+# define PCI_DOM_MASK 0x01fful
+#else
+# define PCI_DOM_MASK 0x0ffu
#endif
-/*
- * ATIIdentify --
- *
- * Print the driver's list of chipset names.
- */
-static void
-ATIIdentify
-(
- int flags
-)
+#define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK))
+#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
+
+static struct pci_device*
+ati_device_get_from_busid(int bus, int dev, int func)
{
- /*
- * Only print chip families here, chip lists are printed when a subdriver
- * is loaded.
- */
- xf86Msg(X_INFO, "%s: %s\n", ATI_NAME,
- "ATI driver wrapper (version " ATI_VERSION_NAME ") for chipsets: "
- "mach64, rage128, radeon");
+ return pci_device_find_by_slot(PCI_DOM_FROM_BUS(bus),
+ PCI_BUS_NO_DOMAIN(bus),
+ dev,
+ func);
}
-/*
- * ATIProbe --
- *
- * This function is called once, at the start of the first server generation to
- * do a minimal probe for supported hardware.
- */
-static Bool
-ATIProbe
-(
- DriverPtr pDriver,
- int flags
-)
+static struct pci_device*
+ati_device_get_primary()
{
- pciVideoPtr pVideo;
-#ifndef XSERVER_LIBPCIACCESS
- pciVideoPtr *xf86PciVideoInfo;
-#else
- struct pci_device_iterator *pVideoIter;
-#endif
- Bool DoMach64 = FALSE;
- Bool DoRage128 = FALSE, DoRadeon = FALSE;
- int Chip;
+ struct pci_device *device = NULL;
+ struct pci_device_iterator *device_iter;
- /* Let the sub-drivers probe & configure for themselves */
- if (xf86ServerIsOnlyDetecting())
- return FALSE;
+ device_iter = pci_slot_match_iterator_create(NULL);
+
+ while ((device = pci_device_next(device_iter)) != NULL) {
+ if (xf86IsPrimaryPci(device))
+ break;
+ }
+
+ pci_iterator_destroy(device_iter);
+
+ return device;
+}
+
+#else /* XSERVER_LIBPCIACCESS */
-#ifndef XSERVER_LIBPCIACCESS
+static pciVideoPtr
+ati_device_get_from_busid(int bus, int dev, int func)
+{
+ pciVideoPtr pVideo = NULL;
+ pciVideoPtr *xf86PciVideoInfo;
xf86PciVideoInfo = xf86GetPciVideoInfo();
if (xf86PciVideoInfo == NULL)
- return FALSE;
+ return NULL;
while ((pVideo = *xf86PciVideoInfo++) != NULL)
{
- if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
- (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
- continue;
-
- /* Check for Rage128's, Radeon's and later adapters */
- Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo));
- if (Chip == ATI_CHIP_FAMILY_Mach64)
- DoMach64 = TRUE;
- else if (Chip == ATI_CHIP_FAMILY_Rage128)
- DoRage128 = TRUE;
- else if (Chip == ATI_CHIP_FAMILY_Radeon)
- DoRadeon = TRUE;
+ if ((pVideo->bus == bus) && (pVideo->device == dev) &&
+ (pVideo->func == func))
+ break;
}
-#else /* XSERVER_LIBPCIACCESS */
+ return pVideo;
+}
- pVideoIter = pci_id_match_iterator_create(&ati_device_match);
+static pciVideoPtr
+ati_device_get_primary()
+{
+ pciVideoPtr pVideo = NULL;
+ pciVideoPtr *xf86PciVideoInfo;
- while ((pVideo = pci_device_next(pVideoIter)) != NULL)
- {
- /* Check for non-video devices */
- if (!PCIINFOCLASSES(pVideo->device_class))
- continue;
+ xf86PciVideoInfo = xf86GetPciVideoInfo();
- /* Check for prehistoric PCI Mach32 */
- if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
- (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
- continue;
+ if (xf86PciVideoInfo == NULL)
+ return NULL;
- /* Check for Rage128's, Radeon's and later adapters */
- Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo));
- if (Chip == ATI_CHIP_FAMILY_Mach64)
- DoMach64 = TRUE;
- else if (Chip == ATI_CHIP_FAMILY_Rage128)
- DoRage128 = TRUE;
- else if (Chip == ATI_CHIP_FAMILY_Radeon)
- DoRadeon = TRUE;
+ while ((pVideo = *xf86PciVideoInfo++) != NULL)
+ {
+ if (xf86IsPrimaryPci(pVideo))
+ break;
}
- pci_iterator_destroy(pVideoIter);
+ return pVideo;
+}
#endif /* XSERVER_LIBPCIACCESS */
- /* Call Radeon driver probe */
- if (DoRadeon)
- {
- DriverRec *radeon;
-
- /* If the sub-driver was added, let it probe for itself */
- if (radeon_drv_added)
- return FALSE;
-
- if (!LoaderSymbol(RADEON_NAME))
- xf86LoadDrvSubModule(pDriver, RADEON_DRIVER_NAME);
-
- radeon = (DriverRec*)LoaderSymbol(RADEON_NAME);
-
- if (!radeon)
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to find \"radeon\" driver symbol.\n");
- return FALSE;
- }
-
- radeon->Identify(flags);
+void
+ati_gdev_subdriver(pointer options)
+{
+ int nATIGDev, nMach64GDev, nR128GDev, nRadeonGDev;
+ GDevPtr *ATIGDevs;
+ Bool load_mach64 = FALSE, load_r128 = FALSE, load_radeon = FALSE;
+ int i;
- if (radeon->Probe(pDriver, flags))
- return TRUE;
- }
+ /* let the subdrivers configure for themselves */
+ if (xf86ServerIsOnlyDetecting())
+ return;
- /* Call Rage 128 driver probe */
- if (DoRage128)
- {
- DriverRec *r128;
+ /* get Device sections with Driver "ati" */
+ nATIGDev = xf86MatchDevice(ATI_DRIVER_NAME, &ATIGDevs);
+ nMach64GDev = xf86MatchDevice(MACH64_DRIVER_NAME, NULL);
+ nR128GDev = xf86MatchDevice(R128_DRIVER_NAME, NULL);
+ nRadeonGDev = xf86MatchDevice(RADEON_DRIVER_NAME, NULL);
- /* If the sub-driver was added, let it probe for itself */
- if (r128_drv_added)
- return FALSE;
+ for (i = 0; i < nATIGDev; i++) {
+ GDevPtr ati_gdev = ATIGDevs[i];
+ pciVideoPtr device = NULL;
+ int chip_family;
- if (!LoaderSymbol(R128_NAME))
- xf86LoadDrvSubModule(pDriver, R128_DRIVER_NAME);
+ /* get pci device for the Device section */
+ if (ati_gdev->busID) {
+ int bus, dev, func;
- r128 = (DriverRec*)LoaderSymbol(R128_NAME);
+ if (!xf86ParsePciBusString(ati_gdev->busID, &bus, &dev, &func))
+ continue;
- if (!r128)
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to find \"r128\" driver symbol.\n");
- return FALSE;
+ device = ati_device_get_from_busid(bus, dev, func);
}
-
- r128->Identify(flags);
-
- if (r128->Probe(pDriver, flags))
- return TRUE;
- }
-
- /* Call Mach64 driver probe */
- if (DoMach64)
- {
- DriverRec *mach64;
-
- /* If the sub-driver was added, let it probe for itself */
- if (mach64_drv_added)
- return FALSE;
-
- if (!LoaderSymbol(MACH64_NAME))
- xf86LoadDrvSubModule(pDriver, MACH64_DRIVER_NAME);
-
- mach64 = (DriverRec*)LoaderSymbol(MACH64_NAME);
-
- if (!mach64)
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to find \"mach64\" driver symbol.\n");
- return FALSE;
+ else {
+ device = ati_device_get_primary();
}
- mach64->Identify(flags);
-
- if (mach64->Probe(pDriver, flags))
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*
- * ATIAvailableOptions --
- *
- * Return recognised options that are intended for public consumption.
- */
-static const OptionInfoRec *
-ATIAvailableOptions
-(
- int ChipId,
- int BusId
-)
-{
- CARD16 ChipType = ChipId & 0xffff;
- int Chip;
+ if (!device)
+ continue;
- /* Probe should have loaded the appropriate subdriver by this point */
+ /* check for non-ati devices and prehistoric mach32 */
+ if ((PCI_DEV_VENDOR_ID(device) != PCI_VENDOR_ATI) ||
+ (PCI_DEV_DEVICE_ID(device) == PCI_CHIP_MACH32))
+ continue;
- Chip = ATIChipID(ChipType);
- if (Chip == ATI_CHIP_FAMILY_Mach64)
- {
- DriverRec *mach64 = (DriverRec*)LoaderSymbol(MACH64_NAME);
+ /* replace Driver line in the Device section */
+ chip_family = ATIChipID(PCI_DEV_DEVICE_ID(device));
- if (!mach64)
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to find \"mach64\" driver symbol.\n");
- return NULL;
+ if (chip_family == ATI_CHIP_FAMILY_Mach64) {
+ ati_gdev->driver = MACH64_DRIVER_NAME;
+ load_mach64 = TRUE;
}
- return mach64->AvailableOptions(ChipId, BusId);
- }
-
- if (Chip == ATI_CHIP_FAMILY_Rage128)
- {
- DriverRec *r128 = (DriverRec*)LoaderSymbol(R128_NAME);
-
- if (!r128)
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to find \"r128\" driver symbol.\n");
- return NULL;
+ if (chip_family == ATI_CHIP_FAMILY_Rage128) {
+ ati_gdev->driver = R128_DRIVER_NAME;
+ load_r128 = TRUE;
}
- return r128->AvailableOptions(ChipId, BusId);
+ if (chip_family == ATI_CHIP_FAMILY_Radeon) {
+ ati_gdev->driver = RADEON_DRIVER_NAME;
+ load_radeon = TRUE;
+ }
}
- if (Chip == ATI_CHIP_FAMILY_Radeon)
- {
- DriverRec *radeon = (DriverRec*)LoaderSymbol(RADEON_NAME);
+ xfree(ATIGDevs);
- if (!radeon)
- {
- xf86Msg(X_ERROR,
- ATI_NAME ": Failed to find \"radeon\" driver symbol.\n");
- return NULL;
- }
+ /* load subdrivers as primary modules and only if they do not get loaded
+ * from other device sections
+ */
- return radeon->AvailableOptions(ChipId, BusId);
- }
+ if (load_mach64 && (nMach64GDev == 0))
+ xf86LoadOneModule(MACH64_DRIVER_NAME, options);
- return NULL;
-}
+ if (load_r128 && (nR128GDev == 0))
+ xf86LoadOneModule(R128_DRIVER_NAME, options);
-/* The root of all evil... */
-_X_EXPORT DriverRec ATI =
-{
- ATI_VERSION_CURRENT,
- "ati",
- ATIIdentify,
- ATIProbe,
- ATIAvailableOptions,
- NULL,
- 0
-};
+ if (load_radeon && (nRadeonGDev == 0))
+ xf86LoadOneModule(RADEON_DRIVER_NAME, options);
+}
/*
* ATIChipID --