diff options
author | kem <kem> | 2001-03-26 22:36:48 +0000 |
---|---|---|
committer | kem <kem> | 2001-03-26 22:36:48 +0000 |
commit | b93feef9402edcb36474fa6e106427b2b6e12acb (patch) | |
tree | f65f5591f1975bd7931ec909bdcf61baa4217c2c /xc/programs/Xserver/hw | |
parent | 7bf7bda7738b2029bc71015f9ea08304c15e7240 (diff) |
- Started a new branch off the trunk for the ati pcigart work instead of
mergeing the massive changes from the trunk into the old pcigart branch
- Partially merged code from old pcigart branch -- does NOT compile/work yet
- Fixing/cleaning up the code as I go
- Still need to merge kernel changes (very major) and PPC changes (minor)
Diffstat (limited to 'xc/programs/Xserver/hw')
9 files changed, 965 insertions, 339 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h index 003b9aa2e..3adabfe25 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h @@ -273,6 +273,9 @@ typedef struct { drmHandle registerHandle; Bool IsPCI; /* Current card is a PCI card */ + drmSize pciSize; + drmHandle pciMemHandle; + unsigned char *PCI; /* Map */ drmSize agpSize; drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ 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 0e9b67bf5..a1b8a950c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -47,6 +47,7 @@ /* X and server generic header files */ #include "xf86.h" #include "windowstr.h" +#include "xf86PciInfo.h" /* GLX/DRI/DRM definitions */ #define _XF86DRI_SERVER_ @@ -72,6 +73,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 @@ -399,12 +403,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; } @@ -576,19 +580,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 + 4096; + info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = 4096; + + /* 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. */ @@ -653,11 +785,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; @@ -735,10 +876,10 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) /* Check the DRI version */ DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 1 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "R128DRIScreenInit failed " - "(DRI version = %d.%d.%d, expected 3.1.x). " + "(DRI version = %d.%d.%d, expected 4.0.x). " "Disabling DRI.\n", major, minor, patch); return FALSE; @@ -817,6 +958,9 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = R128DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n"); xfree(pDRIInfo->devPrivate); @@ -830,8 +974,7 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) version = drmGetVersion(info->drmFD); if (version) { if (version->version_major != 2 || - version->version_minor != 1 || - version->version_patchlevel < 0) { + version->version_minor < 1) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "R128DRIScreenInit failed " @@ -849,22 +992,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 @@ -914,7 +1053,7 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) } /* Initialize the vertex buffers list */ - if (!info->IsPCI && !R128DRIBufInit(info, pScreen)) { + if (!R128DRIBufInit(info, pScreen)) { R128DRICloseScreen(pScreen); return FALSE; } @@ -925,35 +1064,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 = (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; } @@ -1002,6 +1142,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); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c index ebbb43a35..5b1e965ee 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -107,6 +107,8 @@ #define MAX(a,b) ((a)>(b)?(a):(b)) #endif +#define USE_CRT_ONLY 0 + /* Forward definitions for driver functions */ static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool R128SaveScreen(ScreenPtr pScreen, int mode); @@ -134,6 +136,10 @@ typedef enum { OPTION_BUFFER_SIZE, OPTION_USE_CCE_2D, #endif +#if USE_CRT_ONLY + /* FIXME: Disable CRTOnly until it is tested */ + OPTION_CRT, +#endif OPTION_BIOS_DISPLAY, OPTION_PANEL_WIDTH, OPTION_PANEL_HEIGHT, @@ -1180,9 +1186,7 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn) { R128InfoPtr info = R128PTR(pScrn); - if (info->IsPCI) { - info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; - } else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) { + if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n"); info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; } else { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h index e9d584ab9..81d4c2fe2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h @@ -191,6 +191,10 @@ #define R128_BIOS_7_SCRATCH 0x002c #define R128_BIOS_ROM 0x0f30 /* PCI */ #define R128_BIST 0x0f0f /* PCI */ +#define R128_BM_CHUNK_0_VAL 0x0a18 +# define R128_BM_PTR_FORCE_TO_PCI (1 << 21) +# define R128_BM_PM4_RD_FORCE_TO_PCI (1 << 22) +# define R128_BM_GLOBAL_FORCE_TO_PCI (1 << 23) #define R128_BRUSH_DATA0 0x1480 #define R128_BRUSH_DATA1 0x1484 #define R128_BRUSH_DATA10 0x14a8 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h index a527234d7..13da7345d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -58,6 +58,11 @@ #include "GL/glxint.h" #endif + /* Render support */ +#ifdef RENDER +#include "picturestr.h" +#endif + #define RADEON_DEBUG 0 /* Turn off debugging output */ #define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ #define RADEON_MMIOSIZE 0x80000 @@ -274,6 +279,9 @@ typedef struct { drmHandle registerHandle; Bool IsPCI; /* Current card is a PCI card */ + drmSize pciSize; + drmHandle pciMemHandle; + unsigned char *PCI; /* Map */ Bool depthMoves; /* Enable depth moves -- slow! */ @@ -358,6 +366,10 @@ typedef struct { CARD32 re_width_height; CARD32 aux_sc_cntl; + +#ifdef PER_CONTEXT_SAREA + int perctx_sarea_size; +#endif #endif XF86VideoAdaptorPtr adaptor; @@ -405,19 +417,19 @@ extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn); #define RADEONCP_START(pScrn, info) \ do { \ - int _ret = drmRadeonStartCP(info->drmFD); \ - if (_ret) { \ + int ret = drmRadeonStartCP(info->drmFD); \ + if (ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ - "%s: CP start %d\n", __FUNCTION__, _ret); \ + "%s: CP start %d\n", __FUNCTION__, ret); \ } \ } while (0) #define RADEONCP_STOP(pScrn, info) \ do { \ - int _ret = drmRadeonStopCP(info->drmFD); \ - if (_ret) { \ + int ret = drmRadeonStopCP(info->drmFD); \ + if (ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ - "%s: CP stop %d\n", __FUNCTION__, _ret); \ + "%s: CP stop %d\n", __FUNCTION__, ret); \ } \ RADEONEngineRestore(pScrn); \ } while (0) @@ -425,10 +437,10 @@ do { \ #define RADEONCP_RESET(pScrn, info) \ do { \ if (RADEONCP_USE_RING_BUFFER(info->CPMode)) { \ - int _ret = drmRadeonResetCP(info->drmFD); \ - if (_ret) { \ + int ret = drmRadeonResetCP(info->drmFD); \ + if (ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ - "%s: CP reset %d\n", __FUNCTION__, _ret); \ + "%s: CP reset %d\n", __FUNCTION__, ret); \ } \ } \ } while (0) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c index ead827483..ddcf37543 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v 1.4 2001/01/21 21:19:20 tsi Exp $ */ +/* $XFree86$ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, * VA Linux Systems Inc., Fremont, California. @@ -105,7 +105,7 @@ static Bool RADEONInitVisualConfigs(ScreenPtr pScreen) for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) { pRADEONConfigPtrs[i] = &pRADEONConfigs[i]; - pConfigs[i].vid = (VisualID)(-1); + pConfigs[i].vid = -1; pConfigs[i].class = -1; pConfigs[i].rgba = TRUE; pConfigs[i].redSize = 5; @@ -181,7 +181,7 @@ static Bool RADEONInitVisualConfigs(ScreenPtr pScreen) for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) { pRADEONConfigPtrs[i] = &pRADEONConfigs[i]; - pConfigs[i].vid = (VisualID)(-1); + pConfigs[i].vid = -1; pConfigs[i].class = -1; pConfigs[i].rgba = TRUE; pConfigs[i].redSize = 8; @@ -244,7 +244,36 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual, drmContext hwContext, void *pVisualConfigPriv, DRIContextType contextStore) { - /* Nothing yet */ +#ifdef PER_CONTEXT_SAREA + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONDRIContextPtr ctx_info; + + ctx_info = (RADEONDRIContextPtr)contextStore; + if (!ctx_info) return FALSE; + + if (drmAddMap(info->drmFD, 0, + info->perctx_sarea_size, + DRM_SHM, + DRM_REMOVABLE, + &ctx_info->sarea_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[DRI] could not create private sarea for ctx id (%d)\n", + (int)hwContext); + return FALSE; + } + + if (drmAddContextPrivateMapping(info->drmFD, hwContext, + ctx_info->sarea_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[DRI] could not associate private sarea to ctx id (%d)\n", + (int)hwContext); + drmRmMap(info->drmFD, ctx_info->sarea_handle); + return FALSE; + } + + ctx_info->ctx_id = hwContext; +#endif return TRUE; } @@ -252,7 +281,20 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual, static void RADEONDestroyContext(ScreenPtr pScreen, drmContext hwContext, DRIContextType contextStore) { - /* Nothing yet */ +#ifdef PER_CONTEXT_SAREA + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONDRIContextPtr ctx_info; + + ctx_info = (RADEONDRIContextPtr) contextStore; + if (!ctx_info) return; + + if (drmRmMap(info->drmFD, ctx_info->sarea_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[DRI] could not remove private sarea for ctx id (%d)\n", + (int)hwContext); + } +#endif } /* Called when the X server is woken up to allow the last client's @@ -381,8 +423,8 @@ do { \ /* Screen to screen copy of data in the depth buffer */ static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn, - int xa, int ya, - int xb, int yb, + int x1, int y1, + int x2, int y2, int w, int h) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -391,26 +433,26 @@ static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn, int x, y, d; unsigned char *buf = info->FB + info->depthOffset; - if (xa < xb) xdir = -1, xstart = w-1, xend = 0; + if (x1 < x2) xdir = -1, xstart = w-1, xend = 0; else xdir = 1, xstart = 0, xend = w-1; - if (ya < yb) ydir = -1, ystart = h-1, yend = 0; + if (y1 < y2) ydir = -1, ystart = h-1, yend = 0; else ydir = 1, ystart = 0, yend = h-1; switch (pScrn->bitsPerPixel) { case 16: for (x = xstart; x != xend; x += xdir) { for (y = ystart; y != yend; y += ydir) { - READ_DEPTH16(d, xa+x, ya+y); - WRITE_DEPTH16(xb+x, yb+y, d); + READ_DEPTH16(d, x1+x, y1+y); + WRITE_DEPTH16(x2+x, y2+y, d); } } break; case 32: for (x = xstart; x != xend; x += xdir) { for (y = ystart; y != yend; y += ydir) { - READ_DEPTH32(d, xa+x, ya+y); - WRITE_DEPTH32(xb+x, yb+y, d); + READ_DEPTH32(d, x1+x, y1+y); + WRITE_DEPTH32(x2+x, y2+y, d); } } break; @@ -419,7 +461,7 @@ static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn, } /* Initialize the state of the back and depth buffers. */ -static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) +static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) { /* FIXME: This routine needs to have acceleration turned on */ ScreenPtr pScreen = pWin->drawable.pScreen; @@ -428,15 +470,27 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) RADEONSAREAPrivPtr pSAREAPriv; BoxPtr pbox; int nbox; - int depth; + unsigned int color, depth; + unsigned int color_mask, depth_mask; /* FIXME: This should be based on the __GLXvisualConfig info */ + color = 0; switch (pScrn->bitsPerPixel) { - case 8: depth = 0x000000ff; break; - case 16: depth = 0x0000ffff; break; - case 24: depth = 0x00ffffff; break; - case 32: depth = 0xffffffff; break; - default: depth = 0x00000000; break; + case 16: + depth = 0x0000ffff; + color_mask = 0x0000ffff; + depth_mask = 0xffffffff; + break; + case 32: + depth = 0x00ffffff; + color_mask = 0xffffffff; + depth_mask = 0xffffffff; + break; + default: + depth = 0x00000000; + color_mask = 0x00000000; + depth_mask = 0x00000000; + break; } /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */ @@ -464,11 +518,8 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) ret = drmRadeonClear(info->drmFD, DRM_RADEON_BACK | DRM_RADEON_DEPTH, - pbox->x1, - pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1, - 0, depth); + color, depth, color_mask, depth_mask, + pSAREAPriv->boxes, pSAREAPriv->nbox); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DRIInitBuffers timed out, resetting engine...\n"); @@ -495,14 +546,14 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) * are reversed. */ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, - RegionPtr prgnSrc, CARD32 indx) + RegionPtr prgnSrc, CARD32 index) { ScreenPtr pScreen = pParent->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); BoxPtr pboxTmp, pboxNext, pboxBase; - DDXPointPtr pptTmp; + DDXPointPtr pptTmp, pptNew2; int xdir, ydir; int screenwidth = pScrn->virtualX; @@ -511,10 +562,9 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, BoxPtr pbox = REGION_RECTS(prgnSrc); int nbox = REGION_NUM_RECTS(prgnSrc); - BoxPtr pboxNew1 = NULL; - BoxPtr pboxNew2 = NULL; - DDXPointPtr pptNew1 = NULL; - DDXPointPtr pptNew2 = NULL; + BoxPtr pboxNew1 = 0; + BoxPtr pboxNew2 = 0; + DDXPointPtr pptNew1 = 0; DDXPointPtr pptSrc = &ptOldOrg; int dx = pParent->drawable.x - ptOldOrg.x; @@ -564,10 +614,12 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); if (!pboxNew2 || !pptNew2) { - DEALLOCATE_LOCAL(pptNew2); - DEALLOCATE_LOCAL(pboxNew2); - DEALLOCATE_LOCAL(pptNew1); - DEALLOCATE_LOCAL(pboxNew1); + if (pptNew2) DEALLOCATE_LOCAL(pptNew2); + if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } return; } pboxBase = pboxNext = pbox; @@ -594,18 +646,18 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, } (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, - (CARD32)(-1), -1); + -1, -1); for (; nbox-- ; pbox++) { - int xa = pbox->x1; - int ya = pbox->y1; - int destx = xa + dx; - int desty = ya + dy; - int w = pbox->x2 - xa + 1; - int h = pbox->y2 - ya + 1; - - if (destx < 0) xa -= destx, w += destx, destx = 0; - if (desty < 0) ya -= desty, h += desty, desty = 0; + int x1 = pbox->x1; + int y1 = pbox->y1; + int destx = x1 + dx; + int desty = y1 + dy; + int w = pbox->x2 - x1 + 1; + int h = pbox->y2 - y1 + 1; + + if (destx < 0) x1 -= destx, w += destx, destx = 0; + if (desty < 0) y1 -= desty, h += desty, desty = 0; if (destx + w > screenwidth) w = screenwidth - destx; if (desty + h > screenheight) h = screenheight - desty; @@ -614,24 +666,28 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RADEONSelectBuffer(pScrn, RADEON_BACK); (*info->accel->SubsequentScreenToScreenCopy)(pScrn, - xa, ya, + x1, y1, destx, desty, w, h); RADEONSelectBuffer(pScrn, RADEON_DEPTH); if (info->depthMoves) RADEONScreenToScreenCopyDepth(pScrn, - xa, ya, + x1, y1, destx, desty, w, h); } RADEONSelectBuffer(pScrn, RADEON_FRONT); - DEALLOCATE_LOCAL(pptNew2); - DEALLOCATE_LOCAL(pboxNew2); - DEALLOCATE_LOCAL(pptNew1); - DEALLOCATE_LOCAL(pboxNew1); + if (pboxNew2) { + DEALLOCATE_LOCAL(pptNew2); + DEALLOCATE_LOCAL(pboxNew2); + } + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } info->accel->NeedToSync = TRUE; } @@ -803,23 +859,114 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen) /* Enable bus mastering in PCI config space */ - info->pciCommand = pciReadLong(info->PciTag, PCI_CMD_STAT_REG); - pciWriteLong(info->PciTag, PCI_CMD_STAT_REG, - info->pciCommand | PCI_CMD_MASTER_ENABLE); + xf86EnablePciBusMaster(info->PciInfo, TRUE); return TRUE; } -#if 0 -/* Fake the vertex buffers for PCI cards. */ +/* Initialize the PCIGART state. Request memory for use in PCI space, + and initialize the Radeon registers to point to that memory. */ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen) { - info->bufStart = 0; - info->bufMapSize = info->bufSize*1024*1024; + unsigned char *RADEONMMIO = info->MMIO; + 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 + 4096; + info->ringSizeLog2QW = RADEONMinBits(info->ringSize*1024*1024/8)-1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = 4096; + + /* 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); return TRUE; } -#endif /* Add a map for the MMIO registers that will be accessed by any DRI-based clients. */ @@ -883,11 +1030,24 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen) { /* Initialize vertex buffers */ - if ((info->bufNumBufs = drmAddBufs(info->drmFD, - info->bufMapSize / RADEON_BUFFER_SIZE, - RADEON_BUFFER_SIZE, - DRM_AGP_BUFFER, - info->bufStart)) <= 0) { + if (info->IsPCI) { +#if 1 + return TRUE; +#else + info->bufNumBufs = drmAddBufs(info->drmFD, + info->bufMapSize / RADEON_BUFFER_SIZE, + RADEON_BUFFER_SIZE, + DRM_SG_BUFFER, + info->bufStart); +#endif + } else { + info->bufNumBufs = drmAddBufs(info->drmFD, + info->bufMapSize / RADEON_BUFFER_SIZE, + RADEON_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; @@ -1028,9 +1188,9 @@ static void RADEONDRISAREAInit(ScreenPtr pScreen, ctx->pp_rot_matrix_0 = 0x00000000; ctx->pp_rot_matrix_1 = 0x00000000; - ctx->rb3d_stencilrefmask = ((0x000 << RADEON_STENCIL_REF_SHIFT) | - (0x0ff << RADEON_STENCIL_MASK_SHIFT) | - (0x0ff << RADEON_STENCIL_WRITEMASK_SHIFT)); + ctx->rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); ctx->rb3d_ropcntl = 0x00000000; ctx->rb3d_planemask = 0xffffffff; @@ -1133,10 +1293,10 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) /* Check the DRI version */ DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 1 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "RADEONDRIScreenInit failed " - "(DRI version = %d.%d.%d, expected 3.1.x). " + "(DRI version = %d.%d.%d, expected 4.0.x). " "Disabling DRI.\n", major, minor, patch); return FALSE; @@ -1180,6 +1340,11 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) < RADEON_MAX_DRAWABLES ? SAREA_MAX_DRAWABLES : RADEON_MAX_DRAWABLES); +#ifdef PER_CONTEXT_SAREA + /* This is only here for testing per-context SAREAs. When used, the + magic number below would be properly defined in a header file. */ + info->perctx_sarea_size = 64 * 1024; +#endif #ifdef NOT_DONE /* FIXME: Need to extend DRI protocol to pass this size back to @@ -1215,6 +1380,9 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n"); xfree(pDRIInfo->devPrivate); @@ -1228,8 +1396,7 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) version = drmGetVersion(info->drmFD); if (version) { if (version->version_major != 1 || - version->version_minor != 0 || - version->version_patchlevel < 0) { + version->version_minor < 0) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "RADEONDRIScreenInit failed " @@ -1245,20 +1412,31 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) drmFreeVersion(version); } +#if 1 /* Initialize AGP */ if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } -#if 0 + /* Initialize PCI */ - if (info->IsPCI && !RADEONDRIPciInit(info, pScreen)) { + if (info->IsPCI) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n"); RADEONDRICloseScreen(pScreen); return FALSE; } #else - if (info->IsPCI) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n"); + /* Initialize AGP */ + if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) { + 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"); + } + + /* Initialize PCI */ + if (info->IsPCI && !RADEONDRIPciInit(info, pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } @@ -1312,7 +1490,7 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) } /* Initialize the vertex buffers list */ - if (!info->IsPCI && !RADEONDRIBufInit(info, pScreen)) { + if (!RADEONDRIBufInit(info, pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } @@ -1323,39 +1501,47 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) /* Initialize the SAREA private data structure */ pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + RADEONDRISAREAInit(pScreen, pSAREAPriv); - pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate; + pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate; + + pRADEONDRI->deviceID = info->Chipset; + pRADEONDRI->width = pScrn->virtualX; + pRADEONDRI->height = pScrn->virtualY; + pRADEONDRI->depth = pScrn->depth; + pRADEONDRI->bpp = pScrn->bitsPerPixel; + + pRADEONDRI->IsPCI = info->IsPCI; + pRADEONDRI->AGPMode = info->agpMode; - pRADEONDRI->deviceID = info->Chipset; - pRADEONDRI->width = pScrn->virtualX; - pRADEONDRI->height = pScrn->virtualY; - pRADEONDRI->depth = pScrn->depth; - pRADEONDRI->bpp = pScrn->bitsPerPixel; + pRADEONDRI->frontOffset = info->frontOffset; + pRADEONDRI->frontPitch = info->frontPitch; + pRADEONDRI->backOffset = info->backOffset; + pRADEONDRI->backPitch = info->backPitch; + pRADEONDRI->depthOffset = info->depthOffset; + pRADEONDRI->depthPitch = info->depthPitch; + pRADEONDRI->textureOffset = info->textureOffset; + pRADEONDRI->textureSize = info->textureSize; + pRADEONDRI->log2TexGran = info->log2TexGran; - pRADEONDRI->IsPCI = info->IsPCI; - pRADEONDRI->AGPMode = info->agpMode; + pRADEONDRI->registerHandle = info->registerHandle; + pRADEONDRI->registerSize = info->registerSize; - pRADEONDRI->frontOffset = info->frontOffset; - pRADEONDRI->frontPitch = info->frontPitch; - pRADEONDRI->backOffset = info->backOffset; - pRADEONDRI->backPitch = info->backPitch; - pRADEONDRI->depthOffset = info->depthOffset; - pRADEONDRI->depthPitch = info->depthPitch; - pRADEONDRI->textureOffset = info->textureOffset; - pRADEONDRI->textureSize = info->textureSize; - pRADEONDRI->log2TexGran = info->log2TexGran; + pRADEONDRI->statusHandle = info->ringReadPtrHandle; + pRADEONDRI->statusSize = info->ringReadMapSize; - pRADEONDRI->registerHandle = info->registerHandle; - pRADEONDRI->registerSize = info->registerSize; + pRADEONDRI->agpTexHandle = info->agpTexHandle; + pRADEONDRI->agpTexMapSize = info->agpTexMapSize; + pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran; + pRADEONDRI->agpTexOffset = info->agpTexStart; - pRADEONDRI->statusHandle = info->ringReadPtrHandle; - pRADEONDRI->statusSize = info->ringReadMapSize; + pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); - pRADEONDRI->agpTexHandle = info->agpTexHandle; - pRADEONDRI->agpTexMapSize = info->agpTexMapSize; - pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran; - pRADEONDRI->agpTexOffset = info->agpTexStart; +#ifdef PER_CONTEXT_SAREA + /* Set per-context SAREA size */ + pRADEONDRI->perctx_sarea_size = info->perctx_sarea_size; +#endif return TRUE; } @@ -1404,9 +1590,10 @@ void RADEONDRICloseScreen(ScreenPtr pScreen) info->agpMemHandle = 0; drmAgpRelease(info->drmFD); } - - /* Restore PCI command register */ - pciWriteLong(info->PciTag, PCI_CMD_STAT_REG, info->pciCommand); + if (info->pciMemHandle) { + drmScatterGatherFree(info->drmFD, info->pciMemHandle); + info->pciMemHandle = 0; + } /* De-allocate all DRI resources */ DRICloseScreen(pScreen); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c index 26049b328..276ba052f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -1103,9 +1103,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - if (info->IsPCI) { - info->CPMode = RADEON_DEFAULT_CP_PIO_MODE; - } else if (xf86ReturnOptValBool(RADEONOptions, OPTION_CP_PIO, FALSE)) { + if (xf86ReturnOptValBool(RADEONOptions, OPTION_CP_PIO, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CP into PIO mode\n"); info->CPMode = RADEON_DEFAULT_CP_PIO_MODE; } else { @@ -1739,11 +1737,13 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) y2 = (info->FbMapSize / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes)); + if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + /* The acceleration engine uses 14 bit signed coordinates, so we can't have any drawable caches beyond this region. */ - if (y2 > 8191 ) y2 = 8191; - MemBox.y2 = y2; + if (MemBox.y2 > 8191) MemBox.y2 = 8191; if (!xf86InitFBManager(pScreen, &MemBox)) { xf86DrvMsg(scrnIndex, X_ERROR, diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c index 5c2c08c3b..8aa27fd3e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,12 +23,12 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: Rickard E. (Rik) Faith <faith@valinux.com> * Kevin E. Martin <martin@valinux.com> * * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.17 2000/09/24 13:51:32 alanh Exp $ - * + * */ #ifdef XFree86Server @@ -81,7 +81,18 @@ extern unsigned long _bus_base(void); #include "xf86drm.h" #include "drm.h" -#define DRM_FIXED_DEVICE_MAJOR 145 +#ifndef DRM_MAJOR +#define DRM_MAJOR 226 /* Linux */ +#endif + +#ifndef __linux__ +#undef DRM_MAJOR +#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */ +#endif + +#ifndef DRM_MAX_MINOR +#define DRM_MAX_MINOR 16 +#endif #ifdef __linux__ #include <sys/sysmacros.h> /* for makedev() */ @@ -119,7 +130,7 @@ void drmFree(void *pt) static char *drmStrdup(const char *s) { char *retval = NULL; - + if (s) { retval = _DRM_MALLOC(strlen(s)+1); strcpy(retval, s); @@ -161,93 +172,108 @@ static drmHashEntry *drmGetEntry(int fd) return entry; } -/* drm_open is used to open the /dev/dri device */ - -static int drm_open(const char *file) -{ - int fd = open(file, O_RDWR, 0); - - if (fd >= 0) return fd; - return -errno; -} - -static int drmOpenDevice(const char *path, long dev, - mode_t mode, uid_t user, gid_t group) +static int drmOpenDevice(long dev, int minor) { #ifdef XFree86LOADER struct xf86stat st; #else struct stat st; #endif + char buf[64]; + int fd; + mode_t dirmode = DRM_DEV_DIRMODE; + mode_t devmode = DRM_DEV_MODE; + int isroot = !geteuid(); +#if defined(XFree86Server) + uid_t user = DRM_DEV_UID; + gid_t group = DRM_DEV_GID; +#endif - /* Fiddle mode to remove execute bits */ - mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); +#if defined(XFree86Server) + devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; + dirmode = (devmode & S_IRUSR) ? S_IXUSR : 0; + dirmode |= (devmode & S_IRGRP) ? S_IXGRP : 0; + dirmode |= (devmode & S_IROTH) ? S_IXOTH : 0; + dirmode |= devmode; + devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); + group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID; +#endif - if (!stat(path, &st) && st.st_rdev == dev) { - if (!geteuid()) { - chown(path, user, group); - chmod(path, mode); - } - return drm_open(path); + if (stat(DRM_DIR_NAME, &st)) { + if (!isroot) return DRM_ERR_NOT_ROOT; + remove(DRM_DIR_NAME); + mkdir(DRM_DIR_NAME, dirmode); } +#if defined(XFree86Server) + chown(DRM_DIR_NAME, user, group); + chmod(DRM_DIR_NAME, dirmode); +#endif - if (geteuid()) return DRM_ERR_NOT_ROOT; - remove(path); - if (mknod(path, S_IFCHR, dev)) { - remove(path); - return DRM_ERR_NOT_ROOT; + sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + if (stat(buf, &st) || st.st_rdev != dev) { + if (!isroot) return DRM_ERR_NOT_ROOT; + remove(buf); + mknod(buf, S_IFCHR | devmode, dev); } - chown(path, user, group); - chmod(path, mode); - return drm_open(path); +#if defined(XFree86Server) + chown(buf, user, group); + chmod(buf, devmode); +#endif + + if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; + remove(buf); + return -errno; } -/* drmAvailable looks for /proc/dri, and returns 1 if it is present. On - OSs that do not have a Linux-like /proc, this information will not be - available, and we'll have to create a device and check if the driver is - loaded that way. */ +int drmOpenMinor(int minor, int create) +{ + int fd; + char buf[64]; + + if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor); + + sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; + return -errno; +} + +/* drmAvailable looks for (DRM_MAJOR, 0) and returns 1 if it returns + information for DRM_IOCTL_VERSION. For backward compatibility with + older Linux implementations, /proc/dri is also checked. */ int drmAvailable(void) { - char dev_name[64]; drmVersionPtr version; int retval = 0; int fd; + + if ((fd = drmOpenMinor(0, 1)) < 0) { + /* Try proc for backward Linux compatibility */ + if (!access("/proc/dri/0", R_OK)) return 1; + return 0; + } - if (!access("/proc/dri/0", R_OK)) return 1; - - sprintf(dev_name, "/dev/dri-temp-%d", getpid()); - - remove(dev_name); - if ((fd = drmOpenDevice(dev_name, makedev(DRM_FIXED_DEVICE_MAJOR, 0), - S_IRUSR, geteuid(), getegid())) >= 0) { - /* Read version to make sure this is - actually a DRI device. */ - if ((version = drmGetVersion(fd))) { - retval = 1; - drmFreeVersion(version); - } - close(fd); + if ((version = drmGetVersion(fd))) { + retval = 1; + drmFreeVersion(version); } - remove(dev_name); + close(fd); return retval; } static int drmOpenByBusid(const char *busid) { - int i; - char dev_name[64]; - char *buf; - int fd; - - for (i = 0; i < 8; i++) { - sprintf(dev_name, "/dev/dri/card%d", i); - if ((fd = drm_open(dev_name)) >= 0) { + int i; + int fd; + const char *buf; + + for (i = 0; i < DRM_MAX_MINOR; i++) { + if ((fd = drmOpenMinor(i, 0)) >= 0) { buf = drmGetBusid(fd); if (buf && !strcmp(buf, busid)) { - drmFreeBusid(buf); - return fd; + drmFreeBusid(buf); + return fd; } if (buf) drmFreeBusid(buf); close(fd); @@ -258,54 +284,43 @@ static int drmOpenByBusid(const char *busid) static int drmOpenByName(const char *name) { - int i; - char proc_name[64]; - char dev_name[64]; - char buf[512]; - mode_t mode = DRM_DEV_MODE; - mode_t dirmode; - gid_t group = DRM_DEV_GID; - uid_t user = DRM_DEV_UID; - int fd; - char *pt; - char *driver = NULL; - char *devstring; - long dev = 0; - int retcode; - -#if defined(XFree86Server) - mode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; - group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID; -#endif - -#if defined(XFree86Server) + int i; + int fd; + drmVersionPtr version; + if (!drmAvailable()) { +#if !defined(XFree86Server) + return -1; +#else /* try to load the kernel module now */ if (!xf86LoadKernelModule(name)) { ErrorF("[drm] failed to load kernel module \"%s\"\n", name); return -1; } - } -#else - if (!drmAvailable()) - return -1; #endif + } - if (!geteuid()) { - dirmode = mode; - if (dirmode & S_IRUSR) dirmode |= S_IXUSR; - if (dirmode & S_IRGRP) dirmode |= S_IXGRP; - if (dirmode & S_IROTH) dirmode |= S_IXOTH; - dirmode &= ~(S_IWGRP | S_IWOTH); - mkdir("/dev/dri", 0); - chown("/dev/dri", user, group); - chmod("/dev/dri", dirmode); + for (i = 0; i < DRM_MAX_MINOR; i++) { + if ((fd = drmOpenMinor(i, 1)) >= 0) { + if ((version = drmGetVersion(fd))) { + if (!strcmp(version->name, name)) { + drmFreeVersion(version); + return fd; + } + drmFreeVersion(version); + } + } } +#ifdef __linux__ + /* Backward-compatibility /proc support */ for (i = 0; i < 8; i++) { + char proc_name[64], buf[512]; + char *driver, *pt, *devstring; + int retcode; + sprintf(proc_name, "/proc/dri/%d/name", i); - sprintf(dev_name, "/dev/dri/card%d", i); if ((fd = open(proc_name, 0, 0)) >= 0) { retcode = read(fd, buf, sizeof(buf)-1); close(fd); @@ -319,34 +334,17 @@ static int drmOpenByName(const char *name) for (devstring = ++pt; *pt && *pt != ' '; ++pt) ; if (*pt) { /* Found busid */ - return drmOpenByBusid(++pt); + return drmOpenByBusid(++pt); } else { /* No busid */ - dev = strtol(devstring, NULL, 0); - return drmOpenDevice(dev_name, dev, - mode, user, group); + return drmOpenDevice(strtol(devstring, NULL, 0),i); } } } } - } else { - drmVersionPtr version; - /* /proc/dri not available, possibly - because we aren't on a Linux system. - So, try to create the next device and - see if it's active. */ - dev = makedev(DRM_FIXED_DEVICE_MAJOR, i); - if ((fd = drmOpenDevice(dev_name, dev, mode, user, group))) { - if ((version = drmGetVersion(fd))) { - if (!strcmp(version->name, name)) { - drmFreeVersion(version); - return fd; - } - drmFreeVersion(version); - } - } - remove(dev_name); } } +#endif + return -1; } @@ -408,7 +406,7 @@ drmVersionPtr drmGetVersion(int fd) version->date = NULL; version->desc_len = 0; version->desc = NULL; - + if (ioctl(fd, DRM_IOCTL_VERSION, version)) { drmFreeKernelVersion(version); return NULL; @@ -421,7 +419,7 @@ drmVersionPtr drmGetVersion(int fd) version->date = drmMalloc(version->date_len + 1); if (version->desc_len) version->desc = drmMalloc(version->desc_len + 1); - + if (ioctl(fd, DRM_IOCTL_VERSION, version)) { drmFreeKernelVersion(version); return NULL; @@ -503,7 +501,7 @@ int drmAddMap(int fd, map.offset = offset; #ifdef __alpha__ /* Make sure we add the bus_base to all but shm */ - if (type != DRM_SHM) + if (type != DRM_SHM) map.offset += BUS_BASE; #endif map.size = size; @@ -515,18 +513,28 @@ int drmAddMap(int fd, return 0; } +int drmRmMap(int fd, drmHandle handle) +{ + drm_map_t map; + + map.handle = (void *)handle; + + if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno; + return 0; +} + int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, int agp_offset) { drm_buf_desc_t request; - + request.count = count; request.size = size; request.low_mark = 0; request.high_mark = 0; request.flags = flags; request.agp_start = agp_offset; - + if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno; return request.count; } @@ -542,16 +550,16 @@ int drmMarkBufs(int fd, double low, double high) if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL; if (!info.count) return -EINVAL; - + if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) return -ENOMEM; - + if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { int retval = -errno; drmFree(info.list); return retval; } - + for (i = 0; i < info.count; i++) { info.list[i].low_mark = low * info.list[i].count; info.list[i].high_mark = high * info.list[i].count; @@ -562,7 +570,7 @@ int drmMarkBufs(int fd, double low, double high) } } drmFree(info.list); - + return 0; } @@ -630,7 +638,7 @@ drmBufInfoPtr drmGetBufInfo(int fd) if (info.count) { if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) return NULL; - + if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { drmFree(info.list); return NULL; @@ -657,7 +665,7 @@ drmBufMapPtr drmMapBufs(int fd) drm_buf_map_t bufs; drmBufMapPtr retval; int i; - + bufs.count = 0; bufs.list = NULL; if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL; @@ -689,16 +697,19 @@ drmBufMapPtr drmMapBufs(int fd) int drmUnmapBufs(drmBufMapPtr bufs) { int i; - + for (i = 0; i < bufs->count; i++) { munmap(bufs->list[i].address, bufs->list[i].total); } return 0; } +#define DRM_DMA_RETRY 16 + int drmDMA(int fd, drmDMAReqPtr request) { drm_dma_t dma; + int ret, i = 0; /* Copy to hidden structure */ dma.context = request->context; @@ -710,10 +721,17 @@ int drmDMA(int fd, drmDMAReqPtr request) dma.request_size = request->request_size; dma.request_indices = request->request_list; dma.request_sizes = request->request_sizes; - if (ioctl(fd, DRM_IOCTL_DMA, &dma)) return -errno; - request->granted_count = dma.granted_count; - - return 0; + + do { + ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); + } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); + + if ( ret == 0 ) { + request->granted_count = dma.granted_count; + return 0; + } else { + return -errno; + } } int drmGetLock(int fd, drmContext context, drmLockFlags flags) @@ -728,7 +746,7 @@ int drmGetLock(int fd, drmContext context, drmLockFlags flags) if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; - + while (ioctl(fd, DRM_IOCTL_LOCK, &lock)) ; return 0; @@ -827,7 +845,7 @@ int drmGetContextFlags(int fd, drmContext context, drmContextFlagsPtr flags) if (ctx.flags & _DRM_CONTEXT_2DONLY) *flags |= DRM_CONTEXT_2DONLY; return 0; } - + int drmDestroyContext(int fd, drmContext handle) { drm_ctx_t ctx; @@ -989,6 +1007,28 @@ unsigned int drmAgpDeviceId(int fd) return i.id_device; } +int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle) +{ + drm_scatter_gather_t sg; + + *handle = 0; + sg.size = size; + sg.handle = 0; + if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno; + *handle = sg.handle; + return 0; +} + +int drmScatterGatherFree(int fd, unsigned long handle) +{ + drm_scatter_gather_t sg; + + sg.size = 0; + sg.handle = handle; + if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno; + return 0; +} + int drmError(int err, const char *label) { switch (err) { @@ -1074,12 +1114,189 @@ void *drmGetContextTag(int fd, drmContext context) { drmHashEntry *entry = drmGetEntry(fd); void *value; - + if (drmHashLookup(entry->tagTable, context, &value)) return NULL; return value; } +int drmAddContextPrivateMapping(int fd, drmContext ctx_id, drmHandle handle) +{ + drm_ctx_priv_map_t map; + + map.ctx_id = ctx_id; + map.handle = (void *)handle; + + if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno; + return 0; +} + +int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle) +{ + drm_ctx_priv_map_t map; + + map.ctx_id = ctx_id; + + if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno; + if (handle) *handle = (drmHandle)map.handle; + + return 0; +} + +int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size, + drmMapType *type, drmMapFlags *flags, drmHandle *handle, + int *mtrr) +{ + drm_map_t map; + + map.offset = idx; + if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno; + *offset = map.offset; + *size = map.size; + *type = map.type; + *flags = map.flags; + *handle = (unsigned long)map.handle; + *mtrr = map.mtrr; + return 0; +} + +int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, + unsigned long *magic, unsigned long *iocs) +{ + drm_client_t client; + + client.idx = idx; + if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno; + *auth = client.auth; + *pid = client.pid; + *uid = client.uid; + *magic = client.magic; + *iocs = client.iocs; + return 0; +} + +int drmGetStats(int fd, drmStatsT *stats) +{ + drm_stats_t s; + int i; + + if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno; + + stats->count = 0; + memset(stats, 0, sizeof(*stats)); + if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) + return -1; + +#define SET_VALUE \ + stats->data[i].long_format = "%-20.20s"; \ + stats->data[i].rate_format = "%8.8s"; \ + stats->data[i].isvalue = 1; \ + stats->data[i].verbose = 0 + +#define SET_COUNT \ + stats->data[i].long_format = "%-20.20s"; \ + stats->data[i].rate_format = "%5.5s"; \ + stats->data[i].isvalue = 0; \ + stats->data[i].mult_names = "kgm"; \ + stats->data[i].mult = 1000; \ + stats->data[i].verbose = 0 + +#define SET_BYTE \ + stats->data[i].long_format = "%-20.20s"; \ + stats->data[i].rate_format = "%5.5s"; \ + stats->data[i].isvalue = 0; \ + stats->data[i].mult_names = "KGM"; \ + stats->data[i].mult = 1024; \ + stats->data[i].verbose = 0 + + + stats->count = s.count; + for (i = 0; i < s.count; i++) { + stats->data[i].value = s.data[i].value; + switch (s.data[i].type) { + case _DRM_STAT_LOCK: + stats->data[i].long_name = "Lock"; + stats->data[i].rate_name = "Lock"; + SET_VALUE; + break; + case _DRM_STAT_OPENS: + stats->data[i].long_name = "Opens"; + stats->data[i].rate_name = "O"; + SET_COUNT; + stats->data[i].verbose = 1; + break; + case _DRM_STAT_CLOSES: + stats->data[i].long_name = "Closes"; + stats->data[i].rate_name = "Lock"; + SET_COUNT; + stats->data[i].verbose = 1; + break; + case _DRM_STAT_IOCTLS: + stats->data[i].long_name = "Ioctls"; + stats->data[i].rate_name = "Ioc/s"; + SET_COUNT; + break; + case _DRM_STAT_LOCKS: + stats->data[i].long_name = "Locks"; + stats->data[i].rate_name = "Lck/s"; + SET_COUNT; + break; + case _DRM_STAT_UNLOCKS: + stats->data[i].long_name = "Unlocks"; + stats->data[i].rate_name = "Unl/s"; + SET_COUNT; + break; + case _DRM_STAT_IRQ: + stats->data[i].long_name = "IRQs"; + stats->data[i].rate_name = "IRQ/s"; + SET_COUNT; + break; + case _DRM_STAT_PRIMARY: + stats->data[i].long_name = "Primary Bytes"; + stats->data[i].rate_name = "PB/s"; + SET_BYTE; + break; + case _DRM_STAT_SECONDARY: + stats->data[i].long_name = "Secondary Bytes"; + stats->data[i].rate_name = "SB/s"; + SET_BYTE; + break; + case _DRM_STAT_DMA: + stats->data[i].long_name = "DMA"; + stats->data[i].rate_name = "DMA/s"; + SET_COUNT; + break; + case _DRM_STAT_SPECIAL: + stats->data[i].long_name = "Special DMA"; + stats->data[i].rate_name = "dma/s"; + SET_COUNT; + break; + case _DRM_STAT_MISSED: + stats->data[i].long_name = "Miss"; + stats->data[i].rate_name = "Ms/s"; + SET_COUNT; + break; + case _DRM_STAT_VALUE: + stats->data[i].long_name = "Value"; + stats->data[i].rate_name = "Value"; + SET_VALUE; + break; + case _DRM_STAT_BYTE: + stats->data[i].long_name = "Bytes"; + stats->data[i].rate_name = "B/s"; + SET_BYTE; + break; + case _DRM_STAT_COUNT: + default: + stats->data[i].long_name = "Count"; + stats->data[i].rate_name = "Cnt/s"; + SET_COUNT; + break; + } + } + return 0; +} + #if defined(XFree86Server) || defined(DRM_USE_MALLOC) static void drmSIGIOHandler(int interrupt, void *closure) { @@ -1108,7 +1325,7 @@ static void drmSIGIOHandler(int interrupt, void *closure) #if 0 fprintf(stderr, "Got %s\n", buf); #endif - + for (pt = buf; *pt != ' '; ++pt); /* Find first space */ ++pt; old = strtol(pt, &pt, 0); @@ -1141,7 +1358,7 @@ int drmRemoveSIGIOHandler(int fd) drmHashEntry *entry = drmGetEntry(fd); entry->f = NULL; - + return xf86RemoveSIGIOHandler(fd); } #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h index de77ddd8b..e3702c2cf 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,16 +23,26 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Author: Rickard E. (Rik) Faith <faith@valinux.com> * * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.12 2000/09/24 13:51:32 alanh Exp $ - * + * */ #ifndef _XF86DRM_H_ #define _XF86DRM_H_ + /* Defaults, if nothing set in xf86config */ +#define DRM_DEV_UID 0 +#define DRM_DEV_GID 0 +#define DRM_DEV_DIRMODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP) +#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) + +#define DRM_DIR_NAME "/dev/dri" +#define DRM_DEV_NAME "%s/card%d" +#define DRM_PROC_NAME "/proc/dri/" /* For backware Linux compatibility */ + #define DRM_ERR_NO_DEVICE (-1001) #define DRM_ERR_NO_ACCESS (-1002) #define DRM_ERR_NOT_ROOT (-1003) @@ -58,6 +68,21 @@ typedef struct _drmVersion { char *desc; /* User-space buffer to hold desc */ } drmVersion, *drmVersionPtr; +typedef struct _drmStats { + unsigned long count; /* Number of data */ + struct { + unsigned long value; /* Value from kernel */ + const char *long_format; /* Suggested format for long_name */ + const char *long_name; /* Long name for value */ + const char *rate_format; /* Suggested format for rate_name */ + const char *rate_name; /* Short name for value per second */ + int isvalue; /* True if value (vs. counter) */ + const char *mult_names; /* Multiplier names (e.g., "KGM") */ + int mult; /* Multiplier value (e.g., 1024) */ + int verbose; /* Suggest only in verbose output */ + } data[15]; +} drmStatsT; + /* All of these enums *MUST* match with the kernel implementation -- so do *NOT* @@ -68,7 +93,8 @@ typedef enum { DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */ DRM_REGISTERS = 1, /* no caching, no core dump */ DRM_SHM = 2, /* shared, cached */ - DRM_AGP = 3 /* AGP/GART */ + DRM_AGP = 3, /* AGP/GART */ + DRM_SCATTER_GATHER = 4 /* PCI scatter/gather */ } drmMapType; typedef enum { @@ -77,7 +103,8 @@ typedef enum { DRM_LOCKED = 0x0004, /* Physical pages locked */ DRM_KERNEL = 0x0008, /* Kernel requires access */ DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */ - DRM_CONTAINS_LOCK = 0x0020 /* SHM page that contains lock */ + DRM_CONTAINS_LOCK = 0x0020, /* SHM page that contains lock */ + DRM_REMOVABLE = 0x0040 /* Removable mapping */ } drmMapFlags; typedef enum { /* These values *MUST* match drm.h */ @@ -99,7 +126,8 @@ typedef enum { /* These values *MUST* match drm.h */ typedef enum { DRM_PAGE_ALIGN = 0x01, - DRM_AGP_BUFFER = 0x02 + DRM_AGP_BUFFER = 0x02, + DRM_SG_BUFFER = 0x04 } drmBufDescFlags; typedef enum { @@ -147,7 +175,7 @@ typedef struct _drmBufMap { typedef struct _drmLock { volatile unsigned int lock; char padding[60]; - /* This is big enough for most current (and future?) architectures: + /* This is big enough for most current (and future?) architectures: DEC Alpha: 32 bytes Intel Merced: ? Intel P5/PPro/PII/PIII: 32 bytes @@ -175,14 +203,22 @@ typedef struct _drmDMAReq { int granted_count; /* Number of buffers granted at this size */ } drmDMAReq, *drmDMAReqPtr; -#if 0 - /* The kernel does this, but it doesn't - seem necessary with recent gcc's. */ -typedef struct { unsigned int a[100]; } __drm_dummy_lock_t; -#define __drm_dummy_lock(lock) (*(__volatile__ __drm_dummy_lock_t *)lock) -#else +typedef struct _drmRegion { + drmHandle handle; + unsigned int offset; + drmSize size; + drmAddress map; +} drmRegion, *drmRegionPtr; + +typedef struct _drmTextureRegion { + unsigned char next; + unsigned char prev; + unsigned char in_use; + unsigned char padding; /* Explicitly pad this out */ + unsigned int age; +} drmTextureRegion, *drmTextureRegionPtr; + #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#endif #define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */ #define DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */ @@ -227,7 +263,7 @@ typedef struct { unsigned int a[100]; } __drm_dummy_lock_t; : "r" (old), \ "r" (new)); \ } while(0) - + #elif defined(__sparc__) #define DRM_CAS(lock,old,new,__ret) \ @@ -314,7 +350,7 @@ do { register unsigned int __old __asm("o0"); \ if (flags) drmGetLock(fd,context,flags); \ else DRM_LIGHT_LOCK(fd,lock,context); \ } while(0) - + #define DRM_UNLOCK(fd,lock,context) \ do { \ DRM_CAS_RESULT(__ret); \ @@ -372,6 +408,14 @@ extern int drmGetMagic(int fd, drmMagicPtr magic); extern char *drmGetBusid(int fd); extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum); +extern int drmGetMap(int fd, int idx, drmHandle *offset, + drmSize *size, drmMapType *type, + drmMapFlags *flags, drmHandle *handle, + int *mtrr); +extern int drmGetClient(int fd, int idx, int *auth, int *pid, + int *uid, unsigned long *magic, + unsigned long *iocs); +extern int drmGetStats(int fd, drmStatsT *stats); /* General user-level programmer's API: X server (root) only */ @@ -384,7 +428,11 @@ extern int drmAddMap(int fd, drmMapType type, drmMapFlags flags, drmHandlePtr handle); -extern int drmAddBufs(int fd, int count, int size, +extern int drmRmMap(int fd, drmHandle handle); +extern int drmAddContextPrivateMapping(int fd, drmContext ctx_id, + drmHandle handle); + +extern int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, int agp_offset); extern int drmMarkBufs(int fd, double low, double high); @@ -426,12 +474,14 @@ extern int drmGetLock(int fd, drmLockFlags flags); extern int drmUnlock(int fd, drmContext context); extern int drmFinish(int fd, int context, drmLockFlags flags); +extern int drmGetContextPrivateMapping(int fd, drmContext ctx_id, + drmHandlePtr handle); /* AGP/GART support: X server (root) only */ extern int drmAgpAcquire(int fd); extern int drmAgpRelease(int fd); extern int drmAgpEnable(int fd, unsigned long mode); -extern int drmAgpAlloc(int fd, unsigned long size, +extern int drmAgpAlloc(int fd, unsigned long size, unsigned long type, unsigned long *address, unsigned long *handle); extern int drmAgpFree(int fd, unsigned long handle); @@ -450,6 +500,11 @@ extern unsigned long drmAgpMemoryAvail(int fd); extern unsigned int drmAgpVendorId(int fd); extern unsigned int drmAgpDeviceId(int fd); +/* PCI scatter/gather support: X server (root) only */ +extern int drmScatterGatherAlloc(int fd, unsigned long size, + unsigned long *handle); +extern int drmScatterGatherFree(int fd, unsigned long handle); + /* Support routines */ extern int drmError(int err, const char *label); extern void *drmMalloc(int size); |