summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Kuehling <fxkuehl@gmx.de>2005-03-06 01:36:10 +0000
committerFelix Kuehling <fxkuehl@gmx.de>2005-03-06 01:36:10 +0000
commit33033884e9ec07d96c70765132a2be0ebc466299 (patch)
treefdf3c29a49be1dab58b1b31c06ea5f81f7067121 /src
parent21bf49050a7b868c50831fb3951086fe9c21e8f6 (diff)
- Support for the new DRM version 2.4 with command DMA.
- Added an option "DmaMode" to choose between vertex and command DMA. - Allow ShadowStatus to be explicitly disabled even with DRI enabled. - Updated the man page.
Diffstat (limited to 'src')
-rw-r--r--src/savage_dri.c209
-rw-r--r--src/savage_dri.h5
-rw-r--r--src/savage_driver.c47
-rw-r--r--src/savage_driver.h3
4 files changed, 198 insertions, 66 deletions
diff --git a/src/savage_dri.c b/src/savage_dri.c
index c7d5e63..8613fd0 100644
--- a/src/savage_dri.c
+++ b/src/savage_dri.c
@@ -733,6 +733,7 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
unsigned long mode;
unsigned int vendor, device;
+ unsigned int offset;
int ret;
/*int size,numbuffer,i;
savageAgpBufferPtr agpbuffer;*/
@@ -742,14 +743,23 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024;
pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size; /* ? */
- if (psav->AgpDMA) {
- pSAVAGEDRIServer->buffers.offset = 0;
- pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE;
+ offset = 0;
+
+ if ( psav->AgpDMA ) {
+ if ( psav->CommandDMA ) {
+ pSAVAGEDRIServer->cmdDma.offset = offset;
+ pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE;
+ offset += pSAVAGEDRIServer->cmdDma.size;
+ } else if ( psav->VertexDMA ) {
+ pSAVAGEDRIServer->buffers.offset = 0;
+ pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE;
+ offset += pSAVAGEDRIServer->buffers.size;
+ }
}
- pSAVAGEDRIServer->agpTextures.offset = pSAVAGEDRIServer->buffers.size;
- pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size -
- pSAVAGEDRIServer->buffers.size);
+ pSAVAGEDRIServer->agpTextures.offset = offset;
+ pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - offset);
+ offset += pSAVAGEDRIServer->agpTextures.size;
if ( drmAgpAcquire( psav->drmFD ) < 0 ) {
xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" );
@@ -807,31 +817,59 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
/* DMA buffers
*/
if ( psav->AgpDMA ) {
- if ( drmAddMap( psav->drmFD,
- pSAVAGEDRIServer->buffers.offset,
- pSAVAGEDRIServer->buffers.size,
- DRM_AGP, 0,
- &pSAVAGEDRIServer->buffers.handle ) < 0 ) {
- xf86DrvMsg( pScreen->myNum, X_ERROR,
- "[agp] Could not add DMA buffers mapping\n" );
- return FALSE;
- }
- xf86DrvMsg( pScreen->myNum, X_INFO,
- "[agp] DMA buffers handle = 0x%08lx\n",
- pSAVAGEDRIServer->buffers.handle );
- /* not needed in the server
- if ( drmMap( psav->drmFD,
- pSAVAGEDRIServer->buffers.handle,
- pSAVAGEDRIServer->buffers.size,
- &pSAVAGEDRIServer->buffers.map ) < 0 ) {
- xf86DrvMsg( pScreen->myNum, X_ERROR,
- "[agp] Could not map DMA buffers\n" );
- return FALSE;
+ if ( psav->CommandDMA ) {
+ if ( drmAddMap( psav->drmFD,
+ pSAVAGEDRIServer->cmdDma.offset,
+ pSAVAGEDRIServer->cmdDma.size,
+ DRM_AGP, DRM_RESTRICTED | DRM_KERNEL,
+ &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not add command DMA mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] command DMA handle = 0x%08lx\n",
+ pSAVAGEDRIServer->cmdDma.handle );
+ /* not needed in the server
+ if ( drmMap( psav->drmFD,
+ pSAVAGEDRIServer->cmdDma.handle,
+ pSAVAGEDRIServer->cmdDma.size,
+ &pSAVAGEDRIServer->cmdDma.map ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not map command DMA\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] command DMA mapped at 0x%08lx\n",
+ (unsigned long)pSAVAGEDRIServer->cmdDma.map );
+ */
+ } else if ( psav->VertexDMA ) {
+ if ( drmAddMap( psav->drmFD,
+ pSAVAGEDRIServer->buffers.offset,
+ pSAVAGEDRIServer->buffers.size,
+ DRM_AGP, 0,
+ &pSAVAGEDRIServer->buffers.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not add DMA buffers mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] DMA buffers handle = 0x%08lx\n",
+ pSAVAGEDRIServer->buffers.handle );
+ /* not needed in the server
+ if ( drmMap( psav->drmFD,
+ pSAVAGEDRIServer->buffers.handle,
+ pSAVAGEDRIServer->buffers.size,
+ &pSAVAGEDRIServer->buffers.map ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[agp] Could not map DMA buffers\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[agp] DMA buffers mapped at 0x%08lx\n",
+ (unsigned long)pSAVAGEDRIServer->buffers.map );
+ */
}
- xf86DrvMsg( pScreen->myNum, X_INFO,
- "[agp] DMA buffers mapped at 0x%08lx\n",
- (unsigned long)pSAVAGEDRIServer->buffers.map );
- */
}
/* AGP textures
@@ -847,7 +885,7 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
}
/* pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/
xf86DrvMsg( pScreen->myNum, X_INFO,
- "[agp] agpTextures microcode handle = 0x%08lx\n",
+ "[agp] agpTextures handle = 0x%08lx\n",
pSAVAGEDRIServer->agpTextures.handle );
/* not needed in the server
@@ -931,40 +969,55 @@ static Bool SAVAGEDRIMapInit( ScreenPtr pScreen )
}*/
- /* Always enable ShadowStatus for direct rendering. */
- if ( !psav->ShadowStatus ) {
- psav->ShadowStatus = 1;
+ if ( !psav->AgpDMA && psav->CommandDMA ) {
+ pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE;
+ if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->cmdDma.size,
+ DRM_CONSISTENT, DRM_RESTRICTED | DRM_LOCKED |
+ DRM_KERNEL | DRM_WRITE_COMBINING,
+ &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) {
+ psav->CommandDMA = FALSE;
+ xf86DrvMsg( pScreen->myNum, X_WARNING,
+ "[drm] Could not add PCI command DMA mapping\n" );
+ } else
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] PCI command DMA handle = 0x%08lx\n",
+ pSAVAGEDRIServer->cmdDma.handle );
+ }
+
+ /* Enable ShadowStatus by default for direct rendering. */
+ if ( !psav->ShadowStatus && !psav->ForceShadowStatus ) {
+ psav->ShadowStatus = TRUE;
xf86DrvMsg( pScreen->myNum, X_INFO,
"[drm] Enabling ShadowStatus for DRI.\n" );
- }
- pSAVAGEDRIServer->status.size = 4096; /* 1 page */
+ pSAVAGEDRIServer->status.size = 4096; /* 1 page */
- if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size,
- DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
- &pSAVAGEDRIServer->status.handle ) < 0 ) {
- xf86DrvMsg( pScreen->myNum, X_ERROR,
- "[drm] Could not add status page mapping\n" );
- return FALSE;
- }
- xf86DrvMsg( pScreen->myNum, X_INFO,
- "[drm] Status handle = 0x%08lx\n",
- pSAVAGEDRIServer->status.handle );
+ if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size,
+ DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
+ &pSAVAGEDRIServer->status.handle ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not add status page mapping\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Status handle = 0x%08lx\n",
+ pSAVAGEDRIServer->status.handle );
- if ( drmMap( psav->drmFD,
- pSAVAGEDRIServer->status.handle,
- pSAVAGEDRIServer->status.size,
- &pSAVAGEDRIServer->status.map ) < 0 ) {
- xf86DrvMsg( pScreen->myNum, X_ERROR,
- "[drm] Could not map status page\n" );
- return FALSE;
- }
- xf86DrvMsg( pScreen->myNum, X_INFO,
- "[drm] Status page mapped at 0x%08lx\n",
- (unsigned long)pSAVAGEDRIServer->status.map );
+ if ( drmMap( psav->drmFD,
+ pSAVAGEDRIServer->status.handle,
+ pSAVAGEDRIServer->status.size,
+ &pSAVAGEDRIServer->status.map ) < 0 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] Could not map status page\n" );
+ return FALSE;
+ }
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] Status page mapped at 0x%08lx\n",
+ (unsigned long)pSAVAGEDRIServer->status.map );
- psav->ShadowPhysical = pSAVAGEDRIServer->status.handle;
- psav->ShadowVirtual = pSAVAGEDRIServer->status.map;
+ psav->ShadowPhysical = pSAVAGEDRIServer->status.handle;
+ psav->ShadowVirtual = pSAVAGEDRIServer->status.map;
+ }
return TRUE;
}
@@ -976,6 +1029,13 @@ static Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen )
SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
int count;
+ if ( !psav->VertexDMA || psav->CommandDMA ) {
+ /* At this point psav->CommandDMA == TRUE means that CommandDMA
+ * allocation was actually successful. */
+ psav->VertexDMA = FALSE;
+ return TRUE;
+ }
+
if ( psav->AgpDMA ) {
count = drmAddBufs( psav->drmFD,
SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
@@ -1042,9 +1102,19 @@ static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
init.texture_size = pSAVAGEDRIServer->textureSize;
init.status_offset = pSAVAGEDRIServer->status.handle;
- init.buffers_offset = pSAVAGEDRIServer->buffers.handle;
init.agp_textures_offset = pSAVAGEDRIServer->agpTextures.handle;
+ /* Savage4-based chips with DRM version >= 2.4 support command DMA,
+ * which is preferred because it works with all vertex
+ * formats. Command DMA and vertex DMA don't work at the same
+ * time. */
+ init.buffers_offset = 0;
+ init.cmd_dma_offset = 0;
+ if ( psav->CommandDMA )
+ init.cmd_dma_offset = pSAVAGEDRIServer->cmdDma.handle;
+ else if ( psav->VertexDMA )
+ init.buffers_offset = pSAVAGEDRIServer->buffers.handle;
+
ret = drmCommandWrite( psav->drmFD, DRM_SAVAGE_BCI_INIT, &init, sizeof(init) );
if ( ret < 0 ) {
xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
@@ -1251,7 +1321,7 @@ Bool SAVAGEDRIScreenInit( ScreenPtr pScreen )
/* incompatible drm version */
xf86DrvMsg( pScreen->myNum, X_ERROR,
"[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
- "[dri] savage.o kernel module version is %d.%d.%d but version 2.0.x is needed.\n"
+ "[dri] savage.ko kernel module version is %d.%d.%d but version 2.0.x is needed.\n"
"[dri] Disabling DRI.\n",
version->version_major,
version->version_minor,
@@ -1260,6 +1330,18 @@ Bool SAVAGEDRIScreenInit( ScreenPtr pScreen )
SAVAGEDRICloseScreen( pScreen ); /* FIXME: ??? */
return FALSE;
}
+ if ( psav->CommandDMA && version->version_minor < 4 ) {
+ xf86DrvMsg( pScreen->myNum, X_WARNING,
+ "[drm] DRM version < 2.4.0 does not support command DMA.\n");
+ psav->CommandDMA = FALSE;
+ }
+ if ( !psav->VertexDMA && version->version_minor < 4 ) {
+ xf86DrvMsg( pScreen->myNum, X_ERROR,
+ "[drm] DRM version < 2.4.0 requires vertex DMA.\n");
+ drmFreeVersion( version );
+ SAVAGEDRICloseScreen( pScreen );
+ return FALSE;
+ }
drmFreeVersion( version );
}
}
@@ -1483,6 +1565,11 @@ Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen )
xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:handle:0x%08lx\n",pSAVAGEDRIServer->cmdDma.handle);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:offset:0x%08x\n",pSAVAGEDRIServer->cmdDma.offset);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:size:0x%08x\n",pSAVAGEDRIServer->cmdDma.size);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.map);
+
xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" );
xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRI->chipset );
xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] width:0x%08x\n",pSAVAGEDRI->width );
diff --git a/src/savage_dri.h b/src/savage_dri.h
index 39b6564..82b4aee 100644
--- a/src/savage_dri.h
+++ b/src/savage_dri.h
@@ -34,6 +34,8 @@
#define SAVAGE_NUM_BUFFERS 32
#define SAVAGE_BUFFER_SIZE (1 << 16) /* 64k */
+#define SAVAGE_CMDDMA_SIZE 0x100000 /* 1MB */
+
#define SAVAGE_DEFAULT_AGP_MODE 1
#define SAVAGE_MAX_AGP_MODE 4
@@ -101,6 +103,9 @@ typedef struct _server{
drmRegion agpTextures;
int logAgpTextureGranularity;
+ /* command DMA */
+ drmRegion cmdDma;
+
#if 0
drmBufMapPtr drmBuffers;
#endif
diff --git a/src/savage_driver.c b/src/savage_driver.c
index 74ff6a0..5b7704e 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -213,6 +213,7 @@ typedef enum {
,OPTION_DVI
,OPTION_BUS_TYPE
,OPTION_DMA_TYPE
+ ,OPTION_DMA_MODE
,OPTION_AGP_MODE
,OPTION_AGP_SIZE
} SavageOpts;
@@ -243,6 +244,7 @@ static const OptionInfoRec SavageOptions[] =
#ifdef XF86DRI
{ OPTION_BUS_TYPE, "BusType", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_DMA_TYPE, "DmaType", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_DMA_MODE, "DmaMode", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE },
{ OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE },
#endif
@@ -1223,9 +1225,12 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
"Option: LCDClock %1.2f MHz\n", psav->LCDClock );
- if( xf86GetOptValBool( psav->Options, OPTION_SHADOW_STATUS, &psav->ShadowStatus))
+ if( xf86GetOptValBool( psav->Options, OPTION_SHADOW_STATUS, &psav->ShadowStatus)) {
xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
- "Option: ShadowStatus enabled\n" );
+ "Option: ShadowStatus %sabled\n", psav->ShadowStatus ? "en" : "dis" );
+ psav->ForceShadowStatus = TRUE;
+ } else
+ psav->ForceShadowStatus = FALSE;
/* If ShadowStatus is off it will be automatically enabled for DRI.
* If DRI initialization fails fall back to ConfigShadowStatus. */
psav->ConfigShadowStatus = psav->ShadowStatus;
@@ -1427,6 +1432,36 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
"Using %s DMA\n", psav->AgpDMA ? "AGP" : "PCI");
}
+ psav->CommandDMA = TRUE;
+ psav->VertexDMA = TRUE;
+ from = X_DEFAULT;
+ if ((s = xf86GetOptValString(psav->Options, OPTION_DMA_MODE))) {
+ from = X_CONFIG;
+ if (strcmp(s, "Command") == 0)
+ psav->VertexDMA = FALSE;
+ else if (strcmp(s, "Vertex") == 0)
+ psav->CommandDMA = FALSE;
+ else if (strcmp(s, "None") == 0)
+ psav->VertexDMA = psav->CommandDMA = FALSE;
+ else if (strcmp(s, "Any") != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid DmaMode option\n");
+ from = X_DEFAULT;
+ }
+ }
+ psav->CommandDMA = (psav->CommandDMA && !S3_SAVAGE3D_SERIES(psav->Chipset));
+ if (psav->CommandDMA && psav->VertexDMA)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will try command and vertex DMA mode\n");
+ else if (psav->CommandDMA && !psav->VertexDMA)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will try only command DMA mode\n");
+ else if (!psav->CommandDMA && psav->VertexDMA)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will try only vertex DMA mode\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "DMA disabled\n");
+
if (!psav->IsPCI) {
from = X_DEFAULT;
psav->agpMode = SAVAGE_DEFAULT_AGP_MODE;
@@ -3026,13 +3061,14 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
/* Setup DRI after visuals have been established */
psav->directRenderingEnabled = SAVAGEDRIScreenInit(pScreen);
/* If DRI init failed, reset shadow status. */
- if (!psav->directRenderingEnabled) {
+ if (!psav->directRenderingEnabled &&
+ psav->ShadowStatus != psav->ConfigShadowStatus) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n");
SavageInitShadowStatus(pScrn);
}
/* If shadow status was enabled for DRI, hook up the shadow
* waiting functions now. */
- else if (!psav->ConfigShadowStatus) {
+ else if (psav->ShadowStatus && !psav->ConfigShadowStatus) {
psav->WaitQueue = ShadowWaitQueue;
psav->WaitIdle = ShadowWait;
psav->WaitIdleEmpty = ShadowWait;
@@ -3211,7 +3247,8 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
psav->directRenderingEnabled = SAVAGEDRIFinishScreenInit(pScreen);
/* If DRI initialization failed, reset shadow status and
* reinitialize 2D engine. */
- if (!psav->directRenderingEnabled) {
+ if (!psav->directRenderingEnabled &&
+ psav->ShadowStatus != psav->ConfigShadowStatus) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n");
SavageInitShadowStatus(pScrn);
SavageInitialize2DEngine(pScrn);
diff --git a/src/savage_driver.h b/src/savage_driver.h
index 6b8ee9e..a60262c 100644
--- a/src/savage_driver.h
+++ b/src/savage_driver.h
@@ -234,6 +234,7 @@ typedef struct _Savage {
double LCDClock;
Bool ConfigShadowStatus; /* from the config */
Bool ShadowStatus; /* automatically enabled with DRI */
+ Bool ForceShadowStatus; /* true if explicitly set in conf */
Bool CrtOnly;
Bool TvOn;
Bool PAL;
@@ -340,6 +341,8 @@ typedef struct _Savage {
Bool IsPCI;
Bool AgpDMA;
+ Bool VertexDMA;
+ Bool CommandDMA;
int agpMode;
drmSize agpSize;
FBLinearPtr reserved;