diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c | 276 |
1 files changed, 211 insertions, 65 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c index 3127aff1d..e069d9100 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.12 2001/03/21 19:46:26 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.13 2001/04/10 16:07:59 dawes Exp $ */ /* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, * Precision Insight, Inc., Cedar Park, Texas, and @@ -47,12 +47,20 @@ /* X and server generic header files */ #include "xf86.h" #include "windowstr.h" +#include "xf86PciInfo.h" /* GLX/DRI/DRM definitions */ #define _XF86DRI_SERVER_ #include "GL/glxtokens.h" #include "sarea.h" +/* ?? HACK - for now, put this here... */ +/* ?? Alpha - this may need to be a variable to handle UP1x00 vs TITAN */ +#if defined(__alpha__) +# define DRM_PAGE_SIZE 8192 +#else +# define DRM_PAGE_SIZE 4096 +#endif /* Initialize the visual configs that are supported by the hardware. These are combined with the visual configs that the indirect @@ -72,6 +80,9 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen) case 8: /* 8bpp mode is not support */ case 15: /* FIXME */ case 24: /* FIXME */ + xf86DrvMsg(pScreen->myNum, X_WARNING, + "R128DRIScreenInit failed (depth %d not supported). " + "Disabling DRI.\n", info->CurrentLayout.pixel_code); return FALSE; #define R128_USE_ACCUM 1 @@ -83,18 +94,18 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen) if (R128_USE_STENCIL) numConfigs *= 2; if (!(pConfigs - = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig), numConfigs))) { return FALSE; } if (!(pR128Configs - = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec), + = (R128ConfigPrivPtr)xcalloc(sizeof(R128ConfigPrivRec), numConfigs))) { xfree(pConfigs); return FALSE; } if (!(pR128ConfigPtrs - = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr), + = (R128ConfigPrivPtr*)xcalloc(sizeof(R128ConfigPrivPtr), numConfigs))) { xfree(pConfigs); xfree(pR128Configs); @@ -160,18 +171,18 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen) if (R128_USE_STENCIL) numConfigs *= 2; if (!(pConfigs - = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig), numConfigs))) { return FALSE; } if (!(pR128Configs - = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec), + = (R128ConfigPrivPtr)xcalloc(sizeof(R128ConfigPrivRec), numConfigs))) { xfree(pConfigs); return FALSE; } if (!(pR128ConfigPtrs - = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr), + = (R128ConfigPrivPtr*)xcalloc(sizeof(R128ConfigPrivPtr), numConfigs))) { xfree(pConfigs); xfree(pR128Configs); @@ -399,12 +410,12 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) unsigned long mode; unsigned int vendor, device; int ret; - unsigned long cntl; + unsigned long cntl, chunk; int s, l; int flags; if (drmAgpAcquire(info->drmFD) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n"); + xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n"); return FALSE; } @@ -457,11 +468,11 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) /* Initialize the CCE ring buffer data */ info->ringStart = info->agpOffset; - info->ringMapSize = info->ringSize*1024*1024 + 4096; + info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE; info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = 4096; + info->ringReadMapSize = DRM_PAGE_SIZE; /* Reserve space for vertex/indirect buffers */ info->bufStart = info->ringReadOffset + info->ringReadMapSize; @@ -576,21 +587,147 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) OUTREG(R128_AGP_BASE, info->ringHandle); /* Ring buf is at AGP offset 0 */ OUTREG(R128_AGP_CNTL, cntl); + /* Disable Rage 128's PCIGART registers */ + chunk = INREG(R128_BM_CHUNK_0_VAL); + chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | + R128_BM_PM4_RD_FORCE_TO_PCI | + R128_BM_GLOBAL_FORCE_TO_PCI); + OUTREG(R128_BM_CHUNK_0_VAL, chunk); + + OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */ + xf86EnablePciBusMaster(info->PciInfo, TRUE); return TRUE; } -#if 0 -/* Fake the vertex buffers for PCI cards. */ -static Bool R128DRIPciInit(R128InfoPtr info) +static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen) { - info->bufStart = 0; - info->bufMapSize = info->bufSize*1024*1024; + unsigned char *R128MMIO = info->MMIO; + CARD32 chunk; + int ret; + int flags; + + info->agpOffset = 0; + + ret = drmScatterGatherAlloc(info->drmFD, info->agpSize*1024*1024, + &info->pciMemHandle); + if (ret < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] %d kB allocated with handle 0x%08x\n", + info->agpSize*1024, info->pciMemHandle); + + /* Initialize the CCE ring buffer data */ + info->ringStart = info->agpOffset; + info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE; + info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = DRM_PAGE_SIZE; + + /* Reserve space for vertex/indirect buffers */ + info->bufStart = info->ringReadOffset + info->ringReadMapSize; + info->bufMapSize = info->bufSize*1024*1024; + + flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; + + if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize, + DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[pci] Could not add ring mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] ring handle = 0x%08lx\n", info->ringHandle); + + if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize, + (drmAddressPtr)&info->ring) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] Ring mapped at 0x%08lx\n", + (unsigned long)info->ring); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] Ring contents 0x%08lx\n", + *(unsigned long *)info->ring); + + if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, + DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[pci] Could not add ring read ptr mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] ring read ptr handle = 0x%08lx\n", + info->ringReadPtrHandle); + + if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, + (drmAddressPtr)&info->ringReadPtr) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[pci] Could not map ring read ptr\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] Ring read ptr mapped at 0x%08lx\n", + (unsigned long)info->ringReadPtr); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] Ring read ptr contents 0x%08lx\n", + *(unsigned long *)info->ringReadPtr); + + if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize, + DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[pci] Could not add vertex/indirect buffers mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] vertex/indirect buffers handle = 0x%08lx\n", + info->bufHandle); + + if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize, + (drmAddressPtr)&info->buf) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[pci] Could not map vertex/indirect buffers\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", + (unsigned long)info->buf); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[pci] Vertex/indirect buffers contents 0x%08lx\n", + *(unsigned long *)info->buf); + + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RK: + /* This is a PCI card, do nothing */ + break; + + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RG: + case PCI_CHIP_RAGE128RL: + case PCI_CHIP_RAGE128PF: + default: + /* This is really an AGP card, force PCI GART mode */ + chunk = INREG(R128_BM_CHUNK_0_VAL); + chunk |= (R128_BM_PTR_FORCE_TO_PCI | + R128_BM_PM4_RD_FORCE_TO_PCI | + R128_BM_GLOBAL_FORCE_TO_PCI); + OUTREG(R128_BM_CHUNK_0_VAL, chunk); + OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ + break; + } return TRUE; } -#endif /* Add a map for the MMIO registers that will be accessed by any DRI-based clients. */ @@ -655,11 +792,20 @@ static int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen) static Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen) { /* Initialize vertex buffers */ - if ((info->bufNumBufs = drmAddBufs(info->drmFD, - info->bufMapSize / R128_BUFFER_SIZE, - R128_BUFFER_SIZE, - DRM_AGP_BUFFER, - info->bufStart)) <= 0) { + if (info->IsPCI) { + info->bufNumBufs = drmAddBufs(info->drmFD, + info->bufMapSize / R128_BUFFER_SIZE, + R128_BUFFER_SIZE, + DRM_SG_BUFFER, + info->bufStart); + } else { + info->bufNumBufs = drmAddBufs(info->drmFD, + info->bufMapSize / R128_BUFFER_SIZE, + R128_BUFFER_SIZE, + DRM_AGP_BUFFER, + info->bufStart); + } + if (info->bufNumBufs <= 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Could not create vertex/indirect buffers list\n"); return FALSE; @@ -803,7 +949,7 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) pDRIInfo->SAREASize = SAREA_MAX; #endif - if (!(pR128DRI = (R128DRIPtr)xnfcalloc(sizeof(R128DRIRec),1))) { + if (!(pR128DRI = (R128DRIPtr)xcalloc(sizeof(R128DRIRec),1))) { DRIDestroyInfoRec(info->pDRIInfo); info->pDRIInfo = NULL; return FALSE; @@ -853,22 +999,18 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) /* Initialize AGP */ if (!info->IsPCI && !R128DRIAgpInit(info, pScreen)) { - R128DRICloseScreen(pScreen); - return FALSE; + info->IsPCI = TRUE; + xf86DrvMsg(pScreen->myNum, X_WARNING, + "AGP failed to initialize -- falling back to PCI mode.\n"); + xf86DrvMsg(pScreen->myNum, X_WARNING, + "Make sure you have the agpgart kernel module loaded.\n"); } -#if 0 - /* Initialize PCI */ + + /* Initialize PCIGART */ if (info->IsPCI && !R128DRIPciInit(info, pScreen)) { R128DRICloseScreen(pScreen); return FALSE; } -#else - if (info->IsPCI) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n"); - R128DRICloseScreen(pScreen); - return FALSE; - } -#endif /* DRIScreenInit doesn't add all the common mappings. Add additional @@ -918,7 +1060,7 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) } /* Initialize the vertex buffers list */ - if (!info->IsPCI && !R128DRIBufInit(info, pScreen)) { + if (!R128DRIBufInit(info, pScreen)) { R128DRICloseScreen(pScreen); return FALSE; } @@ -929,36 +1071,36 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate; - - pR128DRI->deviceID = info->Chipset; - pR128DRI->width = pScrn->virtualX; - pR128DRI->height = pScrn->virtualY; - pR128DRI->depth = pScrn->depth; - pR128DRI->bpp = pScrn->bitsPerPixel; - - pR128DRI->IsPCI = info->IsPCI; - pR128DRI->AGPMode = info->agpMode; - - pR128DRI->frontOffset = info->frontOffset; - pR128DRI->frontPitch = info->frontPitch; - pR128DRI->backOffset = info->backOffset; - pR128DRI->backPitch = info->backPitch; - pR128DRI->depthOffset = info->depthOffset; - pR128DRI->depthPitch = info->depthPitch; - pR128DRI->spanOffset = info->spanOffset; - pR128DRI->textureOffset = info->textureOffset; - pR128DRI->textureSize = info->textureSize; - pR128DRI->log2TexGran = info->log2TexGran; - - pR128DRI->registerHandle = info->registerHandle; - pR128DRI->registerSize = info->registerSize; - - pR128DRI->agpTexHandle = info->agpTexHandle; - pR128DRI->agpTexMapSize = info->agpTexMapSize; - pR128DRI->log2AGPTexGran = info->log2AGPTexGran; - pR128DRI->agpTexOffset = info->agpTexStart; - pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate; + + pR128DRI->deviceID = info->Chipset; + pR128DRI->width = pScrn->virtualX; + pR128DRI->height = pScrn->virtualY; + pR128DRI->depth = pScrn->depth; + pR128DRI->bpp = pScrn->bitsPerPixel; + + pR128DRI->IsPCI = info->IsPCI; + pR128DRI->AGPMode = info->agpMode; + + pR128DRI->frontOffset = info->frontOffset; + pR128DRI->frontPitch = info->frontPitch; + pR128DRI->backOffset = info->backOffset; + pR128DRI->backPitch = info->backPitch; + pR128DRI->depthOffset = info->depthOffset; + pR128DRI->depthPitch = info->depthPitch; + pR128DRI->spanOffset = info->spanOffset; + pR128DRI->textureOffset = info->textureOffset; + pR128DRI->textureSize = info->textureSize; + pR128DRI->log2TexGran = info->log2TexGran; + + pR128DRI->registerHandle = info->registerHandle; + pR128DRI->registerSize = info->registerSize; + + pR128DRI->agpTexHandle = info->agpTexHandle; + pR128DRI->agpTexMapSize = info->agpTexMapSize; + pR128DRI->log2AGPTexGran = info->log2AGPTexGran; + pR128DRI->agpTexOffset = info->agpTexStart; + pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); return TRUE; } @@ -1007,6 +1149,10 @@ void R128DRICloseScreen(ScreenPtr pScreen) info->agpMemHandle = 0; drmAgpRelease(info->drmFD); } + if (info->pciMemHandle) { + drmScatterGatherFree(info->drmFD, info->pciMemHandle); + info->pciMemHandle = 0; + } /* De-allocate all DRI resources */ DRICloseScreen(pScreen); |