From ffc5ba7f0b1cdefdcecf6bd47018b6a4924bfc44 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 22 Aug 2007 12:38:14 -0700 Subject: Merge PCI-rework support and "classic" PCI interface support into one tree First pass at merging both trees. So far, this has only been compile tested. I need to dig out a savage card to put in a system for testing, so it may take another hour or two. --- configure.ac | 13 ++- src/savage_dri.c | 8 +- src/savage_driver.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/savage_driver.h | 15 +++ 4 files changed, 313 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 16c19d0..04a4c3e 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,11 @@ AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri], [Disable DRI support [[default=auto]]]), [DRI="$enableval"], [DRI=auto]) +AC_ARG_ENABLE(pciaccess, + AS_HELP_STRING([--enable-pciaccess], + [Enable use of libpciaccess (default: disabled)]), + [PCIACCESS=$enableval], + [PCIACCESS=no]) # Checks for extensions XORG_DRIVER_CHECK_EXT(RANDR, randrproto) @@ -95,8 +100,12 @@ if test "$DRI" = yes; then AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support]) fi -PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0]) -XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" +AM_CONDITIONAL(PCIACCESS, [test "x$PCIACCESS" = xyes]) +if test "x$PCIACCESS" = xyes; then + AC_DEFINE(PCIACCESS, 1, [Use libpciaccess]) + PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.7.0]) + XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" +fi AC_SUBST([DRI_CFLAGS]) AC_SUBST([XORG_CFLAGS]) diff --git a/src/savage_dri.c b/src/savage_dri.c index 41e8bb1..aca0b8c 100644 --- a/src/savage_dri.c +++ b/src/savage_dri.c @@ -467,8 +467,8 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) xf86DrvMsg( pScreen->myNum, X_INFO, "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", mode, vendor, device, - psav->PciInfo->vendor_id, - psav->PciInfo->device_id ); + VENDOR_ID(psav->PciInfo), + DEVICE_ID(psav->PciInfo)); if ( drmAgpEnable( psav->drmFD, mode ) < 0 ) { xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); @@ -882,7 +882,11 @@ Bool SAVAGEDRIScreenInit( ScreenPtr pScreen ) sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", psav->PciInfo->bus, +#ifdef PCIACCESS psav->PciInfo->dev, +#else + psav->PciInfo->device, +#endif psav->PciInfo->func); } pDRIInfo->ddxDriverMajorVersion = SAVAGE_VERSION_MAJOR; diff --git a/src/savage_driver.c b/src/savage_driver.c index 9975119..4c4246b 100644 --- a/src/savage_driver.c +++ b/src/savage_driver.c @@ -72,8 +72,13 @@ static void SavageDisableMMIO(ScrnInfoPtr pScrn); static const OptionInfoRec * SavageAvailableOptions(int chipid, int busid); static void SavageIdentify(int flags); +#ifdef PCIACCESS static Bool SavagePciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, intptr_t match_data); +#else +static Bool SavageProbe(DriverPtr drv, int flags); +static int LookupChipID(PciChipsets* pset, int ChipID); +#endif static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags); static Bool SavageEnterVT(int scrnIndex, int flags); @@ -133,6 +138,7 @@ extern ScrnInfoPtr gpScrn; int gSavageEntityIndex = -1; +#ifdef PCIACCESS #define SAVAGE_DEVICE_MATCH(d, i) \ { 0x5333, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } @@ -163,6 +169,7 @@ static const struct pci_id_match savage_device_match[] = { { 0, 0, 0 }, }; +#endif /* Supported chipsets */ @@ -205,6 +212,37 @@ static SymTabRec SavageChipsets[] = { { -1, NULL } }; +#ifndef PCIACCESS +/* This table maps a PCI device ID to a chipset family identifier. */ + +static PciChipsets SavagePciChipsets[] = { + { S3_SAVAGE3D, PCI_CHIP_SAVAGE3D, RES_SHARED_VGA }, + { S3_SAVAGE3D, PCI_CHIP_SAVAGE3D_MV, RES_SHARED_VGA }, + { S3_SAVAGE4, PCI_CHIP_SAVAGE4, RES_SHARED_VGA }, + { S3_SAVAGE2000, PCI_CHIP_SAVAGE2000, RES_SHARED_VGA }, + { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_MX_MV, RES_SHARED_VGA }, + { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_MX, RES_SHARED_VGA }, + { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX_MV, RES_SHARED_VGA }, + { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX, RES_SHARED_VGA }, + { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_PM, RES_SHARED_VGA }, + { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_KM, RES_SHARED_VGA }, + { S3_TWISTER, PCI_CHIP_S3TWISTER_P, RES_SHARED_VGA }, + { S3_TWISTER, PCI_CHIP_S3TWISTER_K, RES_SHARED_VGA }, + { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDR, RES_SHARED_VGA }, + { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDRK, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX128, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64C, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX128SDR, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX128DDR, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX64SDR, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX64DDR, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IXCSDR, RES_SHARED_VGA }, + { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IXCDDR, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; +#endif + typedef enum { OPTION_PCI_BURST ,OPTION_PCI_RETRY @@ -280,14 +318,20 @@ _X_EXPORT DriverRec SAVAGE = SAVAGE_VERSION, SAVAGE_DRIVER_NAME, SavageIdentify, +#ifdef PCIACCESS NULL, +#else + SavageProbe, +#endif SavageAvailableOptions, NULL, 0, NULL, +#ifdef PCIACCESS savage_device_match, SavagePciProbe +#endif }; @@ -794,6 +838,7 @@ static void SavageIdentify(int flags) } +#ifdef PCIACCESS static Bool SavagePciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, intptr_t match_data) { @@ -867,6 +912,133 @@ static Bool SavagePciProbe(DriverPtr drv, int entity_num, return (pScrn != NULL); } +#else + +static Bool SavageProbe(DriverPtr drv, int flags) +{ + int i; + GDevPtr *devSections = NULL; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + + /* sanity checks */ + if ((numDevSections = xf86MatchDevice("savage", &devSections)) <= 0) + return FALSE; + if (xf86GetPciVideoInfo() == NULL) { + if (devSections) + xfree(devSections); + return FALSE; + } + + numUsed = xf86MatchPciInstances("SAVAGE", PCI_VENDOR_S3, + SavageChipsets, SavagePciChipsets, + devSections, numDevSections, drv, + &usedChips); + if (devSections) + xfree(devSections); + devSections = NULL; + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else + for (i=0; idriverVersion = SAVAGE_VERSION; + pScrn->driverName = SAVAGE_DRIVER_NAME; + pScrn->name = "SAVAGE"; + pScrn->Probe = SavageProbe; + pScrn->PreInit = SavagePreInit; + pScrn->ScreenInit = SavageScreenInit; + pScrn->SwitchMode = SavageSwitchMode; + pScrn->AdjustFrame = SavageAdjustFrame; + pScrn->EnterVT = SavageEnterVT; + pScrn->LeaveVT = SavageLeaveVT; + pScrn->FreeScreen = NULL; + pScrn->ValidMode = SavageValidMode; + foundScreen = TRUE; + + if (!SavageGetRec(pScrn)) + return FALSE; + + psav = SAVPTR(pScrn); + + psav->PciInfo = xf86GetPciInfoForEntity(pEnt->index); + if (pEnt->device->chipset && *pEnt->device->chipset) { + psav->Chipset = xf86StringToToken(SavageChipsets, + pEnt->device->chipset); + } else if (pEnt->device->chipID >= 0) { + psav->Chipset = LookupChipID(SavagePciChipsets, + pEnt->device->chipID); + } else { + psav->Chipset = LookupChipID(SavagePciChipsets, + psav->PciInfo->chipType); + } + } + + pEnt = xf86GetEntityInfo(usedChips[i]); + + /* MX, IX, SuperSavage cards support Dual-Head, mark the entity as sharable*/ + if(pEnt->chipset == S3_SAVAGE_MX || pEnt->chipset == S3_SUPERSAVAGE) + { + DevUnion *pPriv; + SavageEntPtr pSavageEnt; + + xf86SetEntitySharable(usedChips[i]); + + if (gSavageEntityIndex == -1) + gSavageEntityIndex = xf86AllocateEntityPrivateIndex(); + + pPriv = xf86GetEntityPrivate(pEnt->index, + gSavageEntityIndex); + + if (!pPriv->ptr) { + int j; + int instance = xf86GetNumEntityInstances(pEnt->index); + + for (j = 0; j < instance; j++) + xf86SetEntityInstanceForScreen(pScrn, pEnt->index, j); + + pPriv->ptr = xnfcalloc(sizeof(SavageEntRec), 1); + pSavageEnt = pPriv->ptr; + pSavageEnt->HasSecondary = FALSE; + } else { + pSavageEnt = pPriv->ptr; + pSavageEnt->HasSecondary = TRUE; + } + } + xfree(pEnt); + } + + + xfree(usedChips); + return foundScreen; +} + +static int LookupChipID( PciChipsets* pset, int ChipID ) +{ + /* Is there a function to do this for me? */ + while( pset->numChipset >= 0 ) + { + if( pset->PCIid == ChipID ) + return pset->numChipset; + pset++; + } + + return -1; +} +#endif + static void SavageDoDDC(ScrnInfoPtr pScrn) { SavagePtr psav= SAVPTR(pScrn); @@ -1398,7 +1570,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) pEnt->device->chipID); } else { from = X_PROBED; - psav->ChipId = psav->PciInfo->device_id; + psav->ChipId = DEVICE_ID(psav->PciInfo); pScrn->chipset = (char *)xf86TokenToString(SavageChipsets, psav->Chipset); } @@ -1411,7 +1583,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", psav->ChipRev); } else - psav->ChipRev = psav->PciInfo->revision; + psav->ChipRev = CHIP_REVISION(psav->PciInfo); xf86DrvMsg(pScrn->scrnIndex, from, "Engine: \"%s\"\n", pScrn->chipset); @@ -1420,18 +1592,82 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xfree(pEnt); - psav->PciTag = pciTag(psav->PciInfo->bus, psav->PciInfo->dev, +#ifndef PCIACCESS + psav->PciTag = pciTag(psav->PciInfo->bus, psav->PciInfo->device, psav->PciInfo->func); +#endif /* Set AGP Mode from config */ /* We support 1X 2X and 4X */ #ifdef XF86DRI +#ifdef PCIACCESS /* Try to read the AGP capabilty block from the device. If there is * no AGP info, the device is PCI. */ psav->IsPCI = (pci_device_get_agp_info(psav->PciInfo) == NULL); +#else + /* AGP/PCI (FK: copied from radeon_driver.c) */ + /* Proper autodetection of an AGP capable device requires examining + * PCI config registers to determine if the device implements extended + * PCI capabilities, and then walking the capability list as indicated + * in the PCI 2.2 and AGP 2.0 specifications, to determine if AGP + * capability is present. The procedure is outlined as follows: + * + * 1) Test bit 4 (CAP_LIST) of the PCI status register of the device + * to determine wether or not this device implements any extended + * capabilities. If this bit is zero, then the device is a PCI 2.1 + * or earlier device and is not AGP capable, and we can conclude it + * to be a PCI device. + * + * 2) If bit 4 of the status register is set, then the device implements + * extended capabilities. There is an 8 bit wide capabilities pointer + * register located at offset 0x34 in PCI config space which points to + * the first capability in a linked list of extended capabilities that + * this device implements. The lower two bits of this register are + * reserved and MBZ so must be masked out. + * + * 3) The extended capabilities list is formed by one or more extended + * capabilities structures which are aligned on DWORD boundaries. + * The first byte of the structure is the capability ID (CAP_ID) + * indicating what extended capability this structure refers to. The + * second byte of the structure is an offset from the beginning of + * PCI config space pointing to the next capability in the linked + * list (NEXT_PTR) or NULL (0x00) at the end of the list. The lower + * two bits of this pointer are reserved and MBZ. By examining the + * CAP_ID of each capability and walking through the list, we will + * either find the AGP_CAP_ID (0x02) indicating this device is an + * AGP device, or we'll reach the end of the list, indicating it is + * a PCI device. + * + * Mike A. Harris + * + * References: + * - PCI Local Bus Specification Revision 2.2, Chapter 6 + * - AGP Interface Specification Revision 2.0, Section 6.1.5 + */ + + psav->IsPCI = TRUE; + + if (pciReadLong(psav->PciTag, PCI_CMD_STAT_REG) & SAVAGE_CAP_LIST) { + CARD32 cap_ptr, cap_id; + + cap_ptr = pciReadLong(psav->PciTag, + SAVAGE_CAPABILITIES_PTR_PCI_CONFIG) + & SAVAGE_CAP_PTR_MASK; + + while(cap_ptr != SAVAGE_CAP_ID_NULL) { + cap_id = pciReadLong(psav->PciTag, cap_ptr); + if ((cap_id & 0xff) == SAVAGE_CAP_ID_AGP) { + psav->IsPCI = FALSE; + break; + } + cap_ptr = (cap_id >> 8) & SAVAGE_CAP_PTR_MASK; + } + } +#endif + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s card detected\n", (psav->IsPCI) ? "PCI" : "AGP"); @@ -2824,6 +3060,9 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, static Bool SavageMapMem(ScrnInfoPtr pScrn) { SavagePtr psav = SAVPTR(pScrn); +#ifndef PCIACCESS + int mode; +#endif unsigned i; TRACE(("SavageMapMem()\n")); @@ -2861,6 +3100,7 @@ static Bool SavageMapMem(ScrnInfoPtr pScrn) } +#ifdef PCIACCESS psav->MmioBase = psav->PciInfo->regions[ psav->MmioRegion.bar ].base_addr + psav->MmioRegion.offset; @@ -2869,6 +3109,16 @@ static Bool SavageMapMem(ScrnInfoPtr pScrn) psav->ApertureBase = psav->PciInfo->regions[ psav->FbRegion.bar ].base_addr + psav->ApertureRegion.offset; +#else + psav->MmioBase = psav->PciInfo->memBase[ psav->MmioRegion.bar ] + + psav->MmioRegion.offset; + + psav->FrameBufferBase = psav->PciInfo->memBase[ psav->FbRegion.bar ] + + psav->FbRegion.offset; + + psav->ApertureBase = psav->PciInfo->memBase[ psav->FbRegion.bar ] + + psav->ApertureRegion.offset; +#endif /* FIXME: This seems fine even on Savage3D where the same BAR contains the @@ -2876,15 +3126,33 @@ static Bool SavageMapMem(ScrnInfoPtr pScrn) * FIXME: later. Someone should investigate this, though. And kick S3 * FIXME: for doing something so silly. */ +#ifndef PCIACCESS + mode = VIDMEM_MMIO; +#endif for (i = 0; i <= psav->last_bar; i++) { - if (pci_device_map_region(psav->PciInfo, i, TRUE)) { + int err; + +#ifdef PCIACCESS + err = pci_device_map_region(psav->PciInfo, i, TRUE); +#else + psav->bar_mappings[i] = xf86MapPciMem(pScrn->scrnIndex, mode, + psav->PciTag, + psav->PciInfo->memBase[i], + (1U << psav->PciInfo->size[i])); + err = (psav->bar_mappings[i] == NULL); +#endif + if (err) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: cound not map PCI region %u, last BAR = %u\n", i, psav->last_bar); return FALSE; } +#ifdef PCIACCESS psav->bar_mappings[i] = psav->PciInfo->regions[i].memory; +#else + mode = VIDMEM_FRAMEBUFFER; +#endif } psav->MapBase = psav->bar_mappings[ psav->MmioRegion.bar ] @@ -2907,7 +3175,11 @@ static Bool SavageMapMem(ScrnInfoPtr pScrn) psav->ApertureMap += 0x1000000; } +#ifdef PCIACCESS pScrn->memPhysBase = psav->PciInfo->regions[0].base_addr; +#else + pScrn->memPhysBase = psav->PciInfo->memBase[0]; +#endif return TRUE; } @@ -2929,7 +3201,12 @@ static void SavageUnmapMem(ScrnInfoPtr pScrn, int All) for (i = (All) ? 0 : 1; i <= psav->last_bar; i++) { if (psav->bar_mappings[i]) { +#ifdef PCIACCESS pci_device_unmap_region(psav->PciInfo, i); +#else + xf86UnMapVidMem(pScrn->scrnIndex, psav->bar_mappings[i], + (1U << psav->PciInfo->size[i])); +#endif psav->bar_mappings[i] = NULL; } } diff --git a/src/savage_driver.h b/src/savage_driver.h index 9286c1e..74eea5c 100644 --- a/src/savage_driver.h +++ b/src/savage_driver.h @@ -33,7 +33,18 @@ #include #include +#ifdef PCIACCESS #include +#define VENDOR_ID(p) (p)->vendor_id +#define DEVICE_ID(p) (p)->device_id +#define SUBSYS_ID(p) (p)->subdevice_id +#define CHIP_REVISION(p) (p)->revision +#else +#define VENDOR_ID(p) (p)->vendor +#define DEVICE_ID(p) (p)->chipType +#define SUBSYS_ID(p) (p)->subsysCard +#define CHIP_REVISION(p) (p)->chipRev +#endif #define MODE_24 24 @@ -365,8 +376,12 @@ typedef struct _Savage { int TVSizeY; CloseScreenProcPtr CloseScreen; +#ifdef PCIACCESS struct pci_device * PciInfo; +#else + pciVideoPtr PciInfo; PCITAG PciTag; +#endif int Chipset; int ChipId; int ChipRev; -- cgit v1.2.3