summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c260
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c10
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h30
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c395
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c10
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c499
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h93
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);