Index: lib/GL/mesa/src/drv/Imakefile =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/Imakefile,v retrieving revision 1.19 diff -u -r1.19 Imakefile --- lib/GL/mesa/src/drv/Imakefile 23 Sep 2002 17:26:32 -0000 1.19 +++ lib/GL/mesa/src/drv/Imakefile 24 Sep 2002 07:39:45 -0000 @@ -5,8 +5,8 @@ #define IHaveSubdirs #define PassCDebugFlags -#SUBDIRS = common DriDrivers -SUBDIRS = common r200 radeon +SUBDIRS = common DriDrivers +#SUBDIRS = common r200 radeon MakeSubdirs($(SUBDIRS)) DependSubdirs($(SUBDIRS)) Index: lib/GL/mesa/src/drv/mga/mga_xmesa.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v retrieving revision 1.38 diff -u -r1.38 mga_xmesa.c --- lib/GL/mesa/src/drv/mga/mga_xmesa.c 8 Jul 2002 17:49:09 -0000 1.38 +++ lib/GL/mesa/src/drv/mga/mga_xmesa.c 24 Sep 2002 07:39:45 -0000 @@ -442,6 +442,11 @@ mgaInitVB( ctx ); mgaInitState( mmesa ); + if (sPriv->drmMajor > 3 || (sPriv->drmMajor == 3 && sPriv->drmMinor >= 1)) { + if (mmesa->mgaScreen->irq && getenv("MGA_THROTTLE_REFRESH")) + mmesa->vblwait = GL_TRUE; + } + driContextPriv->driverPrivate = (void *) mmesa; return GL_TRUE; Index: lib/GL/mesa/src/drv/mga/mga_xmesa.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h,v retrieving revision 1.18 diff -u -r1.18 mga_xmesa.h --- lib/GL/mesa/src/drv/mga/mga_xmesa.h 9 Apr 2002 21:54:50 -0000 1.18 +++ lib/GL/mesa/src/drv/mga/mga_xmesa.h 24 Sep 2002 07:39:45 -0000 @@ -46,6 +46,7 @@ int cpp; /* for front and back buffers */ GLint agpMode; + unsigned int irq; /* IRQ number (0 means none) */ unsigned int mAccess; Index: lib/GL/mesa/src/drv/mga/mgacontext.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v retrieving revision 1.15 diff -u -r1.15 mgacontext.h --- lib/GL/mesa/src/drv/mga/mgacontext.h 9 Apr 2002 21:54:50 -0000 1.15 +++ lib/GL/mesa/src/drv/mga/mgacontext.h 24 Sep 2002 07:39:45 -0000 @@ -202,6 +202,10 @@ drmBufPtr vertex_dma_buffer; drmBufPtr iload_buffer; + /* VBI + */ + GLuint vbl_seq; + GLboolean vblwait; /* Drawable, cliprect and scissor information */ Index: lib/GL/mesa/src/drv/mga/mgaioctl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v retrieving revision 1.29 diff -u -r1.29 mgaioctl.c --- lib/GL/mesa/src/drv/mga/mgaioctl.c 17 May 2002 10:56:12 -0000 1.29 +++ lib/GL/mesa/src/drv/mga/mgaioctl.c 24 Sep 2002 07:39:46 -0000 @@ -280,6 +280,22 @@ int nrswaps; +void mgaWaitForVBlank( mgaContextPtr mmesa ) +{ + drmVBlank vbl; + int ret; + + assert( mmesa->mgaScreen->irq ); + + /* Wait for at least one vertical blank since the last call */ + vbl.type = DRM_VBLANK_ABSOLUTE; + vbl.sequence = mmesa->vbl_seq + 1; + + ret = drmWaitVBlank( mmesa->driFd, &vbl ); + + mmesa->vbl_seq = vbl.sequence; +} + /* * Copy the back buffer to the front buffer. @@ -302,6 +318,10 @@ FLUSH_BATCH( mmesa ); + if ( mmesa->vblwait ) { + mgaWaitForVBlank( mmesa ); + } + LOCK_HARDWARE( mmesa ); last_frame = mmesa->sarea->last_frame.head; @@ -651,7 +671,27 @@ void mgaDDInitIoctlFuncs( GLcontext *ctx ) { + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + ctx->Driver.Clear = mgaDDClear; ctx->Driver.Flush = mgaDDFlush; ctx->Driver.Finish = mgaDDFinish; + + if (mmesa->driScreen->drmMajor > 3 || \ + (mmesa->driScreen->drmMajor == 3 && \ + mmesa->driScreen->drmMinor >= 1)) { + drmMGAGetParam gp; + int ret; + + gp.param = MGA_PARAM_IRQ_ACTIVE; + gp.value = &mmesa->mgaScreen->irq; + + ret = drmCommandWriteRead( mmesa->driFd, + DRM_MGA_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_ACTIVE): %d\n", ret); + exit(1); + } + } } Index: lib/GL/mesa/src/drv/mga/mgaioctl.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v retrieving revision 1.18 diff -u -r1.18 mgaioctl.h --- lib/GL/mesa/src/drv/mga/mgaioctl.h 9 Apr 2002 21:54:50 -0000 1.18 +++ lib/GL/mesa/src/drv/mga/mgaioctl.h 24 Sep 2002 07:39:46 -0000 @@ -34,6 +34,7 @@ #include "mga_xmesa.h" void mgaSwapBuffers( Display *dpy, void *drawablePrivate ); +void mgaWaitForVBlank( mgaContextPtr mmesa ); GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); Index: lib/GL/mesa/src/drv/r200/r200_context.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_context.c,v retrieving revision 1.4 diff -u -r1.4 r200_context.c --- lib/GL/mesa/src/drv/r200/r200_context.c 23 Sep 2002 17:26:33 -0000 1.4 +++ lib/GL/mesa/src/drv/r200/r200_context.c 24 Sep 2002 07:39:46 -0000 @@ -416,7 +416,10 @@ r200InitState( rmesa ); r200InitSwtcl( ctx ); - rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && + if (rmesa->r200Screen->irq && getenv("R200_THROTTLE_REFRESH")) + rmesa->vblwait = GL_TRUE; + + rmesa->do_irqs = (rmesa->r200Screen->irq && !getenv("R200_NO_IRQS") && rmesa->r200Screen->irq_active); @@ -531,10 +534,14 @@ ctx = rmesa->glCtx; if (ctx->Visual.doubleBufferMode) { _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ + + if ( rmesa->vblwait ) { + r200WaitForVBlank( rmesa ); + } + if ( rmesa->doPageFlip ) { r200PageFlip( dPriv ); - } - else { + } else { r200CopyBuffer( dPriv ); } } Index: lib/GL/mesa/src/drv/r200/r200_context.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_context.h,v retrieving revision 1.3 diff -u -r1.3 r200_context.h --- lib/GL/mesa/src/drv/r200/r200_context.h 23 Sep 2002 17:26:33 -0000 1.3 +++ lib/GL/mesa/src/drv/r200/r200_context.h 24 Sep 2002 07:39:46 -0000 @@ -825,6 +825,11 @@ GLuint TexGenCompSel; GLmatrix tmpmat; + /* VBI + */ + GLuint vbl_seq; + GLboolean vblwait; + /* r200_tcl.c */ struct r200_tcl_info tcl; Index: lib/GL/mesa/src/drv/r200/r200_ioctl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c,v retrieving revision 1.3 diff -u -r1.3 r200_ioctl.c --- lib/GL/mesa/src/drv/r200/r200_ioctl.c 23 Sep 2002 17:21:35 -0000 1.3 +++ lib/GL/mesa/src/drv/r200/r200_ioctl.c 24 Sep 2002 07:39:47 -0000 @@ -680,6 +680,24 @@ } +void r200WaitForVBlank( r200ContextPtr rmesa ) +{ + drmVBlank vbl; + int ret; + + assert( rmesa->r200Screen->irq ); + + /* Wait for at least one vertical blank since the last call */ + vbl.type = DRM_VBLANK_ABSOLUTE; + vbl.sequence = rmesa->vbl_seq + 1; + + if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl )) && (R200_DEBUG & DEBUG_IOCTL) ) + fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); + + rmesa->vbl_seq = vbl.sequence; +} + + void r200Flush( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); @@ -853,8 +871,26 @@ void r200InitIoctlFuncs( GLcontext *ctx ) { + r200ContextPtr rmesa = R200_CONTEXT( ctx ); + ctx->Driver.Clear = r200Clear; ctx->Driver.Finish = r200Finish; ctx->Driver.Flush = r200Flush; + + if ( rmesa->dri.drmMinor >= 6 ) { + drmRadeonGetParam gp; + int ret; + + gp.param = RADEON_PARAM_IRQ_ACTIVE; + gp.value = &rmesa->r200Screen->irq; + + ret = drmCommandWriteRead( rmesa->dri.fd, + DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); + exit(1); + } + } } Index: lib/GL/mesa/src/drv/r200/r200_ioctl.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h,v retrieving revision 1.3 diff -u -r1.3 r200_ioctl.h --- lib/GL/mesa/src/drv/r200/r200_ioctl.h 23 Sep 2002 17:26:34 -0000 1.3 +++ lib/GL/mesa/src/drv/r200/r200_ioctl.h 24 Sep 2002 07:39:47 -0000 @@ -101,6 +101,7 @@ extern void r200Flush( GLcontext *ctx ); extern void r200Finish( GLcontext *ctx ); extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); +extern void r200WaitForVBlank( r200ContextPtr rmesa ); extern void r200InitIoctlFuncs( GLcontext *ctx ); extern void *r200AllocateMemoryNV( GLsizei size, GLfloat readfreq, Index: lib/GL/mesa/src/drv/r200/r200_screen.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_screen.h,v retrieving revision 1.3 diff -u -r1.3 r200_screen.h --- lib/GL/mesa/src/drv/r200/r200_screen.h 23 Sep 2002 17:26:36 -0000 1.3 +++ lib/GL/mesa/src/drv/r200/r200_screen.h 24 Sep 2002 07:39:47 -0000 @@ -61,6 +61,7 @@ int cpp; int IsPCI; /* Current card is a PCI card */ int AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ unsigned int frontOffset; unsigned int frontPitch; Index: lib/GL/mesa/src/drv/radeon/radeon_context.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v retrieving revision 1.17 diff -u -r1.17 radeon_context.c --- lib/GL/mesa/src/drv/radeon/radeon_context.c 8 Sep 2002 18:04:39 -0000 1.17 +++ lib/GL/mesa/src/drv/radeon/radeon_context.c 24 Sep 2002 07:39:47 -0000 @@ -404,7 +404,8 @@ radeonInitState( rmesa ); radeonInitSwtcl( ctx ); - + if (rmesa->radeonScreen->irq && getenv("RADEON_THROTTLE_REFRESH")) + rmesa->vblwait = GL_TRUE; #if DO_DEBUG if (getenv("RADEON_DEBUG_FALLBACKS")) @@ -652,10 +653,14 @@ ctx = rmesa->glCtx; if (ctx->Visual.doubleBufferMode) { _mesa_swapbuffers( ctx ); /* flush pending rendering comands */ + + if ( rmesa->vblwait ) { + radeonWaitForVBlank( rmesa ); + } + if ( rmesa->doPageFlip ) { radeonPageFlip( dPriv ); - } - else { + } else { radeonCopyBuffer( dPriv ); } } Index: lib/GL/mesa/src/drv/radeon/radeon_context.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v retrieving revision 1.13 diff -u -r1.13 radeon_context.h --- lib/GL/mesa/src/drv/radeon/radeon_context.h 3 Jul 2002 08:25:42 -0000 1.13 +++ lib/GL/mesa/src/drv/radeon/radeon_context.h 24 Sep 2002 07:39:47 -0000 @@ -738,6 +738,11 @@ GLmatrix tmpmat; GLuint last_ReallyEnabled; + /* VBI + */ + GLuint vbl_seq; + GLboolean vblwait; + /* radeon_tcl.c */ struct radeon_tcl_info tcl; Index: lib/GL/mesa/src/drv/radeon/radeon_ioctl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v retrieving revision 1.23 diff -u -r1.23 radeon_ioctl.c --- lib/GL/mesa/src/drv/radeon/radeon_ioctl.c 5 Sep 2002 16:00:34 -0000 1.23 +++ lib/GL/mesa/src/drv/radeon/radeon_ioctl.c 24 Sep 2002 07:39:47 -0000 @@ -987,6 +987,25 @@ UNLOCK_HARDWARE(rmesa); } + +void radeonWaitForVBlank( radeonContextPtr rmesa ) +{ + drmVBlank vbl; + int ret; + + assert( rmesa->radeonScreen->irq ); + + /* Wait for at least one vertical blank since the last call */ + vbl.type = DRM_VBLANK_ABSOLUTE; + vbl.sequence = rmesa->vbl_seq + 1; + + if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl )) && (RADEON_DEBUG & DEBUG_IOCTL) ) + fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); + + rmesa->vbl_seq = vbl.sequence; +} + + void radeonGetAllParams( radeonContextPtr rmesa ) { int ret; @@ -999,8 +1018,21 @@ DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { - fprintf(stderr, "drmRadeonGetParam: %d\n", ret); + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret); exit(1); + } + + if ( rmesa->dri.drmMinor >= 6 ) { + gp.param = RADEON_PARAM_IRQ_ACTIVE; + gp.value = &rmesa->radeonScreen->irq; + + ret = drmCommandWriteRead( rmesa->dri.fd, + DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ): %d\n", ret); + exit(1); + } } } Index: lib/GL/mesa/src/drv/radeon/radeon_ioctl.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v retrieving revision 1.6 diff -u -r1.6 radeon_ioctl.h --- lib/GL/mesa/src/drv/radeon/radeon_ioctl.h 12 Jun 2002 15:50:26 -0000 1.6 +++ lib/GL/mesa/src/drv/radeon/radeon_ioctl.h 24 Sep 2002 07:39:47 -0000 @@ -93,6 +93,7 @@ extern void radeonFlush( GLcontext *ctx ); extern void radeonFinish( GLcontext *ctx ); extern void radeonWaitForIdleLocked( radeonContextPtr rmesa ); +extern void radeonWaitForVBlank( radeonContextPtr rmesa ); extern void radeonInitIoctlFuncs( GLcontext *ctx ); extern void radeonGetAllParams( radeonContextPtr rmesa ); Index: lib/GL/mesa/src/drv/radeon/radeon_screen.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v retrieving revision 1.8 diff -u -r1.8 radeon_screen.h --- lib/GL/mesa/src/drv/radeon/radeon_screen.h 5 Sep 2002 16:00:35 -0000 1.8 +++ lib/GL/mesa/src/drv/radeon/radeon_screen.h 24 Sep 2002 07:39:47 -0000 @@ -60,6 +60,7 @@ int cpp; int IsPCI; /* Current card is a PCI card */ int AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ unsigned int frontOffset; unsigned int frontPitch; Index: programs/Xserver/hw/xfree86/drivers/ati/radeon.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v retrieving revision 1.26 diff -u -r1.26 radeon.h --- programs/Xserver/hw/xfree86/drivers/ati/radeon.h 23 Sep 2002 17:26:39 -0000 1.26 +++ programs/Xserver/hw/xfree86/drivers/ati/radeon.h 24 Sep 2002 07:39:49 -0000 @@ -481,6 +481,8 @@ CARD32 aux_sc_cntl; int irq; + CARD32 gen_int_cntl; + #endif /* XVideo */ Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v retrieving revision 1.32 diff -u -r1.32 radeon_dri.c --- programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 23 Sep 2002 17:26:39 -0000 1.32 +++ programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 24 Sep 2002 07:39:50 -0000 @@ -1329,6 +1329,11 @@ RADEONCP_STOP(pScrn, info); } + if (info->irq) { + drmCtlUninstHandler(info->drmFD); + info->irq = 0; + } + /* De-allocate vertex buffers */ if (info->buffers) { drmUnmapBufs(info->buffers); Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v retrieving revision 1.27 diff -u -r1.27 radeon_driver.c --- programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 23 Sep 2002 17:26:40 -0000 1.27 +++ programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 24 Sep 2002 07:39:56 -0000 @@ -4506,6 +4506,11 @@ * Charl P. Botha */ xf86EnablePciBusMaster(info->PciInfo, TRUE); + if (info->irq) { + unsigned char *RADEONMMIO = info->MMIO; + OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl); + } + RADEONCP_START(pScrn, info); DRIUnlock(pScrn->pScreen); } Index: programs/Xserver/hw/xfree86/drivers/mga/mga.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v retrieving revision 1.23 diff -u -r1.23 mga.h --- programs/Xserver/hw/xfree86/drivers/mga/mga.h 27 Jan 2002 20:05:35 -0000 1.23 +++ programs/Xserver/hw/xfree86/drivers/mga/mga.h 24 Sep 2002 07:39:56 -0000 @@ -352,6 +352,7 @@ int agpMode; int agpSize; + int irq; #endif XF86VideoAdaptorPtr adaptor; Bool SecondCrtc; Index: programs/Xserver/hw/xfree86/drivers/mga/mga_common.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_common.h,v retrieving revision 1.2 diff -u -r1.2 mga_common.h --- programs/Xserver/hw/xfree86/drivers/mga/mga_common.h 9 Apr 2002 21:54:53 -0000 1.2 +++ programs/Xserver/hw/xfree86/drivers/mga/mga_common.h 24 Sep 2002 07:39:56 -0000 @@ -58,6 +58,7 @@ #define DRM_MGA_INDICES 0x06 #define DRM_MGA_ILOAD 0x07 #define DRM_MGA_BLIT 0x08 +#define DRM_MGA_GETPARAM 0x09 typedef struct { enum { @@ -137,5 +138,15 @@ int height, ydir; /* flip image vertically */ int source_pitch, dest_pitch; } drmMGABlit; + +/* 3.1: An ioctl to get parameters that aren't available to the 3d + * client any other way. + */ +#define MGA_PARAM_IRQ_ACTIVE 1 + +typedef struct { + int param; + int *value; +} drmMGAGetParam; #endif Index: programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v retrieving revision 1.44 diff -u -r1.44 mga_dri.c --- programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c 9 Apr 2002 21:54:53 -0000 1.44 +++ programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c 24 Sep 2002 07:39:57 -0000 @@ -922,6 +922,32 @@ return TRUE; } +static void MGADRIIrqInit(MGAPtr info, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (!info->irq) { + info->irq = drmGetInterruptFromBusID( + info->drmFD, + ((pciConfigPtr)info->PciInfo->thisCard)->busnum, + ((pciConfigPtr)info->PciInfo->thisCard)->devnum, + ((pciConfigPtr)info->PciInfo->thisCard)->funcnum); + + if((drmCtlInstHandler(info->drmFD, info->irq)) != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] failure adding irq handler, " + "there is a device already using that irq\n" + "[drm] falling back to irq-free operation\n"); + info->irq = 0; + } + } + + if (info->irq) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] dma control initialized, using IRQ %d\n", + info->irq); +} + static Bool MGADRIBuffersInit( ScreenPtr pScreen ) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -1248,6 +1274,8 @@ return FALSE; } + MGADRIIrqInit(pMga, pScreen); + switch(pMga->Chipset) { case PCI_CHIP_MGAG550: case PCI_CHIP_MGAG400: @@ -1314,6 +1342,11 @@ if ( pMGADRIServer->drmBuffers ) { drmUnmapBufs( pMGADRIServer->drmBuffers ); pMGADRIServer->drmBuffers = NULL; + } + + if (pMga->irq) { + drmCtlUninstHandler(pMga->drmFD); + pMga->irq = 0; } /* Cleanup DMA */ Index: programs/Xserver/hw/xfree86/os-support/xf86drm.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v retrieving revision 1.22 diff -u -r1.22 xf86drm.h --- programs/Xserver/hw/xfree86/os-support/xf86drm.h 12 Jun 2002 15:50:28 -0000 1.22 +++ programs/Xserver/hw/xfree86/os-support/xf86drm.h 24 Sep 2002 07:39:58 -0000 @@ -227,6 +227,19 @@ } drmClipRect, *drmClipRectPtr; +typedef enum { + DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ + DRM_VBLANK_RELATIVE = 0x1 /* Wait for given number of vblanks */ +} drmVBlankSeqType; + +typedef struct _drmVBlank { + drmVBlankSeqType type; + unsigned int sequence; + long tval_sec; + long tval_usec; +} drmVBlank, *drmVBlankPtr; + + #define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) @@ -540,6 +553,8 @@ extern int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle); extern int drmScatterGatherFree(int fd, unsigned long handle); + +extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); /* Support routines */ extern int drmError(int err, const char *label); Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile,v retrieving revision 1.11 diff -u -r1.11 Imakefile --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile 23 Sep 2002 17:26:40 -0000 1.11 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile 24 Sep 2002 07:39:58 -0000 @@ -24,6 +24,7 @@ LinkSourceFile(mga_dma.c,$(XF86OSSRC)/shared/drm/kernel) LinkSourceFile(mga_drm.h,$(XF86OSSRC)/shared/drm/kernel) LinkSourceFile(mga_drv.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_irq.c,$(XF86OSSRC)/shared/drm/kernel) LinkSourceFile(mga_state.c,$(XF86OSSRC)/shared/drm/kernel) LinkSourceFile(mga_ucode.h,$(XF86OSSRC)/shared/drm/kernel) LinkSourceFile(mga_warp.c,$(XF86OSSRC)/shared/drm/kernel) Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h,v retrieving revision 1.8 diff -u -r1.8 drm.h --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h 5 Jul 2002 08:31:07 -0000 1.8 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h 24 Sep 2002 07:39:58 -0000 @@ -345,6 +345,18 @@ int funcnum; } drm_irq_busid_t; +typedef enum { + _DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1 /* Wait for given number of vblanks */ +} drm_vblank_seq_type_t; + +typedef struct drm_radeon_vbl_wait { + drm_vblank_seq_type_t type; + unsigned int sequence; + long tval_sec; + long tval_usec; +} drm_wait_vblank_t; + typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; @@ -438,6 +450,8 @@ #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) + +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t) /* Device specfic ioctls should only be in their respective headers * The device specific ioctl range is 0x40 to 0x79. */ Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v retrieving revision 1.8 diff -u -r1.8 drmP.h --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h 5 Jul 2002 08:31:07 -0000 1.8 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h 24 Sep 2002 07:39:59 -0000 @@ -465,6 +465,10 @@ #if __FreeBSD_version >= 400005 struct task task; #endif +#if __HAVE_VBL_IRQ + wait_queue_head_t vbl_queue; /* vbl wait channel */ + atomic_t vbl_received; +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -579,6 +583,9 @@ extern int DRM(irq_install)( drm_device_t *dev, int irq ); extern int DRM(irq_uninstall)( drm_device_t *dev ); extern void DRM(dma_service)( DRM_IRQ_ARGS ); +extern void DRM(driver_irq_preinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_postinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_uninstall)( drm_device_t *dev ); #if __HAVE_DMA_IRQ_BH extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS ); #endif @@ -603,6 +610,9 @@ extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); #endif #endif /* __HAVE_DMA */ +#if __HAVE_VBL_IRQ +extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); +#endif #if __REALLY_HAVE_AGP /* AGP/GART support (drm_agpsupport.h) */ Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h,v retrieving revision 1.4 diff -u -r1.4 drm_dma.h --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h 5 Jul 2002 08:31:07 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h 24 Sep 2002 07:39:59 -0000 @@ -532,7 +532,7 @@ #endif /* Before installing handler */ - DRIVER_PREINSTALL(); + DRM(driver_irq_preinstall)( dev ); /* Install handler */ rid = 0; @@ -552,7 +552,7 @@ } /* After installing handler */ - DRIVER_POSTINSTALL(); + DRM(driver_irq_postinstall)( dev ); return 0; } @@ -571,7 +571,7 @@ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - DRIVER_UNINSTALL(); + DRM(driver_irq_uninstall)( dev ); bus_teardown_intr(dev->device, dev->irqr, dev->irqh); bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irqr); @@ -616,3 +616,34 @@ #endif /* __HAVE_DMA_IRQ */ #endif /* __HAVE_DMA */ + +#if __HAVE_VBL_IRQ +int DRM(wait_vblank)( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret; + + if (!dev->irq) + return DRM_ERR(EINVAL); + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + if ( vblwait.type == _DRM_VBLANK_RELATIVE ) { + vblwait.sequence += atomic_read( &dev->vbl_received ); + } + + ret = DRM(vblank_wait)( dev, &vblwait.sequence ); + + microtime( &now ); + vblwait.tval_sec = now.tv_sec; + vblwait.tval_usec = now.tv_usec; + + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} +#endif /* __HAVE_VBL_IRQ */ Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_drv.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_drv.h,v retrieving revision 1.6 diff -u -r1.6 drm_drv.h --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_drv.h 23 Sep 2002 17:26:40 -0000 1.6 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_drv.h 24 Sep 2002 07:39:59 -0000 @@ -217,6 +217,10 @@ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 }, #endif +#if __HAVE_VBL_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 }, +#endif + DRIVER_IOCTLS }; Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_os_freebsd.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_os_freebsd.h,v retrieving revision 1.5 diff -u -r1.5 drm_os_freebsd.h --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_os_freebsd.h 23 Sep 2002 17:26:41 -0000 1.5 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_os_freebsd.h 24 Sep 2002 07:39:59 -0000 @@ -407,6 +407,9 @@ #if __HAVE_DMA extern d_ioctl_t DRM(control); #endif +#if __HAVE_VBL_IRQ +extern d_ioctl_t DRM(wait_vblank); +#endif /* AGP/GART support (drm_agpsupport.h) */ #if __REALLY_HAVE_AGP Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma_dma.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma_dma.c,v retrieving revision 1.3 diff -u -r1.3 gamma_dma.c --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma_dma.c 23 Sep 2002 17:26:41 -0000 1.3 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma_dma.c 24 Sep 2002 07:39:59 -0000 @@ -567,3 +567,45 @@ return retcode; } + +void DRM(driver_irq_preinstall)(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; +#if 1 + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); +#else + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE ); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); +#endif +} + +void DRM(driver_irq_postinstall)(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; +#if 1 + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); +#else + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); +#endif +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); +} Index: programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga/Makefile =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga/Makefile,v retrieving revision 1.5 diff -u -r1.5 Makefile --- programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga/Makefile 30 Aug 2002 23:49:24 -0000 1.5 +++ programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga/Makefile 24 Sep 2002 07:39:59 -0000 @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/.. KMOD= mga NOMAN= YES -SRCS= mga_drv.c mga_state.c mga_warp.c mga_dma.c +SRCS= mga_drv.c mga_state.c mga_warp.c mga_dma.c mga_irq.c SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS+= ${DEBUG_FLAGS} -I. -I.. Index: programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v retrieving revision 1.37 diff -u -r1.37 xf86drm.c --- programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c 8 Aug 2002 21:23:46 -0000 1.37 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c 24 Sep 2002 07:39:59 -0000 @@ -1105,6 +1105,17 @@ return 0; } +int drmWaitVBlank(int fd, drmVBlankPtr vbl) +{ + int ret; + + do { + ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); + } while (ret && errno == EINTR); + + return ret; +} + int drmError(int err, const char *label) { switch (err) { Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux,v retrieving revision 1.43 diff -u -r1.43 Makefile.linux --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux 23 Sep 2002 17:26:42 -0000 1.43 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux 24 Sep 2002 07:40:00 -0000 @@ -158,7 +158,7 @@ MODS += i830.o endif -MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o +MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES) I810OBJS = i810_drv.o i810_dma.o Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v retrieving revision 1.38 diff -u -r1.38 drm.h --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h 5 Jul 2002 08:31:09 -0000 1.38 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h 24 Sep 2002 07:40:00 -0000 @@ -345,6 +345,19 @@ int funcnum; } drm_irq_busid_t; +typedef enum { + _DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1 /* Wait for given number of vblanks */ +} drm_vblank_seq_type_t; + +typedef struct drm_radeon_vbl_wait { + drm_vblank_seq_type_t type; + unsigned int sequence; + long tval_sec; + long tval_usec; +} drm_wait_vblank_t; + + typedef struct drm_agp_mode { unsigned long mode; } drm_agp_mode_t; @@ -438,6 +451,8 @@ #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) + +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t) /* Device specfic ioctls should only be in their respective headers * The device specific ioctl range is 0x40 to 0x79. */ Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v retrieving revision 1.51 diff -u -r1.51 drmP.h --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h 11 Sep 2002 00:57:49 -0000 1.51 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h 24 Sep 2002 07:40:00 -0000 @@ -577,6 +577,10 @@ int last_context; /* Last current context */ unsigned long last_switch; /* jiffies at last context switch */ struct tq_struct tq; +#if __HAVE_VBL_IRQ + wait_queue_head_t vbl_queue; + atomic_t vbl_received; +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -809,6 +813,9 @@ extern int DRM(irq_uninstall)( drm_device_t *dev ); extern void DRM(dma_service)( int irq, void *device, struct pt_regs *regs ); +extern void DRM(driver_irq_preinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_postinstall)( drm_device_t *dev ); +extern void DRM(driver_irq_uninstall)( drm_device_t *dev ); #if __HAVE_DMA_IRQ_BH extern void DRM(dma_immediate_bh)( void *dev ); #endif @@ -833,6 +840,9 @@ extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); #endif #endif /* __HAVE_DMA */ +#if __HAVE_VBL_IRQ +extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); +#endif #if __REALLY_HAVE_AGP /* AGP/GART support (drm_agpsupport.h) */ @@ -884,6 +894,9 @@ extern int DRM(sg_free)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); #endif + +extern int DRM(wait_vblank)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* ATI PCIGART support (ati_pcigart.h) */ extern int DRM(ati_pcigart_init)(drm_device_t *dev, Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h,v retrieving revision 1.5 diff -u -r1.5 drm_dma.h --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h 14 Feb 2002 02:00:22 -0000 1.5 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h 24 Sep 2002 07:40:01 -0000 @@ -538,8 +538,12 @@ dev->tq.data = dev; #endif +#if __HAVE_VBL_IRQ + init_waitqueue_head(&dev->vbl_queue); +#endif + /* Before installing handler */ - DRIVER_PREINSTALL(); + DRM(driver_irq_preinstall)(dev); /* Install handler */ ret = request_irq( dev->irq, DRM(dma_service), @@ -552,7 +556,7 @@ } /* After installing handler */ - DRIVER_POSTINSTALL(); + DRM(driver_irq_postinstall)(dev); return 0; } @@ -571,7 +575,7 @@ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - DRIVER_UNINSTALL(); + DRM(driver_irq_uninstall)( dev ); free_irq( irq, dev ); @@ -597,6 +601,40 @@ return -EINVAL; } } + +#if __HAVE_VBL_IRQ + +int DRM(wait_vblank)( DRM_IOCTL_ARGS ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret; + + if (!dev->irq) + return -EINVAL; + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + if ( vblwait.type == _DRM_VBLANK_RELATIVE ) { + vblwait.sequence += atomic_read( &dev->vbl_received ); + } + + ret = radeon_vblank_wait( dev, &vblwait.sequence ); + + do_gettimeofday( &now ); + vblwait.tval_sec = now.tv_sec; + vblwait.tval_usec = now.tv_usec; + + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} + +#endif /* __HAVE_VBL_IRQ */ #else Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h,v retrieving revision 1.23 diff -u -r1.23 drm_drv.h --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h 21 Sep 2002 23:18:54 -0000 1.23 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h 24 Sep 2002 07:40:01 -0000 @@ -222,6 +222,10 @@ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 }, #endif +#if __HAVE_VBL_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 }, +#endif + DRIVER_IOCTLS }; Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h,v retrieving revision 1.6 diff -u -r1.6 gamma.h --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h 5 Jul 2002 08:31:09 -0000 1.6 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h 24 Sep 2002 07:40:01 -0000 @@ -95,53 +95,6 @@ #define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_IRQ_BH 1 -#if 1 -#define DRIVER_PREINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); \ - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ -} while (0) -#define DRIVER_POSTINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ -} while (0) -#else -#define DRIVER_POSTINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); \ -} while (0) - -#define DRIVER_PREINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );\ - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );\ -} while (0) -#endif - -#define DRIVER_UNINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ -} while (0) - #define DRIVER_AGP_BUFFERS_MAP( dev ) \ ((drm_gamma_private_t *)((dev)->dev_private))->buffers Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c,v retrieving revision 1.17 diff -u -r1.17 gamma_dma.c --- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c 9 Apr 2002 21:54:55 -0000 1.17 +++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c 24 Sep 2002 07:40:02 -0000 @@ -832,3 +832,45 @@ up(&dev->struct_sem); return 0; } + +void DRM(driver_irq_preinstall)(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; +#if 1 + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); +#else + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE ); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); +#endif +} + +void DRM(driver_irq_postinstall)(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; +#if 1 + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); +#else + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); +#endif +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); +} Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga.h,v retrieving revision 1.2 diff -u -r1.2 mga.h --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga.h 5 Jul 2002 08:31:11 -0000 1.2 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga.h 24 Sep 2002 07:40:02 -0000 @@ -45,11 +45,11 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010321" +#define DRIVER_DATE "20020923" #define DRIVER_MAJOR 3 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 2 +#define DRIVER_MINOR 1 +#define DRIVER_PATCHLEVEL 0 #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ @@ -61,7 +61,8 @@ [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_GETPARAM)]= { mga_getparam, 1, 0 }, #define __HAVE_COUNTERS 3 #define __HAVE_COUNTER6 _DRM_STAT_IRQ @@ -77,6 +78,8 @@ /* DMA customization: */ #define __HAVE_DMA 1 +#define __HAVE_DMA_IRQ 1 +#define __HAVE_VBL_IRQ 1 #define __HAVE_DMA_QUIESCENT 1 #define DRIVER_DMA_QUIESCENT() do { \ Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drm.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drm.h,v retrieving revision 1.2 diff -u -r1.2 mga_drm.h --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drm.h 5 Jul 2002 08:31:11 -0000 1.2 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drm.h 24 Sep 2002 07:40:02 -0000 @@ -239,6 +239,7 @@ #define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) #define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) #define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) +#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(0x49, drm_mga_getparam_t) typedef struct _drm_mga_warp_index { int installed; @@ -321,5 +322,15 @@ int height, ydir; /* flip image vertically */ int source_pitch, dest_pitch; } drm_mga_blit_t; + +/* 3.1: An ioctl to get parameters that aren't available to the 3d + * client any other way. + */ +#define MGA_PARAM_IRQ_ACTIVE 1 + +typedef struct drm_mga_getparam { + int param; + int *value; +} drm_mga_getparam_t; #endif Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drv.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drv.h,v retrieving revision 1.4 diff -u -r1.4 mga_drv.h --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drv.h 29 Aug 2002 07:34:48 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_drv.h 24 Sep 2002 07:40:02 -0000 @@ -98,6 +98,11 @@ drm_map_t *primary; drm_map_t *buffers; drm_map_t *agp_textures; + + /* SW interrupt */ + wait_queue_head_t swi_queue; + atomic_t swi_received; + atomic_t swi_emitted; } drm_mga_private_t; /* mga_dma.c */ @@ -125,6 +130,7 @@ extern int mga_dma_indices( DRM_IOCTL_ARGS ); extern int mga_dma_iload( DRM_IOCTL_ARGS ); extern int mga_dma_blit( DRM_IOCTL_ARGS ); +extern int mga_getparam( DRM_IOCTL_ARGS ); /* mga_warp.c */ extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv ); @@ -141,6 +147,7 @@ #ifdef __alpha__ #define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) +#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg))) #define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) #define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) @@ -152,6 +159,7 @@ #else #define MGA_READ( reg ) MGA_DEREF( reg ) +#define MGA_READ8( reg ) MGA_DEREF8( reg ) #define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0) #define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0) #endif @@ -345,6 +353,11 @@ /* A reduced set of the mga registers. */ #define MGA_CRTC_INDEX 0x1fd4 +#define MGA_CRTC_DATA 0x1fd5 + +/* CRTC11 */ +#define MGA_VINTCLR (1 << 4) +#define MGA_VINTEN (1 << 5) #define MGA_ALPHACTRL 0x2c7c #define MGA_AR0 0x1c60 @@ -416,8 +429,10 @@ #define MGA_ICLEAR 0x1e18 # define MGA_SOFTRAPICLR (1 << 0) +# define MGA_VLINEICLR (1 << 5) #define MGA_IEN 0x1e1c # define MGA_SOFTRAPIEN (1 << 0) +# define MGA_VLINEIEN (1 << 5) #define MGA_LEN 0x1c5c @@ -456,6 +471,8 @@ # define MGA_SRCACC_AGP (1 << 1) #define MGA_STATUS 0x1e14 # define MGA_SOFTRAPEN (1 << 0) +# define MGA_VSYNCPEN (1 << 4) +# define MGA_VLINEPEN (1 << 5) # define MGA_DWGENGSTS (1 << 16) # define MGA_ENDPRDMASTS (1 << 17) #define MGA_STENCIL 0x2cc8 Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_state.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_state.c,v retrieving revision 1.4 diff -u -r1.4 mga_state.c --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_state.c 29 Aug 2002 07:34:48 -0000 1.4 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_state.c 24 Sep 2002 07:40:02 -0000 @@ -1075,3 +1075,36 @@ return 0; } + +int mga_getparam( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_getparam_t param; + int value; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t *)data, + sizeof(param) ); + + DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); + + switch( param.param ) { + case MGA_PARAM_IRQ_ACTIVE: + value = dev->irq ? 1 : 0; + break; + default: + return DRM_ERR(EINVAL); + } + + if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return DRM_ERR(EFAULT); + } + + return 0; +} Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h,v retrieving revision 1.5 diff -u -r1.5 radeon.h --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h 23 Sep 2002 17:26:42 -0000 1.5 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h 24 Sep 2002 07:40:02 -0000 @@ -132,52 +132,9 @@ */ #define __HAVE_DMA 1 - #define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 +#define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 - -#define DRIVER_PREINSTALL() do { \ - drm_radeon_private_t *dev_priv = \ - (drm_radeon_private_t *)dev->dev_private; \ - u32 tmp; \ - \ - /* Clear bit if it's already high: */ \ - tmp = RADEON_READ( RADEON_GEN_INT_STATUS ); \ - tmp = tmp & RADEON_SW_INT_TEST_ACK; \ - RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp ); \ - \ - /* Disable *all* interrupts */ \ - RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \ -} while (0) - -#ifdef __linux__ -#define IWH(x) init_waitqueue_head(x) -#else -#define IWH(x) -#endif - -#define DRIVER_POSTINSTALL() do { \ - drm_radeon_private_t *dev_priv = \ - (drm_radeon_private_t *)dev->dev_private; \ - \ - atomic_set(&dev_priv->irq_received, 0); \ - atomic_set(&dev_priv->irq_emitted, 0); \ - IWH(&dev_priv->irq_queue); \ - \ - /* Turn on SW_INT only */ \ - RADEON_WRITE( RADEON_GEN_INT_CNTL, \ - RADEON_SW_INT_ENABLE ); \ -} while (0) - -#define DRIVER_UNINSTALL() do { \ - drm_radeon_private_t *dev_priv = \ - (drm_radeon_private_t *)dev->dev_private; \ - if ( dev_priv ) { \ - /* Disable *all* interrupts */ \ - RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \ - } \ -} while (0) /* Buffer customization: */ Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h,v retrieving revision 1.6 diff -u -r1.6 radeon_drv.h --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h 23 Sep 2002 17:26:43 -0000 1.6 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_drv.h 24 Sep 2002 07:40:02 -0000 @@ -139,9 +139,10 @@ struct mem_block *agp_heap; struct mem_block *fb_heap; - wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; + /* SW interrupt */ + wait_queue_head_t swi_queue; + atomic_t swi_received; + atomic_t swi_emitted; } drm_radeon_private_t; @@ -187,11 +188,12 @@ extern void radeon_mem_takedown( struct mem_block **heap ); extern void radeon_mem_release( struct mem_block *heap ); + /* radeon_irq.c */ extern int radeon_irq_emit( DRM_IOCTL_ARGS ); extern int radeon_irq_wait( DRM_IOCTL_ARGS ); extern int radeon_emit_and_wait_irq(drm_device_t *dev); -extern int radeon_wait_irq(drm_device_t *dev, int irq_nr); +extern int radeon_wait_irq(drm_device_t *dev, int swi_nr); extern int radeon_emit_irq(drm_device_t *dev); @@ -271,11 +273,15 @@ #define RADEON_GEN_INT_CNTL 0x0040 +# define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) # define RADEON_SW_INT_ENABLE (1 << 25) #define RADEON_GEN_INT_STATUS 0x0044 +# define RADEON_CRTC_VBLANK_STAT (1 << 0) +# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) # define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) +# define RADEON_SW_INT_TEST (1 << 25) # define RADEON_SW_INT_TEST_ACK (1 << 25) # define RADEON_SW_INT_FIRE (1 << 26) Index: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_irq.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_irq.c,v retrieving revision 1.2 diff -u -r1.2 radeon_irq.c --- programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_irq.c 23 Sep 2002 17:26:43 -0000 1.2 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_irq.c 24 Sep 2002 07:40:02 -0000 @@ -1,4 +1,4 @@ -/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*- +/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- * * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * @@ -58,37 +58,77 @@ drm_device_t *dev = (drm_device_t *) arg; drm_radeon_private_t *dev_priv = (drm_radeon_private_t *)dev->dev_private; - u32 temp; + u32 stat, ack = 0; /* Need to wait for fifo to drain? */ - temp = RADEON_READ(RADEON_GEN_INT_STATUS); - temp = temp & RADEON_SW_INT_TEST_ACK; - if (temp == 0) return; - RADEON_WRITE(RADEON_GEN_INT_STATUS, temp); + stat = RADEON_READ(RADEON_GEN_INT_STATUS); - atomic_inc(&dev_priv->irq_received); + /* SW interrupt */ + if (stat & RADEON_SW_INT_TEST) { + ack |= RADEON_SW_INT_TEST_ACK; + atomic_inc(&dev_priv->swi_received); #ifdef __linux__ - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); -#endif /* __linux__ */ + wake_up_interruptible(&dev_priv->swi_queue); +#endif #ifdef __FreeBSD__ - taskqueue_enqueue(taskqueue_swi, &dev->task); -#endif /* __FreeBSD__ */ + wakeup(&dev->vbl_queue); +#endif + } + + /* VBLANK interrupt */ + if (stat & RADEON_CRTC_VBLANK_STAT) { + ack |= RADEON_CRTC_VBLANK_STAT_ACK; + atomic_inc(&dev->vbl_received); +#ifdef __linux__ + wake_up_interruptible(&dev->vbl_queue); +#endif +#ifdef __FreeBSD__ + wakeup(&dev->vbl_queue); +#endif + } + + if (ack) + RADEON_WRITE(RADEON_GEN_INT_STATUS, ack); } + -void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS ) +int radeon_vblank_wait(drm_device_t *dev, unsigned int *sequence) { - drm_device_t *dev = (drm_device_t *) arg; - drm_radeon_private_t *dev_priv = + drm_radeon_private_t *dev_priv = (drm_radeon_private_t *)dev->dev_private; + unsigned int cur_vblank; + int ret = 0; + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + /* Assume that the user has missed the current sequence number by about + * a day rather than she wants to wait for years using vertical blanks :) + */ + while ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) + + ~*sequence + 1 ) > (1<<23) ) { + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; #ifdef __linux__ - wake_up_interruptible(&dev_priv->irq_queue); + interruptible_sleep_on( &dev->vbl_queue ); + + if (signal_pending(current)) { + ret = -EINTR; + break; + } #endif /* __linux__ */ #ifdef __FreeBSD__ - wakeup( &dev_priv->irq_queue ); -#endif + ret = tsleep( &dev->vbl_queue, 3*hz, "rdnvbl", PZERO | PCATCH); + if (ret) + break; +#endif /* __FreeBSD__ */ + } + + *sequence = cur_vblank; + + return ret; } @@ -97,7 +137,7 @@ drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; - atomic_inc(&dev_priv->irq_emitted); + atomic_inc(&dev_priv->swi_emitted); BEGIN_RING(2); OUT_RING( CP_PACKET0( RADEON_GEN_INT_STATUS, 0 ) ); @@ -105,11 +145,11 @@ ADVANCE_RING(); COMMIT_RING(); - return atomic_read(&dev_priv->irq_emitted); + return atomic_read(&dev_priv->swi_emitted); } -int radeon_wait_irq(drm_device_t *dev, int irq_nr) +int radeon_wait_irq(drm_device_t *dev, int swi_nr) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *)dev->dev_private; @@ -119,7 +159,7 @@ #endif /* __linux__ */ int ret = 0; - if (atomic_read(&dev_priv->irq_received) >= irq_nr) + if (atomic_read(&dev_priv->swi_received) >= swi_nr) return 0; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; @@ -143,12 +183,12 @@ } current->state = TASK_RUNNING; - remove_wait_queue(&dev_priv->irq_queue, &entry); + remove_wait_queue(&dev_priv->swi_queue, &entry); return ret; #endif /* __linux__ */ #ifdef __FreeBSD__ - ret = tsleep( &dev_priv->irq_queue, PZERO | PCATCH, \ + ret = tsleep( &dev_priv->swi_queue, PZERO | PCATCH, \ "rdnirq", 3*hz ); if ( (ret == EWOULDBLOCK) || (ret == EINTR) ) return DRM_ERR(EBUSY); @@ -156,7 +196,6 @@ #endif /* __FreeBSD__ */ } - int radeon_emit_and_wait_irq(drm_device_t *dev) { return radeon_wait_irq( dev, radeon_emit_irq(dev) ); @@ -212,3 +251,40 @@ return radeon_wait_irq( dev, irqwait.irq_seq ); } +void DRM(driver_irq_preinstall)( drm_device_t *dev ) { + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + u32 tmp; + + /* Disable *all* interrupts */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + + /* Clear bits if they're already high */ + tmp = RADEON_READ( RADEON_GEN_INT_STATUS ); + RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp ); +} + +void DRM(driver_irq_postinstall)( drm_device_t *dev ) { + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + + atomic_set(&dev_priv->swi_received, 0); + atomic_set(&dev_priv->swi_emitted, 0); +#ifdef __linux__ + init_waitqueue_head(&dev_priv->swi_queue)); +#endif + + /* Turn on SW and VBL ints */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, + RADEON_CRTC_VBLANK_MASK | + RADEON_SW_INT_ENABLE ); +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { + drm_radeon_private_t *dev_priv = + (drm_radeon_private_t *)dev->dev_private; + if ( dev_priv ) { + /* Disable *all* interrupts */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + } +}