diff options
author | Felix Kuehling <fxkuehl@gmx.de> | 2005-01-10 23:11:53 +0000 |
---|---|---|
committer | Felix Kuehling <fxkuehl@gmx.de> | 2005-01-10 23:11:53 +0000 |
commit | d62d010ca8590d99d4150f7b00999e619a6aaac3 (patch) | |
tree | 16abd9b2033fe0cf362882e2f5fe9dda6aeaa036 | |
parent | 303bc2a7df00aadc13d747d6c240ca3d693cad4e (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.c | 121 | ||||
-rw-r--r-- | src/savage_driver.c | 143 | ||||
-rw-r--r-- | src/savage_driver.h | 1 | ||||
-rw-r--r-- | src/savage_regs.h | 8 |
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 |