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 30 Sep 2002 00:17:36 -0000 @@ -442,6 +442,11 @@ mgaInitVB( ctx ); mgaInitState( mmesa ); + if (sPriv->drmMajor > 3 || (sPriv->drmMajor == 3 && sPriv->drmMinor >= 1)) { + if (mmesa->mgaScreen->irq && getenv("LIBGL_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 30 Sep 2002 00:17:36 -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 30 Sep 2002 00:17:36 -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 30 Sep 2002 00:17:37 -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_NR; + gp.value = &mmesa->mgaScreen->irq; + + ret = drmCommandWriteRead( mmesa->driFd, + DRM_MGA_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_ANR): %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 30 Sep 2002 00:17:37 -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: 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 30 Sep 2002 00:17:42 -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 30 Sep 2002 00:17:42 -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_NR 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 30 Sep 2002 00:17:42 -0000 @@ -922,6 +922,36 @@ return TRUE; } +static void MGADRIIrqInit(MGAPtr info, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + /* version = drmGetVersion(pMga->drmFD); + if ( version ) { + if ( version->version_major != 3 || + version->version_minor < 0 ) {*/ + 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 +1278,8 @@ return FALSE; } + MGADRIIrqInit(pMga, pScreen); + switch(pMga->Chipset) { case PCI_CHIP_MGAG550: case PCI_CHIP_MGAG400: @@ -1314,6 +1346,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/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 30 Sep 2002 00:17:43 -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/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 30 Sep 2002 00:17:43 -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/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 30 Sep 2002 00:17:44 -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/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 30 Sep 2002 00:17:44 -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 30 Sep 2002 00:17:44 -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_NR 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 30 Sep 2002 00:17:44 -0000 @@ -125,6 +125,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 +142,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 +154,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 +348,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 +424,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 +466,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 30 Sep 2002 00:17:45 -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_NR: + value = dev->irq; + 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/mga_irq.c =================================================================== RCS file: programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_irq.c diff -N programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_irq.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_irq.c 30 Sep 2002 00:26:53 -0000 @@ -0,0 +1,99 @@ +/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- + * + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * 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. + * + * Authors: + * Keith Whitwell + * Eric Anholt + */ + +#include "mga.h" +#include "drmP.h" +#include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" + +void mga_dma_service( DRM_IRQ_ARGS ) +{ + drm_device_t *dev = (drm_device_t *) arg; + drm_mga_private_t *dev_priv = + (drm_mga_private_t *)dev->dev_private; + int status; + + status = MGA_READ( MGA_STATUS ); + + /* VBLANK interrupt */ + if ( status & MGA_VLINEPEN ) { + MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR ); + atomic_inc(&dev->vbl_received); + DRM_WAKEUP(&dev->vbl_queue); + } +} + +int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence) +{ + unsigned int cur_vblank; + int ret = 0; + + /* 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... + */ + DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, + ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) + + ~*sequence + 1 ) > (1<<23) ) ); + + *sequence = cur_vblank; + + return ret; +} + +void mga_driver_irq_preinstall( drm_device_t *dev ) { + drm_mga_private_t *dev_priv = + (drm_mga_private_t *)dev->dev_private; + + /* Disable *all* interrupts */ + MGA_WRITE( MGA_IEN, 0 ); + /* Clear bits if they're already high */ + MGA_WRITE( MGA_ICLEAR, ~0 ); +} + +void mga_driver_irq_postinstall( drm_device_t *dev ) { + drm_mga_private_t *dev_priv = + (drm_mga_private_t *)dev->dev_private; + + /* Turn on VBL interrupt */ + MGA_WRITE( MGA_IEN, MGA_VLINEIEN ); +} + +void mga_driver_irq_uninstall( drm_device_t *dev ) { + drm_mga_private_t *dev_priv = + (drm_mga_private_t *)dev->dev_private; + if ( dev_priv ) { + /* Disable *all* interrupts */ + MGA_WRITE( MGA_IEN, 0 ); + } +}