diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers')
30 files changed, 1582 insertions, 111 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h index e5b0dc34e..dbdec3436 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h @@ -61,7 +61,8 @@ #include "GL/glxint.h" #endif -#define R128_DEBUG 0 /* Turn off debugging output */ +#define R128_DEBUG 0 /* Turn off debugging output */ +#define R128_IDLE_RETRY 32 /* Fall out of idle loops after this count */ #define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ #define R128_MMIOSIZE 0x80000 @@ -423,7 +424,7 @@ extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen); #define R128CCE_START(pScrn, info) \ do { \ - int _ret = drmR128StartCCE(info->drmFD); \ + int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_START); \ if (_ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CCE start %d\n", __FUNCTION__, _ret); \ @@ -432,7 +433,7 @@ do { \ #define R128CCE_STOP(pScrn, info) \ do { \ - int _ret = drmR128StopCCE(info->drmFD); \ + int _ret = R128CCEStop(pScrn); \ if (_ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CCE stop %d\n", __FUNCTION__, _ret); \ @@ -443,7 +444,7 @@ do { \ do { \ if (info->directRenderingEnabled \ && R128CCE_USE_RING_BUFFER(info->CCEMode)) { \ - int _ret = drmR128ResetCCE(info->drmFD); \ + int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET); \ if (_ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CCE reset %d\n", __FUNCTION__, _ret); \ @@ -457,6 +458,7 @@ extern drmBufPtr R128CCEGetBuffer(ScrnInfoPtr pScrn); extern void R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard); extern void R128CCEReleaseIndirect(ScrnInfoPtr pScrn); extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); +extern int R128CCEStop(ScrnInfoPtr pScrn); #define CCE_PACKET0( reg, n ) \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c index 6146a7a7c..035449026 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c @@ -229,13 +229,16 @@ void R128WaitForIdle(ScrnInfoPtr pScrn) void R128CCEWaitForIdle(ScrnInfoPtr pScrn) { R128InfoPtr info = R128PTR(pScrn); - int ret; + int ret, i; FLUSH_RING(); for (;;) { - /* The ioctl already has a timeout */ - ret = drmR128WaitForIdleCCE(info->drmFD); + i = 0; + do { + ret = drmCommandNone(info->drmFD, DRM_R128_CCE_IDLE); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); + if (ret && ret != -EBUSY) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: CCE idle %d\n", __FUNCTION__, ret); @@ -252,6 +255,49 @@ void R128CCEWaitForIdle(ScrnInfoPtr pScrn) R128CCE_START(pScrn, info); } } + +int R128CCEStop(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + drmR128CCEStop stop; + int ret, i; + + stop.flush = 1; + stop.idle = 1; + + ret = drmCommandWrite( info->drmFD, DRM_R128_CCE_STOP, + &stop, sizeof(drmR128CCEStop) ); + + if ( ret == 0 ) { + return 0; + } else if ( errno != EBUSY ) { + return -errno; + } + + stop.flush = 0; + + i = 0; + do { + ret = drmCommandWrite( info->drmFD, DRM_R128_CCE_STOP, + &stop, sizeof(drmR128CCEStop) ); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); + + if ( ret == 0 ) { + return 0; + } else if ( errno != EBUSY ) { + return -errno; + } + + stop.idle = 0; + + if ( drmCommandWrite( info->drmFD, DRM_R128_CCE_STOP, + &stop, sizeof(drmR128CCEStop) )) { + return -errno; + } else { + return 0; + } +} + #endif /* Setup for XAA SolidFill. */ @@ -1536,6 +1582,7 @@ void R128CCEFlushIndirect( ScrnInfoPtr pScrn, int discard ) R128InfoPtr info = R128PTR(pScrn); drmBufPtr buffer = info->indirectBuffer; int start = info->indirectStart; + drmR128Indirect indirect; if ( !buffer ) return; @@ -1543,8 +1590,13 @@ void R128CCEFlushIndirect( ScrnInfoPtr pScrn, int discard ) if ( (start == buffer->used) && !discard ) return; - drmR128FlushIndirectBuffer( info->drmFD, buffer->idx, - start, buffer->used, discard ); + indirect.idx = buffer->idx; + indirect.start = start; + indirect.end = buffer->used; + indirect.discard = discard; + + drmCommandWriteRead( info->drmFD, DRM_R128_INDIRECT, + &indirect, sizeof(drmR128Indirect)); if ( discard ) buffer = info->indirectBuffer = R128CCEGetBuffer( pScrn ); @@ -1563,6 +1615,7 @@ void R128CCEReleaseIndirect( ScrnInfoPtr pScrn ) R128InfoPtr info = R128PTR(pScrn); drmBufPtr buffer = info->indirectBuffer; int start = info->indirectStart; + drmR128Indirect indirect; info->indirectBuffer = NULL; info->indirectStart = 0; @@ -1570,8 +1623,13 @@ void R128CCEReleaseIndirect( ScrnInfoPtr pScrn ) if ( !buffer ) return; - drmR128FlushIndirectBuffer( info->drmFD, buffer->idx, - start, buffer->used, 1 ); + indirect.idx = buffer->idx; + indirect.start = start; + indirect.end = buffer->used; + indirect.discard = 1; + + drmCommandWriteRead( info->drmFD, DRM_R128_INDIRECT, + &indirect, sizeof(drmR128Indirect)); } static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h new file mode 100644 index 000000000..5d5bed8b4 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h @@ -0,0 +1,162 @@ +/* r128_common.h -- common header definitions for R128 2D/3D/DRM suite + * Created: Sun Apr 9 18:16:28 2000 by kevin@precisioninsight.com + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * 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: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h,v 3.11 2001/04/16 15:02:13 tsi Exp $ + * + */ + +#ifndef _R128_COMMON_H_ +#define _R128_COMMON_H_ + +#include "X11/Xmd.h" + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (r128_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_R128_INIT 0x00 +#define DRM_R128_CCE_START 0x01 +#define DRM_R128_CCE_STOP 0x02 +#define DRM_R128_CCE_RESET 0x03 +#define DRM_R128_CCE_IDLE 0x04 +#define DRM_R128_UNDEFINED1 0x05 +#define DRM_R128_RESET 0x06 +#define DRM_R128_SWAP 0x07 +#define DRM_R128_CLEAR 0x08 +#define DRM_R128_VERTEX 0x09 +#define DRM_R128_INDICES 0x0a +#define DRM_R128_BLIT 0x0b +#define DRM_R128_DEPTH 0x0c +#define DRM_R128_STIPPLE 0x0d +#define DRM_R128_UNDEFINED2 0x0e +#define DRM_R128_INDIRECT 0x0f +#define DRM_R128_FULLSCREEN 0x10 +#define DRM_R128_CLEAR2 0x11 + +#define DRM_R128_FRONT 0x1 +#define DRM_R128_BACK 0x2 +#define DRM_R128_DEPTH 0x4 + +typedef struct { + enum { + DRM_R128_INIT_CCE = 0x01, + DRM_R128_CLEANUP_CCE = 0x02 + } func; + unsigned long sarea_priv_offset; + int is_pci; + int cce_mode; + int cce_secure; /* FIXME: Deprecated, we should remove this */ + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + unsigned int span_offset; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drmR128Init; + +typedef struct { + int flush; + int idle; +} drmR128CCEStop; + +typedef struct { + int idx; + int start; + int end; + int discard; +} drmR128Indirect; + +typedef struct { + int idx; + int pitch; + int offset; + int format; + unsigned short x, y; + unsigned short width, height; +} drmR128Blit; + +typedef struct { + enum { + DRM_R128_WRITE_SPAN = 0x01, + DRM_R128_WRITE_PIXELS = 0x02, + DRM_R128_READ_SPAN = 0x03, + DRM_R128_READ_PIXELS = 0x04 + } func; + int n; + int *x; + int *y; + unsigned int *buffer; + unsigned char *mask; +} drmR128Depth; + +typedef struct { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drmR128Vertex; + +typedef struct { + unsigned int *mask; +} drmR128Stipple; + +typedef struct { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; +} drmR128Clear; + +typedef struct { + enum { + DRM_R128_INIT_FULLSCREEN = 0x01, + DRM_R128_CLEANUP_FULLSCREEN = 0x02 + } func; +} drmR128Fullscreen; + +#endif 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 e3f981731..3031b35f0 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -769,6 +769,9 @@ static int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen) { drmR128Init drmInfo; + memset( &drmInfo, 0, sizeof(drmR128Init) ); + + drmInfo.func = DRM_R128_INIT_CCE; drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); drmInfo.is_pci = info->IsPCI; drmInfo.cce_mode = info->CCEMode; @@ -796,7 +799,9 @@ static int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen) drmInfo.buffers_offset = info->bufHandle; drmInfo.agp_textures_offset = info->agpTexHandle; - if (drmR128InitCCE(info->drmFD, &drmInfo) < 0) return FALSE; + if (drmCommandWrite(info->drmFD, DRM_R128_INIT, + &drmInfo, sizeof(drmR128Init)) < 0) + return FALSE; return TRUE; } @@ -996,6 +1001,42 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) return FALSE; } + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(info->drmFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(info->drmFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] R128DRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + R128DRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + /* Check the r128 DRM version */ version = drmGetVersion(info->drmFD); if (version) { @@ -1130,6 +1171,7 @@ void R128DRICloseScreen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; R128InfoPtr info = R128PTR(pScrn); + drmR128Init drmInfo; /* Stop the CCE if it is still in use */ if (info->directRenderingEnabled) { @@ -1143,7 +1185,10 @@ void R128DRICloseScreen(ScreenPtr pScreen) } /* De-allocate all kernel resources */ - drmR128CleanupCCE(info->drmFD); + memset(&drmInfo, 0, sizeof(drmR128Init)); + drmInfo.func = DRM_R128_CLEANUP_CCE; + drmCommandWrite(info->drmFD, DRM_R128_INIT, + &drmInfo, sizeof(drmR128Init)); /* De-allocate all AGP resources */ if (info->agpTex) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h index 5ef9cdfee..64345d3c2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -40,7 +40,7 @@ #define _R128_DRI_ #include "xf86drm.h" -#include "xf86drmR128.h" +#include "r128_common.h" /* DRI Driver defaults */ #define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM 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 2156a4203..cb05eb68a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -277,18 +277,16 @@ static const char *drmSymbols[] = { "drmAgpUnbind", "drmAgpVendorId", "drmAvailable", + "drmCommandNone", + "drmCommandRead", + "drmCommandWrite", + "drmCommandWriteRead", "drmFreeVersion", + "drmGetLibVersion", "drmGetVersion", "drmMap", "drmMapBufs", "drmDMA", - "drmR128CleanupCCE", - "drmR128InitCCE", - "drmR128ResetCCE", - "drmR128StartCCE", - "drmR128StopCCE", - "drmR128WaitForIdleCCE", - "drmR128FlushIndirectBuffer", "drmScatterGatherAlloc", "drmScatterGatherFree", "drmUnmap", diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c index ac7459502..031026d9b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c @@ -4,7 +4,7 @@ #include "r128_reg.h" #ifdef XF86DRI -#include "xf86drmR128.h" +#include "r128_common.h" #include "r128_sarea.h" #endif @@ -509,6 +509,7 @@ R128DMA( int err=-1, i, idx, offset, hpass, passes, srcpassbytes, dstpassbytes; int sizes[MAXPASSES], list[MAXPASSES]; drmDMAReq req; + drmR128Blit blit; /* Verify conditions and bail out as early as possible */ if (!info->directRenderingEnabled) @@ -567,8 +568,17 @@ R128DMA( } } - if ((err = drmR128TextureBlit(info->drmFD, idx, offset, dstPitch, - (R128_DATATYPE_CI8 >> 16), (offset % 32), 0, w, hpass)) < 0) + blit.idx = idx; + blit.offset = offset; + blit.pitch = dstPitch; + blit.format = (R128_DATATYPE_CI8 >> 16); + blit.x = (offset % 32); + blit.y = 0; + blit.width = w; + blit.height = hpass; + + if ((err = drmCommandWrite(info->drmFD, DRM_R128_BLIT, + &blit, sizeof(drmR128Blit))) < 0) break; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h index cce71271d..08b5ee810 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -66,9 +66,10 @@ #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 +#define RADEON_DEBUG 0 /* Turn off debugging output */ +#define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */ +#define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define RADEON_MMIOSIZE 0x80000 #define RADEON_VBIOS_SIZE 0x00010000 @@ -498,11 +499,12 @@ extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen); extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn); extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn); extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn); +extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info); #define RADEONCP_START(pScrn, info) \ do { \ - int _ret = drmRadeonStartCP(info->drmFD); \ + int _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_START); \ if (_ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CP start %d\n", __FUNCTION__, _ret); \ @@ -511,7 +513,7 @@ do { \ #define RADEONCP_STOP(pScrn, info) \ do { \ - int _ret = drmRadeonStopCP(info->drmFD); \ + int _ret = RADEONCPStop(pScrn, info); \ if (_ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CP stop %d\n", __FUNCTION__, _ret); \ @@ -522,7 +524,7 @@ do { \ #define RADEONCP_RESET(pScrn, info) \ do { \ if (RADEONCP_USE_RING_BUFFER(info->CPMode)) { \ - int _ret = drmRadeonResetCP(info->drmFD); \ + int _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_RESET); \ if (_ret) { \ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ "%s: CP reset %d\n", __FUNCTION__, _ret); \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c index a4b844d37..0b48955e7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -186,14 +186,16 @@ void RADEONWaitForIdle(ScrnInfoPtr pScrn) static void RADEONCPWaitForIdle(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - int ret; - int i = 0; + int ret, i; FLUSH_RING(); for (;;) { do { - ret = drmRadeonWaitForIdleCP(info->drmFD); + i = 0; + do { + ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); + } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); if (ret && ret != -EBUSY) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: CP idle %d\n", __FUNCTION__, ret); @@ -212,6 +214,47 @@ static void RADEONCPWaitForIdle(ScrnInfoPtr pScrn) RADEONCP_START(pScrn, info); } } + +int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info) +{ + drmRadeonCPStop stop; + int ret, i; + + stop.flush = 1; + stop.idle = 1; + + ret = drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP, &stop, + sizeof(drmRadeonCPStop)); + + if ( ret == 0 ) { + return 0; + } else if ( errno != EBUSY ) { + return -errno; + } + + stop.flush = 0; + + i = 0; + do { + ret = drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP, &stop, + sizeof(drmRadeonCPStop)); + } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); + + if ( ret == 0 ) { + return 0; + } else if ( errno != EBUSY ) { + return -errno; + } + + stop.idle = 0; + + if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP, + &stop, sizeof(drmRadeonCPStop))) { + return -errno; + } else { + return 0; + } +} #endif /* Flush all dirty data in the Pixel Cache to memory. */ @@ -1509,6 +1552,7 @@ void RADEONCPFlushIndirect( ScrnInfoPtr pScrn ) RADEONInfoPtr info = RADEONPTR(pScrn); drmBufPtr buffer = info->indirectBuffer; int start = info->indirectStart; + drmRadeonIndirect indirect; int discard; if ( !buffer ) @@ -1519,8 +1563,13 @@ void RADEONCPFlushIndirect( ScrnInfoPtr pScrn ) discard = ( buffer->used + RING_THRESHOLD > buffer->total ); - drmRadeonFlushIndirectBuffer( info->drmFD, buffer->idx, - start, buffer->used, discard ); + indirect.idx = buffer->idx; + indirect.start = start; + indirect.end = buffer->used; + indirect.discard = discard; + + drmCommandWriteRead( info->drmFD, DRM_RADEON_INDIRECT, + &indirect, sizeof(drmRadeonIndirect) ); if ( discard ) { info->indirectBuffer = RADEONCPGetBuffer( pScrn ); @@ -1537,6 +1586,7 @@ void RADEONCPReleaseIndirect( ScrnInfoPtr pScrn ) RADEONInfoPtr info = RADEONPTR(pScrn); drmBufPtr buffer = info->indirectBuffer; int start = info->indirectStart; + drmRadeonIndirect indirect; info->indirectBuffer = NULL; info->indirectStart = 0; @@ -1544,8 +1594,13 @@ void RADEONCPReleaseIndirect( ScrnInfoPtr pScrn ) if ( !buffer ) return; - drmRadeonFlushIndirectBuffer( info->drmFD, buffer->idx, - start, buffer->used, 1 ); + indirect.idx = buffer->idx; + indirect.start = start; + indirect.end = buffer->used; + indirect.discard = 1; + + drmCommandWriteRead( info->drmFD, DRM_RADEON_INDIRECT, + &indirect, sizeof(drmRadeonIndirect) ); } static void RADEONCPAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h new file mode 100644 index 000000000..89f92cc8f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h @@ -0,0 +1,253 @@ +/* radeon_common.h -- common header definitions for Radeon 2D/3D/DRM suite + * + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * 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: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Keith Whitwell <keith_whitwell@yahoo.com> + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h,v 1.6 2001/04/16 15:02:13 tsi Exp $ + * + */ + +#ifndef _RADEON_COMMON_H_ +#define _RADEON_COMMON_H_ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (radeon_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_RADEON_CP_INIT 0x00 +#define DRM_RADEON_CP_START 0x01 +#define DRM_RADEON_CP_STOP 0x02 +#define DRM_RADEON_CP_RESET 0x03 +#define DRM_RADEON_CP_IDLE 0x04 +#define DRM_RADEON_RESET 0x05 +#define DRM_RADEON_FULLSCREEN 0x06 +#define DRM_RADEON_SWAP 0x07 +#define DRM_RADEON_CLEAR 0x08 +#define DRM_RADEON_VERTEX 0x09 +#define DRM_RADEON_INDICES 0x0a +#define DRM_RADEON_STIPPLE 0x0c +#define DRM_RADEON_INDIRECT 0x0d +#define DRM_RADEON_TEXTURE 0x0e +#define DRM_RADEON_VERTEX2 0x0f +#define DRM_RADEON_CMDBUF 0x10 +#define DRM_RADEON_GETPARAM 0x11 +#define DRM_RADEON_MAX_DRM_COMMAND_INDEX 0x39 + + +#define RADEON_FRONT 0x1 +#define RADEON_BACK 0x2 +#define RADEON_DEPTH 0x4 +#define RADEON_STENCIL 0x8 + +#define RADEON_CLEAR_X1 0 +#define RADEON_CLEAR_Y1 1 +#define RADEON_CLEAR_X2 2 +#define RADEON_CLEAR_Y2 3 +#define RADEON_CLEAR_DEPTH 4 + + +typedef struct { + enum { + DRM_RADEON_INIT_CP = 0x01, + DRM_RADEON_CLEANUP_CP = 0x02 + } func; + unsigned long sarea_priv_offset; + int is_pci; + int cp_mode; + int agp_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drmRadeonInit; + +typedef struct { + int flush; + int idle; +} drmRadeonCPStop; + +typedef struct { + int idx; + int start; + int end; + int discard; +} drmRadeonIndirect; + +typedef union drmRadeonClearR { + float f[5]; + unsigned int ui[5]; +} drmRadeonClearRect; + +typedef struct drmRadeonClearT { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; /* misnamed field: should be stencil */ + drmRadeonClearRect *depth_boxes; +} drmRadeonClearType; + +typedef struct drmRadeonFullscreenT { + enum { + RADEON_INIT_FULLSCREEN = 0x01, + RADEON_CLEANUP_FULLSCREEN = 0x02 + } func; +} drmRadeonFullscreenType; + +typedef struct { + unsigned int *mask; +} drmRadeonStipple; + +typedef struct { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + const void *data; +} drmRadeonTexImage; + +typedef struct { + int offset; + int pitch; + int format; + int width; /* Texture image coordinates */ + int height; + drmRadeonTexImage *image; +} drmRadeonTexture; + + +#define RADEON_MAX_TEXTURE_UNITS 3 + +/* Layout matches drm_radeon_state_t in linux drm_radeon.h. + */ +typedef struct { + struct { + unsigned int pp_misc; /* 0x1c14 */ + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + unsigned int pp_cntl; /* 0x1c38 */ + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + } context; + struct { + unsigned int se_cntl; + } setup1; + struct { + unsigned int se_coord_fmt; /* 0x1c50 */ + } vertex; + struct { + unsigned int re_line_pattern; /* 0x1cd0 */ + unsigned int re_line_state; + unsigned int se_line_width; /* 0x1db8 */ + } line; + struct { + unsigned int pp_lum_matrix; /* 0x1d00 */ + unsigned int pp_rot_matrix_0; /* 0x1d58 */ + unsigned int pp_rot_matrix_1; + } bumpmap; + struct { + unsigned int rb3d_stencilrefmask; /* 0x1d7c */ + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + } mask; + struct { + unsigned int se_vport_xscale; /* 0x1d98 */ + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; + } viewport; + struct { + unsigned int se_cntl_status; /* 0x2140 */ + } setup2; + struct { + unsigned int re_top_left; /*ignored*/ /* 0x26c0 */ + unsigned int re_misc; + } misc; + struct { + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + unsigned int pp_border_color; + } texture[RADEON_MAX_TEXTURE_UNITS]; + struct { + unsigned int se_zbias_factor; + unsigned int se_zbias_constant; + } zbias; + unsigned int dirty; +} drmRadeonState; + +typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim:8; + unsigned int stateidx:8; + unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ + unsigned int vc_format; +} drmRadeonPrim; + +typedef struct { + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ + int nr_states; + drmRadeonState *state; + int nr_prims; + drmRadeonPrim *prim; +} drmRadeonVertex2; + +#define RADEON_MAX_STATES 16 +#define RADEON_MAX_PRIMS 64 + +#endif 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 769d45e2e..235acafdd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -491,6 +491,8 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) int nbox; unsigned int color, depth, stencil; unsigned int color_mask, depth_mask, flags; + drmRadeonClearType clear; + drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; /* FIXME: This should be based on the __GLXvisualConfig info */ color = 0; @@ -521,25 +523,36 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + clear.flags = flags; + clear.clear_color = color; + clear.clear_depth = depth; + clear.color_mask = color_mask; + clear.depth_mask = depth_mask; + clear.depth_boxes = depth_boxes; + pbox = REGION_RECTS(prgn); nbox = REGION_NUM_RECTS(prgn); for (; nbox; nbox--, pbox++) { int ret; - /* drmRadeonClear uses the clip rects to draw instead of the + /* DRM_RADEON_CLEAR uses the clip rects to draw instead of the rect passed to it; however, it uses the rect for the depth clears */ pSAREAPriv->boxes[0].x1 = pbox->x1; - pSAREAPriv->boxes[0].x2 = pbox->x2; pSAREAPriv->boxes[0].y1 = pbox->y1; + pSAREAPriv->boxes[0].x2 = pbox->x2; pSAREAPriv->boxes[0].y2 = pbox->y2; pSAREAPriv->nbox = 1; - ret = drmRadeonClear(info->drmFD, - flags, - color, depth, color_mask, depth_mask, - pSAREAPriv->boxes, pSAREAPriv->nbox); + depth_boxes[0].f[RADEON_CLEAR_X1] = (float)pbox->x1; + depth_boxes[0].f[RADEON_CLEAR_Y1] = (float)pbox->y1; + depth_boxes[0].f[RADEON_CLEAR_X2] = (float)pbox->x2; + depth_boxes[0].f[RADEON_CLEAR_Y2] = (float)pbox->y2; + depth_boxes[0].f[RADEON_CLEAR_DEPTH] = (float)depth; + + ret = drmCommandWrite(info->drmFD, DRM_RADEON_CLEAR, + &clear, sizeof(drmRadeonClearType)); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] DRIInitBuffers timed out, resetting engine...\n"); @@ -1007,6 +1020,9 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) int cpp = info->CurrentLayout.pixel_bytes; drmRadeonInit drmInfo; + memset(&drmInfo, 0, sizeof(drmRadeonInit)); + + drmInfo.func = DRM_RADEON_INIT_CP; drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); drmInfo.is_pci = info->IsPCI; drmInfo.cp_mode = info->CPMode; @@ -1031,9 +1047,11 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) drmInfo.buffers_offset = info->bufHandle; drmInfo.agp_textures_offset = info->agpTexHandle; - if (drmRadeonInitCP(info->drmFD, &drmInfo) < 0) return FALSE; + if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT, + &drmInfo, sizeof(drmRadeonInit)) < 0) + return FALSE; - /* drmRadeonInitCP does an engine reset, which resets some engine + /* DRM_RADEON_CP_INIT does an engine reset, which resets some engine registers back to their default values, so we need to restore those engine register here. */ RADEONEngineRestore(pScrn); @@ -1412,6 +1430,42 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) return FALSE; } + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(info->drmFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(info->drmFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] RADEONDRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + RADEONDRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + /* Check the radeon DRM version */ version = drmGetVersion(info->drmFD); if (version) { @@ -1572,6 +1626,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + drmRadeonInit drmInfo; /* Stop the CP */ if (info->directRenderingEnabled) { @@ -1585,7 +1640,10 @@ void RADEONDRICloseScreen(ScreenPtr pScreen) } /* De-allocate all kernel resources */ - drmRadeonCleanupCP(info->drmFD); + memset(&drmInfo, 0, sizeof(drmRadeonInit)); + drmInfo.func = DRM_RADEON_CLEANUP_CP; + drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT, + &drmInfo, sizeof(drmRadeonInit)); /* De-allocate all AGP resources */ if (info->agpTex) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h index 553d54526..4a4f53724 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -38,7 +38,7 @@ #define _RADEON_DRI_ #include "xf86drm.h" -#include "xf86drmRadeon.h" +#include "radeon_common.h" /* DRI Driver defaults */ #define RADEON_DEFAULT_CP_PIO_MODE RADEON_CSQ_PRIPIO_INDPIO diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h index 351713e56..530fd4abb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h @@ -39,7 +39,7 @@ #include "GL/glxint.h" #include "xf86drm.h" -#include "xf86drmRadeon.h" +#include "radeon_common.h" #define RADEON_MAX_DRAWABLES 256 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 cb46661a3..f64ba654a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -260,19 +260,16 @@ static const char *drmSymbols[] = { "drmAgpRelease", "drmAgpUnbind", "drmAgpVendorId", + "drmCommandNone", + "drmCommandRead", + "drmCommandWrite", + "drmCommandWriteRead", "drmDMA", "drmFreeVersion", + "drmGetLibVersion", "drmGetVersion", "drmMap", "drmMapBufs", - "drmRadeonCleanupCP", - "drmRadeonClear", - "drmRadeonFlushIndirectBuffer", - "drmRadeonInitCP", - "drmRadeonResetCP", - "drmRadeonStartCP", - "drmRadeonStopCP", - "drmRadeonWaitForIdleCP", "drmScatterGatherFree" "drmUnmap", "drmUnmapBufs", diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_common.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_common.h new file mode 100644 index 000000000..71f6f6d48 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_common.h @@ -0,0 +1,63 @@ +/* glint_common.h -- common header definitions for Gamma 2D/3D/DRM suite + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * 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. + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86$ + * + */ + +#ifndef _GLINT_COMMON_H_ +#define _GLINT_COMMON_H_ + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (gamma_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_GAMMA_INIT 0x00 +#define DRM_GAMMA_COPY 0x01 + +typedef struct { + enum { + GAMMA_INIT_DMA = 0x01, + GAMMA_CLEANUP_DMA = 0x02 + } func; + int sarea_priv_offset; + int pcimode; + unsigned int mmio0; + unsigned int mmio1; + unsigned int mmio2; + unsigned int mmio3; + unsigned int buffers_offset; +} drmGAMMAInit; + +extern int drmGAMMAInitDMA( int fd, drmGAMMAInit *info ); +extern int drmGAMMACleanupDMA( int fd ); + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c index 1b16da6ba..e6a25cfd1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c @@ -406,6 +406,7 @@ static Bool GLINTDRIKernelInit( ScreenPtr pScreen ) memset( &init, 0, sizeof(drmGAMMAInit) ); + init.func = GAMMA_INIT_DMA; init.sarea_priv_offset = sizeof(XF86DRISAREARec); init.mmio0 = pGlintDRI->registers0.handle; @@ -420,7 +421,8 @@ static Bool GLINTDRIKernelInit( ScreenPtr pScreen ) init.pcimode = 1; } - ret = drmGAMMAInitDMA( pGlint->drmSubFD, &init ); + ret = drmCommandWrite( pGlint->drmSubFD, DRM_GAMMA_INIT, + &init, sizeof(drmGAMMAInit) ); if ( ret < 0 ) { xf86DrvMsg( pScrn->scrnIndex, X_ERROR, @@ -553,9 +555,48 @@ GLINTDRIScreenInit(ScreenPtr pScreen) return FALSE; } - /* Check the GLINT DRM version */ + /* Check the DRM versioning */ { - drmVersionPtr version = drmGetVersion(pGlint->drmSubFD); + drmVersionPtr version; + + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(pGlint->drmSubFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(pGlint->drmSubFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] GLINTDRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + GLINTDRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Check the GLINT DRM version */ + version = drmGetVersion(pGlint->drmSubFD); if (version) { if (version->version_major != 2 || version->version_minor < 0) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h index 5558110e6..8285f17fb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h @@ -36,8 +36,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _GLINT_DRI_H_ #define _GLINT_DRI_H_ -#include <xf86drm.h> -#include <xf86drmGamma.h> +#include "xf86drm.h" +#include "glint_common.h" typedef struct { unsigned int GDeltaMode; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c index 3377d3a0a..4633d2df6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c @@ -341,9 +341,11 @@ const char *GLINTint10Symbols[] = { static const char *drmSymbols[] = { "drmAddBufs", "drmAddMap", + "drmCommandWrite", "drmCtlInstHandler", "drmFreeVersion", "drmGetInterruptFromBusID", + "drmGetLibVersion", "drmGetVersion", "drmMapBufs", "drmUnmapBufs", diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h new file mode 100644 index 000000000..b96104cdf --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h @@ -0,0 +1,188 @@ +/* i810_common.h -- common header definitions for I810 2D/3D/DRM suite + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * 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. + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86$ + * + */ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (i810_drm.h) + */ + +#ifndef _I810_COMMON_H_ +#define _I810_COMMON_H_ + +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ +#define I810_USE_BATCH 1 + +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) +#define I810_DMA_BUF_NR 256 + +#define I810_NR_SAREA_CLIPRECTS 8 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ +#define I810_NR_TEX_REGIONS 64 +#define I810_LOG_MIN_TEX_REGION_SIZE 16 + +/* Destbuffer state + * - backbuffer linear offset and pitch -- invarient in the current dri + * - zbuffer linear offset and pitch -- also invarient + * - drawing origin in back and depth buffers. + * + * Keep the depth/back buffer state here to acommodate private buffers + * in the future. + */ +#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */ +#define I810_DESTREG_DI1 1 +#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */ +#define I810_DESTREG_DV1 3 +#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */ +#define I810_DESTREG_DR1 5 +#define I810_DESTREG_DR2 6 +#define I810_DESTREG_DR3 7 +#define I810_DESTREG_DR4 8 +#define I810_DEST_SETUP_SIZE 10 + +/* Context state + */ +#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */ +#define I810_CTXREG_CF1 1 +#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */ +#define I810_CTXREG_ST1 3 +#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */ +#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */ +#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */ +#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */ +#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */ +#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */ +#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */ +#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */ +#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */ +#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */ +#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */ +#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */ +#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */ +#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */ +#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */ +#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */ +#define I810_CTX_SETUP_SIZE 20 + +/* Texture state (per tex unit) + */ +#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */ +#define I810_TEXREG_MI1 1 +#define I810_TEXREG_MI2 2 +#define I810_TEXREG_MI3 3 +#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */ +#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */ +#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */ +#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */ +#define I810_TEX_SETUP_SIZE 8 + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I810_INIT 0x00 +#define DRM_I810_VERTEX 0x01 +#define DRM_I810_CLEAR 0x02 +#define DRM_I810_FLUSH 0x03 +#define DRM_I810_GETAGE 0x04 +#define DRM_I810_GETBUF 0x05 +#define DRM_I810_SWAP 0x06 +#define DRM_I810_COPY 0x07 +#define DRM_I810_DOCOPY 0x08 +#define DRM_I810_OV0INFO 0x09 +#define DRM_I810_FSTATUS 0x0a +#define DRM_I810_OV0FLIP 0x0b +#define DRM_I810_MC 0x0c +#define DRM_I810_RSTATUS 0x0d + +#endif + +typedef struct { + enum { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02 + } func; + unsigned int mmio_offset; + unsigned int buffers_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int overlay_offset; + unsigned int overlay_physical; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; +} drmI810Init; + +typedef struct { + void *virtual; + int request_idx; + int request_size; + int granted; +} drmI810DMA; + +/* Flags for clear ioctl + */ +#define I810_FRONT 0x1 +#define I810_BACK 0x2 +#define I810_DEPTH 0x4 + +typedef struct { + int clear_color; + int clear_depth; + int flags; +} drmI810Clear; + +typedef struct { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int discard; /* client is finished with the buffer? */ +} drmI810Vertex; + +/* Flags for vertex ioctl + */ +#define PR_TRIANGLES (0x0<<18) +#define PR_TRISTRIP_0 (0x1<<18) +#define PR_TRISTRIP_1 (0x2<<18) +#define PR_TRIFAN (0x3<<18) +#define PR_POLYGON (0x4<<18) +#define PR_LINES (0x5<<18) +#define PR_LINESTRIP (0x6<<18) +#define PR_RECTS (0x7<<18) +#define PR_MASK (0x7<<18) + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c index 297c2e4ed..43d6c924c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c @@ -56,12 +56,18 @@ static int i810_pitch_flags[] = { Bool I810CleanupDma(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); - Bool ret_val; + drmI810Init info; + + memset(&info, 0, sizeof(drmI810Init)); + info.func = I810_CLEANUP_DMA; - ret_val = drmI810CleanupDma(pI810->drmSubFD); - if (ret_val == FALSE) + if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, + &info, sizeof(drmI810Init))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] I810 Dma Cleanup Failed\n"); - return ret_val; + return FALSE; + } + + return TRUE; } Bool I810InitDma(ScrnInfoPtr pScrn) @@ -70,14 +76,17 @@ Bool I810InitDma(ScrnInfoPtr pScrn) I810RingBuffer *ring = &(pI810->LpRing); I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; drmI810Init info; - Bool ret_val; - info.start = ring->mem.Start; - info.end = ring->mem.End; - info.size = ring->mem.Size; + memset(&info, 0, sizeof(drmI810Init)); + + info.func = I810_INIT_DMA; + + info.ring_start = ring->mem.Start; + info.ring_end = ring->mem.End; + info.ring_size = ring->mem.Size; info.mmio_offset = (unsigned int)pI810DRI->regs; info.buffers_offset = (unsigned int)pI810->buffer_map; - info.sarea_off = sizeof(XF86DRISAREARec); + info.sarea_priv_offset = sizeof(XF86DRISAREARec); info.front_offset = 0; info.back_offset = pI810->BackBuffer.Start; @@ -89,12 +98,14 @@ Bool I810InitDma(ScrnInfoPtr pScrn) info.pitch = pI810->auxPitch; info.pitch_bits = pI810->auxPitchBits; - ret_val = drmI810InitDma(pI810->drmSubFD, &info); - if(ret_val == FALSE) { + if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, + &info, sizeof(drmI810Init))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] I810 Dma Initialization failed.\n"); + return FALSE; } - return ret_val; + + return TRUE; } static Bool @@ -334,9 +345,48 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) return FALSE; } - /* Check the i810 DRM version */ + /* Check the DRM versioning */ { - drmVersionPtr version = drmGetVersion(pI810->drmSubFD); + drmVersionPtr version; + + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(pI810->drmSubFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(pI810->drmSubFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] I810DRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + I810DRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Check the i810 DRM version */ + version = drmGetVersion(pI810->drmSubFD); if (version) { if (version->version_major != 1 || version->version_minor < 2) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h index 96a680b85..f52f91562 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h @@ -3,8 +3,8 @@ #ifndef _I810_DRI_ #define _I810_DRI_ -#include <xf86drm.h> -#include <xf86drmI810.h> +#include "xf86drm.h" +#include "i810_common.h" #define I810_MAX_DRAWABLES 256 @@ -57,6 +57,14 @@ typedef struct { /* WARNING: Do not change the SAREA structure without changing the kernel * as well */ +#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ +#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ +#define I810_UPLOAD_CTX 0x4 +#define I810_UPLOAD_BUFFERS 0x8 +#define I810_UPLOAD_TEX0 0x10 +#define I810_UPLOAD_TEX1 0x20 +#define I810_UPLOAD_CLIPRECTS 0x40 + typedef struct { unsigned char next, prev; /* indices to form a circular LRU */ unsigned char in_use; /* owned by a client, or free? */ @@ -64,6 +72,11 @@ typedef struct { } I810TexRegionRec, *I810TexRegionPtr; typedef struct { + unsigned int ContextState[I810_CTX_SETUP_SIZE]; + unsigned int BufferState[I810_DEST_SETUP_SIZE]; + unsigned int TexState[2][I810_TEX_SETUP_SIZE]; + unsigned int dirty; + unsigned int nbox; XF86DRIClipRectRec boxes[I810_NR_SAREA_CLIPRECTS]; @@ -91,6 +104,9 @@ typedef struct { int last_quiescent; /* */ int ctxOwner; /* last context to upload state */ + + int vertex_prim; + } I810SAREARec, *I810SAREAPtr; typedef struct { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c index 5bf7976e8..0f08b4c96 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c @@ -205,16 +205,17 @@ static const char *drmSymbols[] = { "drmAgpRelease", "drmAvailable", "drmAuthMagic", + "drmCommandNone", + "drmCommandRead", + "drmCommandWrite", + "drmCommandWriteRead", "drmCreateContext", "drmCtlInstHandler", "drmDestroyContext", "drmFreeVersion", "drmGetInterruptFromBusID", + "drmGetLibVersion", "drmGetVersion", - "drmI810CleanupDma", - "drmI810InitDma", - "drmI830CleanupDma", - "drmI830InitDma", NULL }; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h new file mode 100644 index 000000000..56b2c449e --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h @@ -0,0 +1,207 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR 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. + + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmI830.h,v 1.2 2001/10/04 18:32:29 alanh Exp $ */ + +/* Author: Jeff Hartmann <jhartmann@valinux.com> + + Converted to common header format: + Jens Owen <jens@tungstengraphics.com> + */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +#ifndef _I830_DEFINES_ +#define _I830_DEFINES_ + +#define I830_DMA_BUF_ORDER 12 +#define I830_DMA_BUF_SZ (1<<I830_DMA_BUF_ORDER) +#define I830_DMA_BUF_NR 256 +#define I830_NR_SAREA_CLIPRECTS 8 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ +#define I830_NR_TEX_REGIONS 64 +#define I830_LOG_MIN_TEX_REGION_SIZE 16 + +/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ +#if !defined(I830_ENABLE_4_TEXTURES) +#define I830_TEXTURE_COUNT 2 +#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ +#else /* defined(I830_ENABLE_4_TEXTURES) */ +#define I830_TEXTURE_COUNT 4 +#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */ +#endif /* I830_ENABLE_4_TEXTURES */ + +#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ + +#define I830_UPLOAD_CTX 0x1 +#define I830_UPLOAD_BUFFERS 0x2 +#define I830_UPLOAD_CLIPRECTS 0x4 +#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */ +#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */ +#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */ +#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */ +#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */ +#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */ +#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */ +#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */ +#define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2)) +#define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2)) +#define I830_UPLOAD_TEXIMAGE_MASK 0xff00 +#define I830_UPLOAD_TEX0 0x10000 +#define I830_UPLOAD_TEX1 0x20000 +#define I830_UPLOAD_TEX2 0x40000 +#define I830_UPLOAD_TEX3 0x80000 +#define I830_UPLOAD_TEX_N(n) (0x10000 << (n)) +#define I830_UPLOAD_TEX_MASK 0xf0000 +#define I830_UPLOAD_TEXBLEND0 0x100000 +#define I830_UPLOAD_TEXBLEND1 0x200000 +#define I830_UPLOAD_TEXBLEND2 0x400000 +#define I830_UPLOAD_TEXBLEND3 0x800000 +#define I830_UPLOAD_TEXBLEND_N(n) (0x100000 << (n)) +#define I830_UPLOAD_TEXBLEND_MASK 0xf00000 +#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) +#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 + +/* Indices into buf.Setup where various bits of state are mirrored per + * context and per buffer. These can be fired at the card as a unit, + * or in a piecewise fashion as required. + */ + +/* Destbuffer state + * - backbuffer linear offset and pitch -- invarient in the current dri + * - zbuffer linear offset and pitch -- also invarient + * - drawing origin in back and depth buffers. + * + * Keep the depth/back buffer state here to acommodate private buffers + * in the future. + */ + +#define I830_DESTREG_CBUFADDR 0 +/* Invarient */ +#define I830_DESTREG_DBUFADDR 1 +#define I830_DESTREG_DV0 2 +#define I830_DESTREG_DV1 3 +#define I830_DESTREG_SENABLE 4 +#define I830_DESTREG_SR0 5 +#define I830_DESTREG_SR1 6 +#define I830_DESTREG_SR2 7 +#define I830_DESTREG_DR0 8 +#define I830_DESTREG_DR1 9 +#define I830_DESTREG_DR2 10 +#define I830_DESTREG_DR3 11 +#define I830_DESTREG_DR4 12 +#define I830_DEST_SETUP_SIZE 13 + +/* Context state + */ +#define I830_CTXREG_STATE1 0 +#define I830_CTXREG_STATE2 1 +#define I830_CTXREG_STATE3 2 +#define I830_CTXREG_STATE4 3 +#define I830_CTXREG_STATE5 4 +#define I830_CTXREG_IALPHAB 5 +#define I830_CTXREG_STENCILTST 6 +#define I830_CTXREG_ENABLES_1 7 +#define I830_CTXREG_ENABLES_2 8 +#define I830_CTXREG_AA 9 +#define I830_CTXREG_FOGCOLOR 10 +#define I830_CTXREG_BLENDCOLR0 11 +#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */ +#define I830_CTXREG_VF 13 +#define I830_CTXREG_VF2 14 +#define I830_CTXREG_MCSB0 15 +#define I830_CTXREG_MCSB1 16 +#define I830_CTX_SETUP_SIZE 17 + +/* Texture state (per tex unit) + */ + +#define I830_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (6 dwords) */ +#define I830_TEXREG_MI1 1 +#define I830_TEXREG_MI2 2 +#define I830_TEXREG_MI3 3 +#define I830_TEXREG_MI4 4 +#define I830_TEXREG_MI5 5 +#define I830_TEXREG_MF 6 /* GFX_OP_MAP_FILTER */ +#define I830_TEXREG_MLC 7 /* GFX_OP_MAP_LOD_CTL */ +#define I830_TEXREG_MLL 8 /* GFX_OP_MAP_LOD_LIMITS */ +#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ +#define I830_TEX_SETUP_SIZE 10 + + +#define I830_FRONT 0x1 +#define I830_BACK 0x2 +#define I830_DEPTH 0x4 + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_VERTEX 0x01 +#define DRM_I830_CLEAR 0x02 +#define DRM_I830_FLUSH 0x03 +#define DRM_I830_GETAGE 0x04 +#define DRM_I830_GETBUF 0x05 +#define DRM_I830_SWAP 0x06 +#define DRM_I830_COPY 0x07 +#define DRM_I830_DOCOPY 0x08 + +#endif /* _I830_DEFINES_ */ + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02 + } func; + unsigned int mmio_offset; + unsigned int buffers_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; +} drmI830Init; + +#endif /* _I830_DRM_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c index b970bffa0..c61643225 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c @@ -80,12 +80,18 @@ static int i830_pitches[] = { Bool I830CleanupDma(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); - Bool ret_val; - - ret_val = drmI830CleanupDma(pI810->drmSubFD); - if (ret_val == FALSE) + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_CLEANUP_DMA; + + if (drmCommandWrite(pI810->drmSubFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Dma Cleanup Failed\n"); - return ret_val; + return FALSE; + } + + return TRUE; } Bool I830InitDma(ScrnInfoPtr pScrn) @@ -94,16 +100,18 @@ Bool I830InitDma(ScrnInfoPtr pScrn) I810RingBuffer *ring = &(pI810->LpRing); I830DRIPtr pI830DRI=(I830DRIPtr)pI810->pDRIInfo->devPrivate; drmI830Init info; - Bool ret_val; - info.start = ring->mem.Start; - info.end = ring->mem.End; - info.size = ring->mem.Size; + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_INIT_DMA; + + info.ring_start = ring->mem.Start; + info.ring_end = ring->mem.End; + info.ring_size = ring->mem.Size; info.mmio_offset = (unsigned int)pI830DRI->regs; info.buffers_offset = (unsigned int)pI810->buffer_map; - info.sarea_off = sizeof(XF86DRISAREARec); + info.sarea_priv_offset = sizeof(XF86DRISAREARec); info.front_offset = 0; info.back_offset = pI810->BackBuffer.Start; @@ -112,11 +120,17 @@ Bool I830InitDma(ScrnInfoPtr pScrn) info.h = pScrn->virtualY; info.pitch = pI810->auxPitch; info.pitch_bits = pI810->auxPitchBits; + info.back_pitch = pI810->auxPitch; + info.depth_pitch = pI810->auxPitch; info.cpp = pI810->cpp; - ret_val = drmI830InitDma(pI810->drmSubFD, &info); - if(ret_val == FALSE) ErrorF("i830 Dma Initialization Failed\n"); - return ret_val; + if (drmCommandWrite(pI810->drmSubFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Dma Initialization Failed\n"); + return FALSE; + } + + return TRUE; } static Bool @@ -445,9 +459,48 @@ Bool I830DRIScreenInit(ScreenPtr pScreen) return FALSE; } - /* Check the i830 DRM version */ + /* Check the DRM versioning */ { - drmVersionPtr version = drmGetVersion(pI810->drmSubFD); + drmVersionPtr version; + + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(pI810->drmSubFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(pI810->drmSubFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] I830DRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + I830DRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Check the i830 DRM version */ + version = drmGetVersion(pI810->drmSubFD); if (version) { if (version->version_major != 1 || version->version_minor < 2) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h index 6c99080af..ac6302681 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h @@ -3,8 +3,8 @@ #ifndef _I830_DRI_H #define _I830_DRI_H -#include <xf86drm.h> -#include <xf86drmI830.h> +#include "xf86drm.h" +#include "i830_common.h" #define I830_MAX_DRAWABLES 256 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h new file mode 100644 index 000000000..6283d979c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h @@ -0,0 +1,141 @@ +/* mga_common.h -- common header definitions for MGA 2D/3D/DRM suite + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * 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. + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h,v 3.6 2001/04/16 15:02:13 tsi Exp $ + * + */ + +#ifndef _MGA_COMMON_H_ +#define _MGA_COMMON_H_ + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (mga_drm.h) + */ + +#define DRM_MGA_IDLE_RETRY 2048 +#define DRM_MGA_NR_TEX_HEAPS 2 + +typedef struct { + int installed; + unsigned long phys_addr; + int size; +} drmMGAWarpIndex; + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_MGA_INIT 0x00 +#define DRM_MGA_FLUSH 0x01 +#define DRM_MGA_RESET 0x02 +#define DRM_MGA_SWAP 0x03 +#define DRM_MGA_CLEAR 0x04 +#define DRM_MGA_VERTEX 0x05 +#define DRM_MGA_INDICES 0x06 +#define DRM_MGA_ILOAD 0x07 +#define DRM_MGA_BLIT 0x08 + +typedef struct { + enum { + MGA_INIT_DMA = 0x01, + MGA_CLEANUP_DMA = 0x02 + } func; + + unsigned long sarea_priv_offset; + + int chipset; + int sgram; + + unsigned int maccess; + + unsigned int fb_cpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + + unsigned int depth_cpp; + unsigned int depth_offset, depth_pitch; + + unsigned int texture_offset[DRM_MGA_NR_TEX_HEAPS]; + unsigned int texture_size[DRM_MGA_NR_TEX_HEAPS]; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long status_offset; + unsigned long warp_offset; + unsigned long primary_offset; + unsigned long buffers_offset; +} drmMGAInit; + +typedef enum { + DRM_MGA_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */ + DRM_MGA_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */ + DRM_MGA_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */ + DRM_MGA_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */ + /* These *HALT* flags aren't supported yet + -- they will be used to support the + full-screen DGA-like mode. */ + DRM_MGA_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */ + DRM_MGA_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */ +} drmMGALockFlags; + +typedef struct { + int context; + drmMGALockFlags flags; +} drmMGALock; + +typedef struct { + int idx; + unsigned int dstorg; + unsigned int length; +} drmMGAIload; + +typedef struct { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; +} drmMGAClearRec; + +typedef struct { + int idx; /* buffer to queue */ + int used; /* bytes in use */ + int discard; /* client finished with buffer? */ +} drmMGAVertex; + +typedef struct { + unsigned int planemask; + unsigned int srcorg; + unsigned int dstorg; + int src_pitch, dst_pitch; + int delta_sx, delta_sy; + int delta_dx, delta_dy; + int height, ydir; /* flip image vertically */ + int source_pitch, dest_pitch; +} drmMGABlit; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c index 3d7df452b..c8545329d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c @@ -342,13 +342,29 @@ static void MGADestroyContext( ScreenPtr pScreen, drmContext hwContext, static void MGAWaitForIdleDMA( ScrnInfoPtr pScrn ) { MGAPtr pMga = MGAPTR(pScrn); + drmMGALock lock; int ret; int i = 0; + memset( &lock, 0, sizeof(drmMGALock) ); + for (;;) { do { - ret = drmMGAFlushDMA( pMga->drmFD, - DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); + /* first ask for quiescent and flush */ + lock.flags = DRM_MGA_LOCK_QUIESCENT | DRM_MGA_LOCK_FLUSH; + do { + ret = drmCommandWrite( pMga->drmFD, DRM_MGA_FLUSH, + &lock, sizeof( drmMGALock ) ); + } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + + /* if it's still busy just try quiescent */ + if ( ret == -EBUSY ) { + lock.flags = DRM_MGA_LOCK_QUIESCENT; + do { + ret = drmCommandWrite( pMga->drmFD, DRM_MGA_FLUSH, + &lock, sizeof( drmMGALock ) ); + } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); + } } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) ); if ( ret == 0 ) @@ -357,7 +373,7 @@ static void MGAWaitForIdleDMA( ScrnInfoPtr pScrn ) xf86DrvMsg( pScrn->scrnIndex, X_ERROR, "[dri] Idle timed out, resetting engine...\n" ); - drmMGAEngineReset( pMga->drmFD ); + drmCommandNone( pMga->drmFD, DRM_MGA_RESET ); } } @@ -846,6 +862,7 @@ static Bool MGADRIKernelInit( ScreenPtr pScreen ) memset( &init, 0, sizeof(drmMGAInit) ); + init.func = MGA_INIT_DMA; init.sarea_priv_offset = sizeof(XF86DRISAREARec); switch ( pMga->Chipset ) { @@ -888,7 +905,7 @@ static Bool MGADRIKernelInit( ScreenPtr pScreen ) init.texture_offset[1] = pMGADRIServer->agpTextures.handle; init.texture_size[1] = pMGADRIServer->agpTextures.size; - ret = drmMGAInitDMA( pMga->drmFD, &init ); + ret = drmCommandWrite( pMga->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit)); if ( ret < 0 ) { xf86DrvMsg( pScrn->scrnIndex, X_ERROR, "[drm] Failed to initialize DMA! (%d)\n", ret ); @@ -1099,9 +1116,48 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) return FALSE; } - /* Check the MGA DRM version */ + /* Check the DRM versioning */ { - drmVersionPtr version = drmGetVersion(pMga->drmFD); + drmVersionPtr version; + + /* Check the DRM lib version. + drmGetLibVersion was not supported in version 1.0, so check for + symbol first to avoid possible crash or hang. + */ + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + version = drmGetLibVersion(pMga->drmFD); + } + else { + /* drmlib version 1.0.0 didn't have the drmGetLibVersion + entry point. Fake it by allocating a version record + via drmGetVersion and changing it to version 1.0.0 + */ + version = drmGetVersion(pMga->drmFD); + version->version_major = 1; + version->version_minor = 0; + version->version_patchlevel = 0; + } + + if (version) { + if (version->version_major != 1 || + version->version_minor < 1) { + /* incompatible drm library version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[dri] MGADRIScreenInit failed because of a version mismatch.\n" + "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + MGADRICloseScreen( pScreen ); /* FIXME: ??? */ + return FALSE; + } + drmFreeVersion(version); + } + + /* Check the MGA DRM version */ + version = drmGetVersion(pMga->drmFD); if ( version ) { if ( version->version_major != 3 || version->version_minor < 0 ) { @@ -1253,13 +1309,17 @@ void MGADRICloseScreen( ScreenPtr pScreen ) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MGAPtr pMga = MGAPTR(pScrn); MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; + drmMGAInit init; if ( pMGADRIServer->drmBuffers ) { drmUnmapBufs( pMGADRIServer->drmBuffers ); pMGADRIServer->drmBuffers = NULL; } - drmMGACleanupDMA( pMga->drmFD ); + /* Cleanup DMA */ + memset( &init, 0, sizeof(drmMGAInit) ); + init.func = MGA_CLEANUP_DMA; + drmCommandWrite( pMga->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit) ); if ( pMGADRIServer->status.map ) { drmUnmap( pMGADRIServer->status.map, pMGADRIServer->status.size ); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h index 0ab62aa32..9d6d7d47c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h @@ -24,7 +24,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: - * Keith WHitwell <keithw@valinux.com> + * Keith Whitwell <keithw@valinux.com> * Gareth Hughes <gareth@valinux.com> */ @@ -32,7 +32,7 @@ #define __MGA_DRI_H__ #include "xf86drm.h" -#include "xf86drmMga.h" +#include "mga_common.h" #define MGA_DEFAULT_AGP_MODE 1 #define MGA_MAX_AGP_MODE 4 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c index 084e3f16f..fcecb2770 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c @@ -331,12 +331,13 @@ static const char *drmSymbols[] = { "drmAgpRelease", "drmAgpUnbind", "drmAgpVendorId", + "drmCommandNone", + "drmCommandRead", + "drmCommandWrite", + "drmCommandWriteRead", "drmFreeVersion", + "drmGetLibVersion", "drmGetVersion", - "drmMGACleanupDMA", - "drmMGAEngineReset", - "drmMGAFlushDMA", - "drmMGAInitDMA", "drmMapBufs", "drmMap", "drmUnmap", diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/xf86drmSiS.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/xf86drmSiS.h new file mode 100644 index 000000000..a4d31a004 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/xf86drmSiS.h @@ -0,0 +1,8 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmSiS.h,v 1.1 2001/12/15 00:59:12 dawes Exp $ */ + +#ifndef __XF86DRI_SIS_H__ +#define __XF86DRI_SIS_H__ + +extern Bool drmSiSAgpInit(int driSubFD, int offset, int size); + +#endif |