summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Kuehling <fxkuehl@gmx.de>2005-01-10 23:11:53 +0000
committerFelix Kuehling <fxkuehl@gmx.de>2005-01-10 23:11:53 +0000
commitd62d010ca8590d99d4150f7b00999e619a6aaac3 (patch)
tree16abd9b2033fe0cf362882e2f5fe9dda6aeaa036
parent303bc2a7df00aadc13d747d6c240ca3d693cad4e (diff)
- Support for PCI Savages: on PCI cards don't run SAVAGEDRIAgpInit, add PCI
DMA buffers instead of AGP buffers. Set dma_type properly in SAVAGEDRIKernelInit. - Something's still wrong with ShadowStatus on the PCI card I'm testing here. Probably a DRM issue. - Fixed error handling. Call SAVAGEDRICloseScreen instead of DRICloseScreen. - Added AGP/PCI detection (copied from the radeon driver).
-rw-r--r--src/savage_dri.c121
-rw-r--r--src/savage_driver.c143
-rw-r--r--src/savage_driver.h1
-rw-r--r--src/savage_regs.h8
4 files changed, 183 insertions, 90 deletions
diff --git a/src/savage_dri.c b/src/savage_dri.c
index d42f895..9af6780 100644
--- a/src/savage_dri.c
+++ b/src/savage_dri.c
@@ -733,7 +733,7 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
unsigned long mode;
unsigned int vendor, device;
- int ret, count;
+ int ret;
/*int size,numbuffer,i;
savageAgpBufferPtr agpbuffer;*/
@@ -829,18 +829,6 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
"[agp] DMA buffers mapped at 0x%08lx\n",
(unsigned long)pSAVAGEDRIServer->buffers.map );
*/
- count = drmAddBufs( psav->drmFD,
- SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
- DRM_AGP_BUFFER, pSAVAGEDRIServer->buffers.offset );
- if ( count <= 0 ) {
- xf86DrvMsg( pScrn->scrnIndex, X_INFO,
- "[drm] failure adding %d %d byte DMA buffers (%d)\n",
- SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, count );
- return FALSE;
- }
- xf86DrvMsg( pScreen->myNum, X_INFO,
- "[drm] Added %d %d byte DMA buffers\n",
- count, SAVAGE_BUFFER_SIZE );
/* AGP textures
*/
@@ -976,6 +964,47 @@ static Bool SAVAGEDRIMapInit( ScreenPtr pScreen )
return TRUE;
}
+static Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen )
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ int count;
+
+ if ( psav->IsPCI ) {
+ count = drmAddBufs( psav->drmFD,
+ SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
+ 0, 0 );
+ } else {
+ count = drmAddBufs( psav->drmFD,
+ SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
+ DRM_AGP_BUFFER, pSAVAGEDRIServer->buffers.offset );
+ }
+ if ( count <= 0 ) {
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "[drm] failure adding %d %d byte DMA buffers (%d)\n",
+ SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, count );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Added %d %d byte DMA buffers\n",
+ count, SAVAGE_BUFFER_SIZE );
+
+ /* not needed in the server
+ pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD );
+ if ( !pSAVAGEDRIServer->drmBuffers ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Failed to map DMA buffers list\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Mapped %d DMA buffers\n",
+ pSAVAGEDRIServer->drmBuffers->count );
+ */
+
+ return TRUE;
+}
+
static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -992,7 +1021,7 @@ static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
init.cob_size = psav->cobSize/4; /* size in 32-bit entries */
init.bci_threshold_lo = psav->bciThresholdLo;
init.bci_threshold_hi = psav->bciThresholdHi;
- init.dma_type = SAVAGE_DMA_AGP; /* PCI support will be added soon */
+ init.dma_type = psav->IsPCI ? SAVAGE_DMA_PCI : SAVAGE_DMA_AGP;
init.fb_bpp = pScrn->bitsPerPixel;
init.front_offset = pSAVAGEDRIServer->frontOffset;
@@ -1021,28 +1050,6 @@ static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
return TRUE;
}
-#if 0
-static Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen )
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- SavagePtr psav = SAVPTR(pScrn);
- SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
-
-
- pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD );
- if ( !pSAVAGEDRIServer->drmBuffers ) {
- xf86DrvMsg( pScreen->myNum, X_ERROR,
- "[drm] Failed to map DMA buffers list\n" );
- return FALSE;
- }
- xf86DrvMsg( pScreen->myNum, X_INFO,
- "[drm] Mapped %d DMA buffers\n",
- pSAVAGEDRIServer->drmBuffers->count );
-
- return TRUE;
-}
-#endif
-
Bool SAVAGEDRIScreenInit( ScreenPtr pScreen )
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -1271,18 +1278,30 @@ Bool SAVAGEDRIScreenInit( ScreenPtr pScreen )
}
#endif
- if ( !SAVAGEDRIAgpInit( pScreen ) ) {
- DRICloseScreen( pScreen );
- return FALSE;
+ if ( !psav->IsPCI && !SAVAGEDRIAgpInit( pScreen ) ) {
+ /*
+ SAVAGEDRICloseScreen( pScreen );
+ return FALSE;
+ */
+ psav->IsPCI = TRUE;
+ xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
+ "[agp] AGP failed to initialize -- falling back to PCI mode.\n");
+ xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
+ "[agp] Make sure you have the agpgart kernel module loaded.\n");
}
if ( !SAVAGEDRIMapInit( pScreen ) ) {
- DRICloseScreen( pScreen );
+ SAVAGEDRICloseScreen( pScreen );
+ return FALSE;
+ }
+
+ if ( !SAVAGEDRIBuffersInit( pScreen ) ) {
+ SAVAGEDRICloseScreen( pScreen );
return FALSE;
}
if ( !SAVAGEInitVisualConfigs( pScreen ) ) {
- DRICloseScreen( pScreen );
+ SAVAGEDRICloseScreen( pScreen );
return FALSE;
}
xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" );
@@ -1320,14 +1339,6 @@ Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen )
return FALSE;
}
-/* no dma...... */
-#if 0
- if ( !SAVAGEDRIBuffersInit( pScreen ) ) {
- SAVAGEDRICloseScreen( pScreen );
- return FALSE;
- }
-#endif
-
pSAVAGEDRI->chipset = psav->Chipset;
pSAVAGEDRI->width = pScrn->virtualX;
pSAVAGEDRI->height = pScrn->virtualY;
@@ -1533,7 +1544,11 @@ void SAVAGEDRICloseScreen( ScreenPtr pScreen )
drmUnmap( pSAVAGEDRIServer->registers.map, pSAVAGEDRIServer->registers.size );
pSAVAGEDRIServer->registers.map = NULL;
}
-
+
+ if ( pSAVAGEDRIServer->aperture.map ) {
+ drmUnmap( pSAVAGEDRIServer->aperture.map, pSAVAGEDRIServer->aperture.size );
+ pSAVAGEDRIServer->aperture.map = NULL;
+ }
if ( pSAVAGEDRIServer->agpTextures.map ) {
drmUnmap( pSAVAGEDRIServer->agpTextures.map,
@@ -1547,15 +1562,17 @@ void SAVAGEDRICloseScreen( ScreenPtr pScreen )
if (pSAVAGEDRIServer->registers.handle)
drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
+ if (pSAVAGEDRIServer->aperture.handle)
+ drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
+
if (pSAVAGEDRIServer->agpTextures.handle)
drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpTextures.handle);
-/* no DMA now.... */
-#if 0
if ( pSAVAGEDRIServer->buffers.map ) {
drmUnmap( pSAVAGEDRIServer->buffers.map, pSAVAGEDRIServer->buffers.size );
pSAVAGEDRIServer->buffers.map = NULL;
}
+#if 0
if ( pSAVAGEDRIServer->primary.map ) {
drmUnmap( pSAVAGEDRIServer->primary.map, pSAVAGEDRIServer->primary.size );
pSAVAGEDRIServer->primary.map = NULL;
diff --git a/src/savage_driver.c b/src/savage_driver.c
index 0c329df..d854729 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -1290,52 +1290,123 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xfree(pEnt);
+ psav->PciTag = pciTag(psav->PciInfo->bus, psav->PciInfo->device,
+ psav->PciInfo->func);
+
+
/* Set AGP Mode from config */
/* We support 1X 2X and 4X */
#ifdef XF86DRI
- from = X_DEFAULT;
- psav->agpMode = SAVAGE_DEFAULT_AGP_MODE;
- /*psav->agpMode = SAVAGE_MAX_AGP_MODE;*/
- psav->agpSize = 16;
+ /* 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 <mharris@redhat.com>
+ *
+ * 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;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
+ (psav->IsPCI) ? "PCI" : "AGP");
+
+ if (!psav->IsPCI) {
+ from = X_DEFAULT;
+ psav->agpMode = SAVAGE_DEFAULT_AGP_MODE;
+ /*psav->agpMode = SAVAGE_MAX_AGP_MODE;*/
+ psav->agpSize = 16;
- if (xf86GetOptValInteger(psav->Options,
- OPTION_AGP_MODE, &(psav->agpMode))) {
- if (psav->agpMode < 1) {
- psav->agpMode = 1;
- }
- if (psav->agpMode > SAVAGE_MAX_AGP_MODE) {
- psav->agpMode = SAVAGE_MAX_AGP_MODE;
- }
- if ((psav->agpMode > 2) &&
- (psav->Chipset == S3_SAVAGE3D ||
- psav->Chipset == S3_SAVAGE_MX))
+ if (xf86GetOptValInteger(psav->Options,
+ OPTION_AGP_MODE, &(psav->agpMode))) {
+ if (psav->agpMode < 1) {
+ psav->agpMode = 1;
+ }
+ if (psav->agpMode > SAVAGE_MAX_AGP_MODE) {
+ psav->agpMode = SAVAGE_MAX_AGP_MODE;
+ }
+ if ((psav->agpMode > 2) &&
+ (psav->Chipset == S3_SAVAGE3D ||
+ psav->Chipset == S3_SAVAGE_MX))
psav->agpMode = 2; /* old savages only support 2x */
- from = X_CONFIG;
- }
+ from = X_CONFIG;
+ }
- xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",
- psav->agpMode);
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",
+ psav->agpMode);
- if (xf86GetOptValInteger(psav->Options,
+ if (xf86GetOptValInteger(psav->Options,
OPTION_AGP_SIZE, (int *)&(psav->agpSize))) {
- switch (psav->agpSize) {
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- case 256:
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ switch (psav->agpSize) {
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Illegal AGP size: %d MB, defaulting to 16 MB\n", psav->agpSize);
- psav->agpSize = 16;
+ psav->agpSize = 16;
+ }
}
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Using %d MB AGP aperture\n", psav->agpSize);
+ } else {
+ psav->agpMode = 0;
+ psav->agpSize = 0;
+ }
#endif
@@ -1419,10 +1490,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from, "Engine: \"%s\"\n", pScrn->chipset);
- psav->PciTag = pciTag(psav->PciInfo->bus, psav->PciInfo->device,
- psav->PciInfo->func);
-
-
if (!SavageMapMMIO(pScrn)) {
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
diff --git a/src/savage_driver.h b/src/savage_driver.h
index 67e2de4..760faf0 100644
--- a/src/savage_driver.h
+++ b/src/savage_driver.h
@@ -263,6 +263,7 @@ typedef struct _Savage {
int Chipset;
int ChipId;
int ChipRev;
+ int IsPCI;
vbeInfoPtr pVbe;
int EntityIndex;
int ShadowCounter;
diff --git a/src/savage_regs.h b/src/savage_regs.h
index ae1c636..6feff07 100644
--- a/src/savage_regs.h
+++ b/src/savage_regs.h
@@ -3,6 +3,14 @@
#ifndef _SAVAGE_REGS_H
#define _SAVAGE_REGS_H
+/* Copied and renamed from radeon_reg.h for AGP/PCI detection. */
+#define SAVAGE_STATUS_PCI_CONFIG 0x06
+# define SAVAGE_CAP_LIST 0x100000
+#define SAVAGE_CAPABILITIES_PTR_PCI_CONFIG 0x34 /* offset in PCI config*/
+# define SAVAGE_CAP_PTR_MASK 0xfc /* mask off reserved bits of CAP_PTR */
+# define SAVAGE_CAP_ID_NULL 0x00 /* End of capability list */
+# define SAVAGE_CAP_ID_AGP 0x02 /* AGP capability ID */
+
/* These are here until xf86PciInfo.h is updated. */
#ifndef PCI_CHIP_S3TWISTER_P