/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
  */
-/**************************************************************************
- *
+/*
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  *
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- **************************************************************************/
+ */
 
 #include "drmP.h"
 #include "drm.h"
        return 0;
 }
 
-static int i915_resume(drm_device_t * dev)
+static int i915_dma_resume(drm_device_t * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
                retcode = i915_dma_cleanup(dev);
                break;
        case I915_RESUME_DMA:
-               retcode = i915_resume(dev);
+               retcode = i915_dma_resume(dev);
                break;
        default:
                retcode = -EINVAL;
        case I915_PARAM_ALLOW_BATCHBUFFER:
                value = dev_priv->allow_batchbuffer ? 1 : 0;
                break;
+       case I915_PARAM_LAST_DISPATCH:
+               value = READ_BREADCRUMB(dev_priv);
+               break;
        default:
                DRM_ERROR("Unkown parameter %d\n", param.param);
                return DRM_ERR(EINVAL);
 
-/**************************************************************************
- *
+/*
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  *
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- **************************************************************************/
+ */
 
 #ifndef _I915_DRM_H_
 #define _I915_DRM_H_
  */
 #define I915_PARAM_IRQ_ACTIVE            1
 #define I915_PARAM_ALLOW_BATCHBUFFER     2
+#define I915_PARAM_LAST_DISPATCH         3
 
 typedef struct drm_i915_getparam {
        int param;
 
 /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
  */
-/**************************************************************************
+/*
  *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- **************************************************************************/
+ */
 
 #include "drmP.h"
 #include "drm.h"
         */
        .driver_features =
            DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
-           DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+           DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
        .load = i915_driver_load,
        .lastclose = i915_driver_lastclose,
        .preclose = i915_driver_preclose,
        .device_is_agp = i915_driver_device_is_agp,
+       .vblank_wait = i915_driver_vblank_wait,
        .irq_preinstall = i915_driver_irq_preinstall,
        .irq_postinstall = i915_driver_irq_postinstall,
        .irq_uninstall = i915_driver_irq_uninstall,
 
 /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
  */
-/**************************************************************************
+/*
  *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- **************************************************************************/
+ */
 
 #ifndef _I915_DRV_H_
 #define _I915_DRV_H_
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20040405"
+#define DRIVER_DATE            "20051209"
 
 /* Interface history:
  *
  * 1.1: Original.
+ * 1.2: Add Power Management
+ * 1.3: Add vblank support
  */
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           1
+#define DRIVER_MINOR           3
 #define DRIVER_PATCHLEVEL      0
 
-/* We use our own dma mechanisms, not the drm template code.  However,
- * the shared IRQ code is useful to us:
- */
-#define __HAVE_PM              1
-
 typedef struct _drm_i915_ring_buffer {
        int tail_mask;
        unsigned long Start;
        int tex_lru_log_granularity;
        int allow_batchbuffer;
        struct mem_block *agp_heap;
+       unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
 } drm_i915_private_t;
 
 extern drm_ioctl_desc_t i915_ioctls[];
 extern void i915_driver_lastclose(drm_device_t * dev);
 extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp);
 extern int i915_driver_device_is_agp(drm_device_t * dev);
+extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+                             unsigned long arg);
 
 /* i915_irq.c */
 extern int i915_irq_emit(DRM_IOCTL_ARGS);
 extern int i915_irq_wait(DRM_IOCTL_ARGS);
 
+extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
 extern void i915_driver_irq_preinstall(drm_device_t * dev);
 extern void i915_driver_irq_postinstall(drm_device_t * dev);
 extern void i915_mem_release(drm_device_t * dev,
                             DRMFILE filp, struct mem_block *heap);
 
-extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
-                             unsigned long arg);
-
-#define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, reg)
-#define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, reg, val)
-#define I915_READ16(reg)       DRM_READ16(dev_priv->mmio_map, reg)
-#define I915_WRITE16(reg,val)  DRM_WRITE16(dev_priv->mmio_map, reg, val)
+#define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, (reg))
+#define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
+#define I915_READ16(reg)       DRM_READ16(dev_priv->mmio_map, (reg))
+#define I915_WRITE16(reg,val)  DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
 
 #define I915_VERBOSE 0
 
 #define PPCR                   0x61204
 #define PPCR_ON                        (1<<0)
 
+#define DVOB                   0x61140
+#define DVOB_ON                        (1<<31)
+#define DVOC                   0x61160
+#define DVOC_ON                        (1<<31)
+#define LVDS                   0x61180
+#define LVDS_ON                        (1<<31)
+
 #define ADPA                   0x61100
 #define ADPA_DPMS_MASK         (~(3<<10))
 #define ADPA_DPMS_ON           (0<<10)
 
 #define CMD_OP_DESTBUFFER_INFO  ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
 
+#define READ_BREADCRUMB(dev_priv) (((u32 *)(dev_priv->hw_status_page))[5])
+
 #endif
 
-/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
+/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
  */
-/**************************************************************************
- *
+/*
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  *
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- **************************************************************************/
+ */
 
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 
-#define USER_INT_FLAG 0x2
+#define USER_INT_FLAG (1<<1)
+#define VSYNC_PIPEB_FLAG (1<<5)
+#define VSYNC_PIPEA_FLAG (1<<7)
+
 #define MAX_NOPID ((u32)~0)
-#define READ_BREADCRUMB(dev_priv)  (((u32*)(dev_priv->hw_status_page))[5])
 
 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 {
        u16 temp;
 
        temp = I915_READ16(I915REG_INT_IDENTITY_R);
-       temp &= USER_INT_FLAG;
+       temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG);
 
        DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
 
                return IRQ_NONE;
 
        I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
-       DRM_WAKEUP(&dev_priv->irq_queue);
+
+       if (temp & USER_INT_FLAG)
+               DRM_WAKEUP(&dev_priv->irq_queue);
+
+       if (temp & VSYNC_PIPEA_FLAG) {
+               atomic_inc(&dev->vbl_received);
+               DRM_WAKEUP(&dev->vbl_queue);
+               drm_vbl_send_signals(dev);
+       }
 
        return IRQ_HANDLED;
 }
        return ret;
 }
 
+int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned int cur_vblank;
+       int ret = 0;
+
+       if (!dev_priv) {
+               DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+               return DRM_ERR(EINVAL);
+       }
+
+       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+                   (((cur_vblank = atomic_read(&dev->vbl_received))
+                       - *sequence) <= (1<<23)));
+       
+       *sequence = cur_vblank;
+
+       return ret;
+}
+
+
 /* Needs the lock as it touches the ring.
  */
 int i915_irq_emit(DRM_IOCTL_ARGS)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-       I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG);
+       I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG);
        DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
 }
 
 
 /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
  */
-/**************************************************************************
- *
+/*
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  *
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- **************************************************************************/
+ */
 
 #include "drmP.h"
 #include "drm.h"