i915: This was part of a sync to the intel driver at some point
authorRobert Noland <rnoland@2hip.net>
Tue, 24 Feb 2009 08:00:42 +0000 (02:00 -0600)
committerRobert Noland <rnoland@2hip.net>
Tue, 24 Feb 2009 18:24:29 +0000 (12:24 -0600)
-Remove the old TTM interface
-Move register definitions to i915_reg.h
-Rework the irq handler

bsd-core/drmP.h
bsd-core/i915_drv.c
bsd-core/i915_reg.h [new symlink]
shared-core/i915_dma.c
shared-core/i915_drv.h
shared-core/i915_irq.c
shared-core/i915_reg.h [new file with mode: 0644]

index 7348745..fe3fc78 100644 (file)
@@ -658,6 +658,7 @@ struct drm_device {
                                /* Context support */
        int               irq;          /* Interrupt used by board         */
        int               irq_enabled;  /* True if the irq handler is enabled */
+       int               msi_enabled;  /* MSI enabled */
        int               irqrid;       /* Interrupt used by board */
        struct resource   *irqr;        /* Resource for interrupt used by board    */
        void              *irqh;        /* Handle from bus_setup_intr      */
index 0c36a6f..70088ee 100644 (file)
@@ -75,7 +75,6 @@ static void i915_configure(struct drm_device *dev)
        dev->driver->buf_priv_size      = sizeof(drm_i915_private_t);
        dev->driver->load               = i915_driver_load;
        dev->driver->unload             = i915_driver_unload;
-       dev->driver->firstopen          = i915_driver_firstopen;
        dev->driver->preclose           = i915_driver_preclose;
        dev->driver->lastclose          = i915_driver_lastclose;
        dev->driver->device_is_agp      = i915_driver_device_is_agp;
diff --git a/bsd-core/i915_reg.h b/bsd-core/i915_reg.h
new file mode 120000 (symlink)
index 0000000..d364e7f
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/i915_reg.h
\ No newline at end of file
index 65bbf23..7f458c7 100644 (file)
@@ -55,6 +55,9 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
                if (ring->space >= n)
                        return 0;
 
+               if (dev_priv->sarea_priv)
+                       dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+
                if (ring->head != last_head)
                        i = 0;
 
@@ -69,77 +72,53 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
        return -EBUSY;
 }
 
-int i915_init_hardware_status(struct drm_device *dev)
+/**
+ * Sets up the hardware status page for devices that need a physical address
+ * in the register.
+ */
+static int i915_init_phys_hws(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_dma_handle_t *dmah;
 
        /* Program Hardware Status Page */
-#ifdef __FreeBSD__
        DRM_UNLOCK();
-#endif
-       dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
-#ifdef __FreeBSD__
+       dev_priv->status_page_dmah =
+               drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
        DRM_LOCK();
-#endif
-       if (!dmah) {
+       if (!dev_priv->status_page_dmah) {
                DRM_ERROR("Can not allocate hardware status page\n");
                return -ENOMEM;
        }
-
-       dev_priv->status_page_dmah = dmah;
-       dev_priv->hw_status_page = dmah->vaddr;
-       dev_priv->dma_status_page = dmah->busaddr;
+       dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+       dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
 
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 
-       I915_WRITE(0x02080, dev_priv->dma_status_page);
+       I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
        DRM_DEBUG("Enabled hardware status page\n");
        return 0;
 }
 
-void i915_free_hardware_status(struct drm_device *dev)
+/**
+ * Frees the hardware status page, whether it's a physical address or a virtual
+ * address set up by the X Server.
+ */
+static void i915_free_hws(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        if (dev_priv->status_page_dmah) {
                drm_pci_free(dev, dev_priv->status_page_dmah);
                dev_priv->status_page_dmah = NULL;
-               /* Need to rewrite hardware status page */
-               I915_WRITE(0x02080, 0x1ffff000);
        }
 
        if (dev_priv->status_gfx_addr) {
                dev_priv->status_gfx_addr = 0;
                drm_core_ioremapfree(&dev_priv->hws_map, dev);
-               I915_WRITE(0x02080, 0x1ffff000);
        }
-}
 
-#if I915_RING_VALIDATE
-/**
- * Validate the cached ring tail value
- *
- * If the X server writes to the ring and DRM doesn't
- * reload the head and tail pointers, it will end up writing
- * data to the wrong place in the ring, causing havoc.
- */
-void i915_ring_validate(struct drm_device *dev, const char *func, int line)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
-       u32     tail = I915_READ(PRB0_TAIL) & HEAD_ADDR;
-       u32     head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-
-       if (tail != ring->tail) {
-               DRM_ERROR("%s:%d head sw %x, hw %x. tail sw %x hw %x\n",
-                         func, line,
-                         ring->head, head, ring->tail, tail);
-#ifdef __linux__
-               BUG_ON(1);
-#endif
-       }
+       /* Need to rewrite hardware status page */
+       I915_WRITE(HWS_PGA, 0x1ffff000);
 }
-#endif
 
 void i915_kernel_lost_context(struct drm_device * dev)
 {
@@ -151,6 +130,9 @@ void i915_kernel_lost_context(struct drm_device * dev)
        ring->space = ring->head - (ring->tail + 8);
        if (ring->space < 0)
                ring->space += ring->Size;
+
+       if (ring->head == ring->tail && dev_priv->sarea_priv)
+               dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
 }
 
 static int i915_dma_cleanup(struct drm_device * dev)
@@ -165,86 +147,22 @@ static int i915_dma_cleanup(struct drm_device * dev)
 
        if (dev_priv->ring.virtual_start) {
                drm_core_ioremapfree(&dev_priv->ring.map, dev);
-               dev_priv->ring.virtual_start = 0;
-               dev_priv->ring.map.handle = 0;
+               dev_priv->ring.virtual_start = NULL;
+               dev_priv->ring.map.handle = NULL;
                dev_priv->ring.map.size = 0;
        }
 
+       /* Clear the HWS virtual address at teardown */
        if (I915_NEED_GFX_HWS(dev))
-               i915_free_hardware_status(dev);
+               i915_free_hws(dev);
 
        return 0;
 }
 
-#if defined(I915_HAVE_BUFFER)
-#define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16)
-#define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff)
-#define DRI2_SAREA_BLOCK_NEXT(p)                               \
-       ((void *) ((unsigned char *) (p) +                      \
-                  DRI2_SAREA_BLOCK_SIZE(*(unsigned int *) p)))
-
-#define DRI2_SAREA_BLOCK_END           0x0000
-#define DRI2_SAREA_BLOCK_LOCK          0x0001
-#define DRI2_SAREA_BLOCK_EVENT_BUFFER  0x0002
-
-static int
-setup_dri2_sarea(struct drm_device * dev,
-                struct drm_file *file_priv,
-                drm_i915_init_t * init)
+static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       int ret;
-       unsigned int *p, *end, *next;
-
-       mutex_lock(&dev->struct_mutex);
-       dev_priv->sarea_bo =
-               drm_lookup_buffer_object(file_priv,
-                                        init->sarea_handle, 1);
-       mutex_unlock(&dev->struct_mutex);
-
-       if (!dev_priv->sarea_bo) {
-               DRM_ERROR("did not find sarea bo\n");
-               return -EINVAL;
-       }
-
-       ret = drm_bo_kmap(dev_priv->sarea_bo, 0,
-                         dev_priv->sarea_bo->num_pages,
-                         &dev_priv->sarea_kmap);
-       if (ret) {
-               DRM_ERROR("could not map sarea bo\n");
-               return ret;
-       }
-
-       p = dev_priv->sarea_kmap.virtual;
-       end = (void *) p + (dev_priv->sarea_bo->num_pages << PAGE_SHIFT);
-       while (p < end && DRI2_SAREA_BLOCK_TYPE(*p) != DRI2_SAREA_BLOCK_END) {
-               switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
-               case DRI2_SAREA_BLOCK_LOCK:
-                       dev->lock.hw_lock = (void *) (p + 1);
-                       dev->sigdata.lock = dev->lock.hw_lock;
-                       break;
-               }
-               next = DRI2_SAREA_BLOCK_NEXT(p);
-               if (next <= p || end < next) {
-                       DRM_ERROR("malformed dri2 sarea: next is %p should be within %p-%p\n",
-                                 next, p, end);
-                       return -EINVAL;
-               }
-               p = next;
-       }
-
-       return 0;
-}
-#endif
 
-static int i915_initialize(struct drm_device * dev,
-                          struct drm_file *file_priv,
-                          drm_i915_init_t * init)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-#if defined(I915_HAVE_BUFFER)
-       int ret;
-#endif
        dev_priv->sarea = drm_getsarea(dev);
        if (!dev_priv->sarea) {
                DRM_ERROR("can not find sarea!\n");
@@ -252,20 +170,17 @@ static int i915_initialize(struct drm_device * dev,
                return -EINVAL;
        }
 
-#ifdef I915_HAVE_BUFFER
-       dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
-#endif
-
-       if (init->sarea_priv_offset)
-               dev_priv->sarea_priv = (drm_i915_sarea_t *)
-                       ((u8 *) dev_priv->sarea->handle +
-                        init->sarea_priv_offset);
-       else {
-               /* No sarea_priv for you! */
-               dev_priv->sarea_priv = NULL;
-       }
+       dev_priv->sarea_priv = (drm_i915_sarea_t *)
+           ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
 
        if (init->ring_size != 0) {
+               if (dev_priv->ring.ring_obj != NULL) {
+                       i915_dma_cleanup(dev);
+                       DRM_ERROR("Client tried to initialize ringbuffer in "
+                                 "GEM mode\n");
+                       return -EINVAL;
+               }
+
                dev_priv->ring.Size = init->ring_size;
                dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
 
@@ -283,41 +198,20 @@ static int i915_initialize(struct drm_device * dev,
                                  " ring buffer\n");
                        return -ENOMEM;
                }
-
-               dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
        }
 
-       dev_priv->cpp = init->cpp;
-
-       if (dev_priv->sarea_priv)
-               dev_priv->sarea_priv->pf_current_page = 0;
+       dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
 
-       /* We are using separate values as placeholders for mechanisms for
-        * private backbuffer/depthbuffer usage.
-        */
+       dev_priv->cpp = init->cpp;
+       dev_priv->back_offset = init->back_offset;
+       dev_priv->front_offset = init->front_offset;
+       dev_priv->current_page = 0;
+       dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
 
        /* Allow hardware batchbuffers unless told otherwise.
         */
        dev_priv->allow_batchbuffer = 1;
 
-       /* Enable vblank on pipe A for older X servers
-        */
-       dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
-
-#ifdef I915_HAVE_BUFFER
-       mutex_init(&dev_priv->cmdbuf_mutex);
-#endif
-#if defined(I915_HAVE_BUFFER)
-       if (init->func == I915_INIT_DMA2) {
-               ret = setup_dri2_sarea(dev, file_priv, init);
-               if (ret) {
-                       i915_dma_cleanup(dev);
-                       DRM_ERROR("could not set up dri2 sarea\n");
-                       return ret;
-               }
-       }
-#endif
-
        return 0;
 }
 
@@ -346,9 +240,9 @@ static int i915_dma_resume(struct drm_device * dev)
        DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
 
        if (dev_priv->status_gfx_addr != 0)
-               I915_WRITE(0x02080, dev_priv->status_gfx_addr);
+               I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
        else
-               I915_WRITE(0x02080, dev_priv->dma_status_page);
+               I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
        DRM_DEBUG("Enabled hardware status page\n");
 
        return 0;
@@ -362,8 +256,7 @@ static int i915_dma_init(struct drm_device *dev, void *data,
 
        switch (init->func) {
        case I915_INIT_DMA:
-       case I915_INIT_DMA2:
-               retcode = i915_initialize(dev, file_priv, init);
+               retcode = i915_initialize(dev, init);
                break;
        case I915_CLEANUP_DMA:
                retcode = i915_dma_cleanup(dev);
@@ -538,55 +431,28 @@ int i915_emit_box(struct drm_device * dev,
  * emit. For now, do it in both places:
  */
 
-void i915_emit_breadcrumb(struct drm_device *dev)
+static void i915_emit_breadcrumb(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
 
-       if (++dev_priv->counter > BREADCRUMB_MASK) {
-                dev_priv->counter = 1;
-                DRM_DEBUG("Breadcrumb counter wrapped around\n");
-       }
-
+       dev_priv->counter++;
+       if (dev_priv->counter > 0x7FFFFFFFUL)
+               dev_priv->counter = 0;
        if (dev_priv->sarea_priv)
                dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
 
        BEGIN_LP_RING(4);
        OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
+       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
        OUT_RING(dev_priv->counter);
        OUT_RING(0);
        ADVANCE_LP_RING();
 }
 
-
-int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       uint32_t flush_cmd = MI_FLUSH;
-       RING_LOCALS;
-
-       flush_cmd |= flush;
-
-       i915_kernel_lost_context(dev);
-
-       BEGIN_LP_RING(4);
-       OUT_RING(flush_cmd);
-       OUT_RING(0);
-       OUT_RING(0);
-       OUT_RING(0);
-       ADVANCE_LP_RING();
-
-       return 0;
-}
-
-
 static int i915_dispatch_cmdbuffer(struct drm_device * dev,
                                   drm_i915_cmdbuffer_t * cmd)
 {
-#ifdef I915_HAVE_FENCE
-       drm_i915_private_t *dev_priv = dev->dev_private;
-#endif
        int nbox = cmd->num_cliprects;
        int i = 0, count, ret;
 
@@ -613,15 +479,11 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
        }
 
        i915_emit_breadcrumb(dev);
-#ifdef I915_HAVE_FENCE
-       if (unlikely((dev_priv->counter & 0xFF) == 0))
-               drm_fence_flush_old(dev, 0, dev_priv->counter);
-#endif
        return 0;
 }
 
-int i915_dispatch_batchbuffer(struct drm_device * dev,
-                             drm_i915_batchbuffer_t * batch)
+static int i915_dispatch_batchbuffer(struct drm_device * dev,
+                                    drm_i915_batchbuffer_t * batch)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_clip_rect __user *boxes = batch->cliprects;
@@ -646,14 +508,7 @@ int i915_dispatch_batchbuffer(struct drm_device * dev,
                                return ret;
                }
 
-               if (IS_I830(dev) || IS_845G(dev)) {
-                       BEGIN_LP_RING(4);
-                       OUT_RING(MI_BATCH_BUFFER);
-                       OUT_RING(batch->start | MI_BATCH_NON_SECURE);
-                       OUT_RING(batch->start + batch->used - 4);
-                       OUT_RING(0);
-                       ADVANCE_LP_RING();
-               } else {
+               if (!IS_I830(dev) && !IS_845G(dev)) {
                        BEGIN_LP_RING(2);
                        if (IS_I965G(dev)) {
                                OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
@@ -663,115 +518,90 @@ int i915_dispatch_batchbuffer(struct drm_device * dev,
                                OUT_RING(batch->start | MI_BATCH_NON_SECURE);
                        }
                        ADVANCE_LP_RING();
+               } else {
+                       BEGIN_LP_RING(4);
+                       OUT_RING(MI_BATCH_BUFFER);
+                       OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+                       OUT_RING(batch->start + batch->used - 4);
+                       OUT_RING(0);
+                       ADVANCE_LP_RING();
                }
        }
 
        i915_emit_breadcrumb(dev);
-#ifdef I915_HAVE_FENCE
-       if (unlikely((dev_priv->counter & 0xFF) == 0))
-               drm_fence_flush_old(dev, 0, dev_priv->counter);
-#endif
+
        return 0;
 }
 
-static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
+static int i915_dispatch_flip(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       u32 num_pages, current_page, next_page, dspbase;
-       int shift = 2 * plane, x, y;
        RING_LOCALS;
 
-       /* Calculate display base offset */
-       num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
-       current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
-       next_page = (current_page + 1) % num_pages;
+       if (!dev_priv->sarea_priv)
+               return -EINVAL;
 
-       switch (next_page) {
-       default:
-       case 0:
-               dspbase = dev_priv->sarea_priv->front_offset;
-               break;
-       case 1:
-               dspbase = dev_priv->sarea_priv->back_offset;
-               break;
-       case 2:
-               dspbase = dev_priv->sarea_priv->third_offset;
-               break;
-       }
+       DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+                 __func__,
+                 dev_priv->current_page,
+                 dev_priv->sarea_priv->pf_current_page);
+
+       i915_kernel_lost_context(dev);
 
-       if (plane == 0) {
-               x = dev_priv->sarea_priv->planeA_x;
-               y = dev_priv->sarea_priv->planeA_y;
+       BEGIN_LP_RING(2);
+       OUT_RING(MI_FLUSH | MI_READ_FLUSH);
+       OUT_RING(0);
+       ADVANCE_LP_RING();
+
+       BEGIN_LP_RING(6);
+       OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
+       OUT_RING(0);
+       if (dev_priv->current_page == 0) {
+               OUT_RING(dev_priv->back_offset);
+               dev_priv->current_page = 1;
        } else {
-               x = dev_priv->sarea_priv->planeB_x;
-               y = dev_priv->sarea_priv->planeB_y;
+               OUT_RING(dev_priv->front_offset);
+               dev_priv->current_page = 0;
        }
+       OUT_RING(0);
+       ADVANCE_LP_RING();
 
-       dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp;
+       BEGIN_LP_RING(2);
+       OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
+       OUT_RING(0);
+       ADVANCE_LP_RING();
 
-       DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page,
-                 dspbase);
+       dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
 
        BEGIN_LP_RING(4);
-       OUT_RING(sync ? 0 :
-                (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP :
-                                      MI_WAIT_FOR_PLANE_A_FLIP)));
-       OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) |
-                (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
-       OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
-       OUT_RING(dspbase);
+       OUT_RING(MI_STORE_DWORD_INDEX);
+       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+       OUT_RING(dev_priv->counter);
+       OUT_RING(0);
        ADVANCE_LP_RING();
 
-       dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
-       dev_priv->sarea_priv->pf_current_page |= next_page << shift;
-}
-
-void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       int i;
-
-       DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
-                 planes, dev_priv->sarea_priv->pf_current_page);
-
-       i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
-
-       for (i = 0; i < 2; i++)
-               if (planes & (1 << i))
-                       i915_do_dispatch_flip(dev, i, sync);
-
-       i915_emit_breadcrumb(dev);
-#ifdef I915_HAVE_FENCE
-       if (unlikely(!sync && ((dev_priv->counter & 0xFF) == 0)))
-               drm_fence_flush_old(dev, 0, dev_priv->counter);
-#endif
+       dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
+       return 0;
 }
 
-int i915_quiescent(struct drm_device *dev)
+static int i915_quiescent(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       int ret;
 
        i915_kernel_lost_context(dev);
-       ret = i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
-       if (ret)
-       {
-               i915_kernel_lost_context (dev);
-               DRM_ERROR ("not quiescent head %08x tail %08x space %08x\n",
-                          dev_priv->ring.head,
-                          dev_priv->ring.tail,
-                          dev_priv->ring.space);
-       }
-       return ret;
+       return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
 }
 
 static int i915_flush_ioctl(struct drm_device *dev, void *data,
                            struct drm_file *file_priv)
 {
+       int ret;
 
-       LOCK_TEST_WITH_RETURN(dev, file_priv);
+       RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
+
+       ret = i915_quiescent(dev);
 
-       return i915_quiescent(dev);
+       return ret;
 }
 
 static int i915_batchbuffer(struct drm_device *dev, void *data,
@@ -781,6 +611,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
        drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
            dev_priv->sarea_priv;
        drm_i915_batchbuffer_t *batch = data;
+       size_t cliplen;
        int ret;
 
        if (!dev_priv->allow_batchbuffer) {
@@ -791,16 +622,35 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
        DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
                  batch->start, batch->used, batch->num_cliprects);
 
-       LOCK_TEST_WITH_RETURN(dev, file_priv);
+       RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+       DRM_UNLOCK();
+       cliplen = batch->num_cliprects * sizeof(struct drm_clip_rect);
        if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
-                                                       batch->num_cliprects *
-                                                       sizeof(struct drm_clip_rect)))
+           cliplen)) {
+               DRM_LOCK();
                return -EFAULT;
+       }
+       if (batch->num_cliprects) {
+               ret = vslock(batch->cliprects, cliplen);
+               if (ret) {
+                       DRM_ERROR("Fault wiring cliprects\n");
+                       DRM_LOCK();
+                       return -EFAULT;
+               }
+       }
+       DRM_LOCK();
 
        ret = i915_dispatch_batchbuffer(dev, batch);
 
-       sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+       if (sarea_priv)
+               sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+
+       DRM_UNLOCK();
+       if (batch->num_cliprects)
+               vsunlock(batch->cliprects, cliplen);
+       DRM_LOCK();
+
        return ret;
 }
 
@@ -811,80 +661,70 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
        drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
            dev_priv->sarea_priv;
        drm_i915_cmdbuffer_t *cmdbuf = data;
+       size_t cliplen;
        int ret;
 
        DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
                  cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
 
-       LOCK_TEST_WITH_RETURN(dev, file_priv);
+       RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-       if (cmdbuf->num_cliprects &&
-           DRM_VERIFYAREA_READ(cmdbuf->cliprects,
-                               cmdbuf->num_cliprects *
-                               sizeof(struct drm_clip_rect))) {
+       DRM_UNLOCK();
+       cliplen = cmdbuf->num_cliprects * sizeof(struct drm_clip_rect);
+       if (cmdbuf->num_cliprects && DRM_VERIFYAREA_READ(cmdbuf->cliprects,
+           cliplen)) {
                DRM_ERROR("Fault accessing cliprects\n");
+               DRM_LOCK();
                return -EFAULT;
        }
+       if (cmdbuf->num_cliprects) {
+               ret = vslock(cmdbuf->cliprects, cliplen);
+               if (ret) {
+                       DRM_ERROR("Fault wiring cliprects\n");
+                       DRM_LOCK();
+                       return -EFAULT;
+               }
+               ret = vslock(cmdbuf->buf, cmdbuf->sz);
+               if (ret) {
+                       vsunlock(cmdbuf->cliprects, cliplen);
+                       DRM_ERROR("Fault wiring cmds\n");
+                       DRM_LOCK();
+                       return -EFAULT;
+               }
+       }
+       DRM_LOCK();
 
        ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
+       DRM_UNLOCK();
+       if (cmdbuf->num_cliprects) {
+               vsunlock(cmdbuf->buf, cmdbuf->sz);
+               vsunlock(cmdbuf->cliprects, cliplen);
+       }
+       DRM_LOCK();
        if (ret) {
                DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
                return ret;
        }
 
-       sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
-       return 0;
-}
-
-#if defined(DRM_DEBUG_CODE)
-#define DRM_DEBUG_RELOCATION   (drm_debug != 0)
-#else
-#define DRM_DEBUG_RELOCATION   0
-#endif
-
-static int i915_do_cleanup_pageflip(struct drm_device * dev)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
-
-       DRM_DEBUG("\n");
-
-       for (i = 0, planes = 0; i < 2; i++)
-               if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
-                       dev_priv->sarea_priv->pf_current_page =
-                               (dev_priv->sarea_priv->pf_current_page &
-                                ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
-
-                       planes |= 1 << i;
-               }
-
-       if (planes)
-               i915_dispatch_flip(dev, planes, 0);
-
+       if (sarea_priv)
+               sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
        return 0;
 }
 
-static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
+static int i915_flip_bufs(struct drm_device *dev, void *data,
+                         struct drm_file *file_priv)
 {
-       drm_i915_flip_t *param = data;
+       int ret;
 
-       DRM_DEBUG("\n");
+       DRM_DEBUG("%s\n", __func__);
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-       /* This is really planes */
-       if (param->pipes & ~0x3) {
-               DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n",
-                         param->pipes);
-               return -EINVAL;
-       }
+       ret = i915_dispatch_flip(dev);
 
-       i915_dispatch_flip(dev, param->pipes, 0);
-
-       return 0;
+       return ret;
 }
 
-
 static int i915_getparam(struct drm_device *dev, void *data,
                         struct drm_file *file_priv)
 {
@@ -911,11 +751,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
                value = dev->pci_device;
                break;
        case I915_PARAM_HAS_GEM:
-#ifdef I915_HAVE_GEM
-               value = 1;
-#else
                value = 0;
-#endif
                break;
        default:
                DRM_ERROR("Unknown parameter %d\n", param->param);
@@ -958,63 +794,6 @@ static int i915_setparam(struct drm_device *dev, void *data,
        return 0;
 }
 
-drm_i915_mmio_entry_t mmio_table[] = {
-       [MMIO_REGS_PS_DEPTH_COUNT] = {
-               I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE,
-               0x2350,
-               8
-       }
-};
-
-static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t);
-
-static int i915_mmio(struct drm_device *dev, void *data,
-                    struct drm_file *file_priv)
-{
-       uint32_t buf[8];
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mmio_entry_t *e;
-       drm_i915_mmio_t *mmio = data;
-       void __iomem *base;
-       int i;
-
-       if (!dev_priv) {
-               DRM_ERROR("called with no initialization\n");
-               return -EINVAL;
-       }
-
-       if (mmio->reg >= mmio_table_size)
-               return -EINVAL;
-
-       e = &mmio_table[mmio->reg];
-       base = (u8 *) dev_priv->mmio_map->handle + e->offset;
-
-       switch (mmio->read_write) {
-       case I915_MMIO_READ:
-               if (!(e->flag & I915_MMIO_MAY_READ))
-                       return -EINVAL;
-               for (i = 0; i < e->size / 4; i++)
-                       buf[i] = I915_READ(e->offset + i * 4);
-               if (DRM_COPY_TO_USER(mmio->data, buf, e->size)) {
-                       DRM_ERROR("DRM_COPY_TO_USER failed\n");
-                       return -EFAULT;
-               }
-               break;
-               
-       case I915_MMIO_WRITE:
-               if (!(e->flag & I915_MMIO_MAY_WRITE))
-                       return -EINVAL;
-               if (DRM_COPY_FROM_USER(buf, mmio->data, e->size)) {
-                       DRM_ERROR("DRM_COPY_TO_USER failed\n");
-                       return -EFAULT;
-               }
-               for (i = 0; i < e->size / 4; i++)
-                       I915_WRITE(e->offset + i * 4, buf[i]);
-               break;
-       }
-       return 0;
-}
-
 static int i915_set_status_page(struct drm_device *dev, void *data,
                                struct drm_file *file_priv)
 {
@@ -1028,6 +807,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
+
        DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
 
        dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
@@ -1050,7 +830,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
        I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
-       DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
+       DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
                        dev_priv->status_gfx_addr);
        DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
        return 0;
@@ -1058,7 +838,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 
 int i915_driver_load(struct drm_device *dev, unsigned long flags)
 {
-       struct drm_i915_private *dev_priv;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long base, size;
        int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
 
@@ -1083,27 +863,34 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        size = drm_get_resource_len(dev, mmio_bar);
 
        ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
-               _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map);
+           _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map);
 #ifdef I915_HAVE_GEM
        i915_gem_load(dev);
 #endif
-       DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
-
-#ifdef __linux__
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
-       intel_init_chipset_flush_compat(dev);
-#endif
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
-       intel_opregion_init(dev);
-#endif
-#endif
-
        /* Init HWS */
        if (!I915_NEED_GFX_HWS(dev)) {
-               ret = i915_init_hardware_status(dev);
-               if(ret)
+               ret = i915_init_phys_hws(dev);
+               if (ret != 0)
                        return ret;
        }
+#ifdef __linux__
+       /* On the 945G/GM, the chipset reports the MSI capability on the
+        * integrated graphics even though the support isn't actually there
+        * according to the published specs.  It doesn't appear to function
+        * correctly in testing on 945G.
+        * This may be a side effect of MSI having been made available for PEG
+        * and the registers being closely associated.
+        *
+        * According to chipset errata, on the 965GM, MSI interrupts may
+        * be lost or delayed
+        */
+       if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev))
+               if (pci_enable_msi(dev->pdev))
+                       DRM_ERROR("failed to enable MSI\n");
+
+       intel_opregion_init(dev);
+#endif
+       DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
 
        return ret;
 }
@@ -1112,71 +899,20 @@ int i915_driver_unload(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       i915_free_hardware_status(dev);
-
-       drm_rmmap(dev, dev_priv->mmio_map);
-
-       DRM_SPINUNINIT(&dev_priv->user_irq_lock);
+       i915_free_hws(dev);
 
+       drm_rmmap(dev, dev_priv->mmio_map);
 #ifdef __linux__
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
        intel_opregion_free(dev);
 #endif
-#endif
+       DRM_SPINUNINIT(&dev_priv->user_irq_lock);
 
        drm_free(dev->dev_private, sizeof(drm_i915_private_t),
                 DRM_MEM_DRIVER);
-       dev->dev_private = NULL;
 
-#ifdef __linux__
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
-       intel_fini_chipset_flush_compat(dev);
-#endif
-#endif
        return 0;
 }
 
-void i915_driver_lastclose(struct drm_device * dev)
-{
-       drm_i915_private_t *dev_priv = dev->dev_private;
-
-       /* agp off can use this to get called before dev_priv */
-       if (!dev_priv)
-               return;
-
-#ifdef I915_HAVE_BUFFER
-       if (dev_priv->val_bufs) {
-               vfree(dev_priv->val_bufs);
-               dev_priv->val_bufs = NULL;
-       }
-#endif
-#ifdef I915_HAVE_GEM
-       i915_gem_lastclose(dev);
-#endif
-       if (drm_getsarea(dev) && dev_priv->sarea_priv)
-               i915_do_cleanup_pageflip(dev);
-       if (dev_priv->sarea_priv)
-               dev_priv->sarea_priv = NULL;
-       if (dev_priv->agp_heap)
-               i915_mem_takedown(&(dev_priv->agp_heap));
-#if defined(I915_HAVE_BUFFER)
-       if (dev_priv->sarea_kmap.virtual) {
-               drm_bo_kunmap(&dev_priv->sarea_kmap);
-               dev_priv->sarea_kmap.virtual = NULL;
-               dev->lock.hw_lock = NULL;
-               dev->sigdata.lock = NULL;
-       }
-
-       if (dev_priv->sarea_bo) {
-               mutex_lock(&dev->struct_mutex);
-               drm_bo_usage_deref_locked(&dev_priv->sarea_bo);
-               mutex_unlock(&dev->struct_mutex);
-               dev_priv->sarea_bo = NULL;
-       }
-#endif
-       i915_dma_cleanup(dev);
-}
-
 int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
 {
        struct drm_i915_file_private *i915_file_priv;
@@ -1196,6 +932,21 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
        return 0;
 }
 
+void i915_driver_lastclose(struct drm_device * dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+
+       if (!dev_priv)
+               return;
+#ifdef I915_HAVE_GEM
+       i915_gem_lastclose(dev);
+#endif
+       if (dev_priv->agp_heap)
+               i915_mem_takedown(&(dev_priv->agp_heap));
+
+       i915_dma_cleanup(dev);
+}
+
 void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
@@ -1226,20 +977,16 @@ struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE,  i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
        DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),
        DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_MMIO, i915_mmio, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-#ifdef I915_HAVE_BUFFER
-       DRM_IOCTL_DEF(DRM_I915_EXECBUFFER, i915_execbuffer, DRM_AUTH),
-#endif
 #ifdef I915_HAVE_GEM
-       DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
        DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
        DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
@@ -1268,11 +1015,3 @@ int i915_driver_device_is_agp(struct drm_device * dev)
 {
        return 1;
 }
-
-int i915_driver_firstopen(struct drm_device *dev)
-{
-#ifdef I915_HAVE_BUFFER
-       drm_bo_driver_init(dev);
-#endif
-       return 0;
-}
index 0c9ebbf..97e6fe2 100644 (file)
@@ -30,6 +30,8 @@
 #ifndef _I915_DRV_H_
 #define _I915_DRV_H_
 
+#include "i915_reg.h"
+
 /* General customization:
  */
 
 #define DRIVER_DESC            "Intel Graphics"
 #define DRIVER_DATE            "20080730"
 
-#if defined(__linux__)
-#define I915_HAVE_FENCE
-#define I915_HAVE_BUFFER
-#define I915_HAVE_GEM
-#endif
+enum pipe {
+       PIPE_A = 0,
+       PIPE_B,
+};
 
 /* Interface history:
  *
  * 1.5: Add vblank pipe configuration
  * 1.6: - New ioctl for scheduling buffer swaps on vertical blank
  *      - Support vertical blank on secondary display pipe
- * 1.8: New ioctl for ARB_Occlusion_Query
- * 1.9: Usable page flipping and triple buffering
- * 1.10: Plane/pipe disentangling
- * 1.11: TTM superioctl
- * 1.12: TTM relocation optimization
  */
 #define DRIVER_MAJOR           1
-#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER)
-#define DRIVER_MINOR           13
-#else
 #define DRIVER_MINOR           6
-#endif
 #define DRIVER_PATCHLEVEL      0
 
-enum pipe {
-    PIPE_A = 0,
-    PIPE_B,
-};
-
-#ifdef I915_HAVE_BUFFER
-#define I915_MAX_VALIDATE_BUFFERS 4096
-struct drm_i915_validate_buffer;
-#endif
-
 #define WATCH_COHERENCY        0
 #define WATCH_BUF      0
 #define WATCH_EXEC     0
@@ -105,15 +87,6 @@ struct mem_block {
        struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
 };
 
-typedef struct _drm_i915_vbl_swap {
-       struct list_head head;
-       drm_drawable_t drw_id;
-       unsigned int plane;
-       unsigned int sequence;
-       int flip;
-} drm_i915_vbl_swap_t;
-
-#ifdef __linux__
 struct opregion_header;
 struct opregion_acpi;
 struct opregion_swsci;
@@ -124,10 +97,8 @@ struct intel_opregion {
        struct opregion_acpi *acpi;
        struct opregion_swsci *swsci;
        struct opregion_asle *asle;
-
        int enabled;
 };
-#endif
 
 typedef struct drm_i915_private {
        struct drm_device *dev;
@@ -147,43 +118,28 @@ typedef struct drm_i915_private {
        struct drm_gem_object *hws_obj;
 
        unsigned int cpp;
+       int back_offset;
+       int front_offset;
+       int current_page;
+       int page_flipping;
 
        wait_queue_head_t irq_queue;
        atomic_t irq_received;
+       /** Protects user_irq_refcount and irq_mask_reg */
+       DRM_SPINTYPE user_irq_lock;
+       /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
+       int user_irq_refcount;
+       /** Cached value of IER to avoid reads in updating the bitfield */
+       u32 irq_mask_reg;
+       u32 pipestat[2];
 
        int tex_lru_log_granularity;
        int allow_batchbuffer;
        struct mem_block *agp_heap;
        unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
        int vblank_pipe;
-       DRM_SPINTYPE user_irq_lock;
-       int user_irq_refcount;
-       int fence_irq_on;
-       uint32_t irq_mask_reg;
-       int irq_enabled;
-
-#ifdef I915_HAVE_FENCE
-       uint32_t flush_sequence;
-       uint32_t flush_flags;
-       uint32_t flush_pending;
-       uint32_t saved_flush_status;
-#endif
-#ifdef I915_HAVE_BUFFER
-       void *agp_iomap;
-       unsigned int max_validate_buffers;
-       struct mutex cmdbuf_mutex;
-       struct drm_i915_validate_buffer *val_bufs;
-#endif
-
-#if defined(I915_HAVE_BUFFER)
-       /* DRI2 sarea */
-       struct drm_buffer_object *sarea_bo;
-       struct drm_bo_kmap_obj sarea_kmap;
-#endif
 
-#ifdef __linux__
        struct intel_opregion opregion;
-#endif
 
        /* Register state */
        u8 saveLBB;
@@ -273,7 +229,6 @@ typedef struct drm_i915_private {
        u8 saveDACMASK;
        u8 saveDACDATA[256*3]; /* 256 3-byte colors */
        u8 saveCR[37];
-
        struct {
 #ifdef __linux__
                struct drm_mm gtt_space;
@@ -358,13 +313,6 @@ typedef struct drm_i915_private {
        } mm;
 } drm_i915_private_t;
 
-struct drm_i915_file_private {
-       struct {
-               uint32_t last_gem_seqno;
-               uint32_t last_gem_throttle_seqno;
-       } mm;
-};
-
 enum intel_chip_family {
        CHIP_I8XX = 0x01,
        CHIP_I9XX = 0x02,
@@ -419,6 +367,9 @@ struct drm_i915_gem_object {
        /** Current tiling mode for the object. */
        uint32_t tiling_mode;
 
+       /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
+       uint32_t agp_type;
+
        /**
         * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
         * GEM_DOMAIN_CPU is not in the object's read domain.
@@ -449,6 +400,13 @@ struct drm_i915_gem_request {
        struct list_head list;
 };
 
+struct drm_i915_file_private {
+       struct {
+               uint32_t last_gem_seqno;
+               uint32_t last_gem_throttle_seqno;
+       } mm;
+};
+
 extern struct drm_ioctl_desc i915_ioctls[];
 extern int i915_max_ioctl;
 
@@ -456,8 +414,8 @@ extern int i915_max_ioctl;
 extern void i915_kernel_lost_context(struct drm_device * dev);
 extern int i915_driver_load(struct drm_device *, unsigned long flags);
 extern int i915_driver_unload(struct drm_device *);
-extern void i915_driver_lastclose(struct drm_device * dev);
 extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
+extern void i915_driver_lastclose(struct drm_device * dev);
 extern void i915_driver_preclose(struct drm_device *dev,
                                 struct drm_file *file_priv);
 extern void i915_driver_postclose(struct drm_device *dev,
@@ -465,43 +423,38 @@ extern void i915_driver_postclose(struct drm_device *dev,
 extern int i915_driver_device_is_agp(struct drm_device * dev);
 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
                              unsigned long arg);
-extern void i915_emit_breadcrumb(struct drm_device *dev);
-extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);
-extern int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush);
-extern int i915_driver_firstopen(struct drm_device *dev);
-extern int i915_dispatch_batchbuffer(struct drm_device * dev,
-                                    drm_i915_batchbuffer_t * batch);
-extern int i915_quiescent(struct drm_device *dev);
-extern int i915_init_hardware_status(struct drm_device *dev);
-extern void i915_free_hardware_status(struct drm_device *dev);
-
-int i915_emit_box(struct drm_device * dev,
-                 struct drm_clip_rect __user * boxes,
-                 int i, int DR1, int DR4);
+extern int i915_emit_box(struct drm_device *dev,
+                        struct drm_clip_rect __user *boxes,
+                        int i, int DR1, int DR4);
 
 /* i915_irq.c */
 extern int i915_irq_emit(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
 extern int i915_irq_wait(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
+void i915_user_irq_get(struct drm_device *dev);
+void i915_user_irq_put(struct drm_device *dev);
 
 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
 extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern int i915_driver_irq_postinstall(struct drm_device * dev);
+extern int i915_driver_irq_postinstall(struct drm_device *dev);
 extern void i915_driver_irq_uninstall(struct drm_device * dev);
 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
-extern int i915_emit_irq(struct drm_device * dev);
-extern int i915_wait_irq(struct drm_device * dev, int irq_nr);
 extern int i915_enable_vblank(struct drm_device *dev, int crtc);
 extern void i915_disable_vblank(struct drm_device *dev, int crtc);
 extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
 extern int i915_vblank_swap(struct drm_device *dev, void *data,
                            struct drm_file *file_priv);
-extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
-extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
+
+void
+i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
+
+void
+i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
+
 
 /* i915_mem.c */
 extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -514,35 +467,8 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
                                 struct drm_file *file_priv);
 extern void i915_mem_takedown(struct mem_block **heap);
 extern void i915_mem_release(struct drm_device * dev,
-                            struct drm_file *file_priv,
-                            struct mem_block *heap);
-
-/* i915_suspend.c */
-extern int i915_save_state(struct drm_device *dev);
-extern int i915_restore_state(struct drm_device *dev);
-
-#ifdef I915_HAVE_FENCE
-/* i915_fence.c */
-extern void i915_fence_handler(struct drm_device *dev);
-extern void i915_invalidate_reported_sequence(struct drm_device *dev);
-
-#endif
-
-#ifdef I915_HAVE_BUFFER
-/* i915_buffer.c */
-extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev);
-extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass,
-                          uint32_t *type);
-extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
-extern int i915_init_mem_type(struct drm_device *dev, uint32_t type,
-                              struct drm_mem_type_manager *man);
-extern uint64_t i915_evict_flags(struct drm_buffer_object *bo);
-extern int i915_move(struct drm_buffer_object *bo, int evict,
-               int no_wait, struct drm_bo_mem_reg *new_mem);
-void i915_flush_ttm(struct drm_ttm *ttm);
-/* i915_execbuf.c */
-int i915_execbuffer(struct drm_device *dev, void *data,
-                                  struct drm_file *file_priv);
+                            struct drm_file *file_priv, struct mem_block *heap);
+#ifdef I915_HAVE_GEM
 /* i915_gem.c */
 int i915_gem_init_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
@@ -588,70 +514,66 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev);
 void i915_gem_retire_requests(struct drm_device *dev);
 void i915_gem_retire_work_handler(struct work_struct *work);
 void i915_gem_clflush_object(struct drm_gem_object *obj);
-#endif
 
 /* i915_gem_tiling.c */
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
 
 /* i915_gem_debug.c */
+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
+                         const char *where, uint32_t mark);
 #if WATCH_INACTIVE
 void i915_verify_inactive(struct drm_device *dev, char *file, int line);
 #else
-#define i915_verify_inactive(dev,file,line)
+#define i915_verify_inactive(dev, file, line)
 #endif
 void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
                          const char *where, uint32_t mark);
 void i915_dump_lru(struct drm_device *dev, const char *where);
+#endif /* I915_HAVE_GEM */
+
+/* i915_suspend.c */
+extern int i915_save_state(struct drm_device *dev);
+extern int i915_restore_state(struct drm_device *dev);
 
-#ifdef __linux__
 /* i915_opregion.c */
 extern int intel_opregion_init(struct drm_device *dev);
 extern void intel_opregion_free(struct drm_device *dev);
 extern void opregion_asle_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
-#endif
 
-#ifdef __linux__
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
-extern void intel_init_chipset_flush_compat(struct drm_device *dev);
-extern void intel_fini_chipset_flush_compat(struct drm_device *dev);
-#endif
+/**
+ * Lock test for when it's just for synchronization of ring access.
+ *
+ * In that case, we don't need to do it when GEM is initialized as nobody else
+ * has access to the ring.
+ */
+#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do {                        \
+       if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \
+               LOCK_TEST_WITH_RETURN(dev, file_priv);                  \
+} while (0)
+
+#if defined(__FreeBSD__)
+typedef boolean_t bool;
 #endif
 
-#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_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_READ8(reg)                DRM_READ8(dev_priv->mmio_map, (reg))
 #define I915_WRITE8(reg,val)   DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
 
-#if defined(__FreeBSD__)
-typedef boolean_t bool;
-#endif
-
 #define I915_VERBOSE 0
-#define I915_RING_VALIDATE 0
-
-#define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
 #define RING_LOCALS    unsigned int outring, ringmask, outcount; \
-                       volatile char *virt;
-
-#if I915_RING_VALIDATE
-void i915_ring_validate(struct drm_device *dev, const char *func, int line);
-#define I915_RING_DO_VALIDATE(dev) i915_ring_validate(dev, __FUNCTION__, __LINE__)
-#else
-#define I915_RING_DO_VALIDATE(dev)
-#endif
+                        volatile char *virt;
 
 #define BEGIN_LP_RING(n) do {                          \
        if (I915_VERBOSE)                               \
-               DRM_DEBUG("BEGIN_LP_RING(%d)\n",        \
-                                (n));                  \
-       I915_RING_DO_VALIDATE(dev);                     \
-       if (dev_priv->ring.space < (n)*4)                      \
-               i915_wait_ring(dev, (n)*4, __FUNCTION__);      \
+               DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n));  \
+       if (dev_priv->ring.space < (n)*4)               \
+               i915_wait_ring(dev, (n)*4, __func__);           \
        outcount = 0;                                   \
        outring = dev_priv->ring.tail;                  \
        ringmask = dev_priv->ring.tail_mask;            \
@@ -660,1420 +582,40 @@ void i915_ring_validate(struct drm_device *dev, const char *func, int line);
 
 #define OUT_RING(n) do {                                       \
        if (I915_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));      \
-       *(volatile unsigned int *)(virt + outring) = (n);               \
-       outcount++;                                             \
+       *(volatile unsigned int *)(virt + outring) = (n);       \
+        outcount++;                                            \
        outring += 4;                                           \
        outring &= ringmask;                                    \
 } while (0)
 
 #define ADVANCE_LP_RING() do {                                         \
        if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring);   \
-       I915_RING_DO_VALIDATE(dev);                                     \
        dev_priv->ring.tail = outring;                                  \
        dev_priv->ring.space -= outcount * 4;                           \
        I915_WRITE(PRB0_TAIL, outring);                 \
 } while(0)
 
-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
-
-#define BREADCRUMB_BITS 31
-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
-
-#define READ_BREADCRUMB(dev_priv)  (((volatile u32*)(dev_priv->hw_status_page))[5])
 /**
  * Reads a dword out of the status page, which is written to from the command
  * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
  * MI_STORE_DATA_IMM.
  *
  * The following dwords have a reserved meaning:
- * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
- * 4: ring 0 head pointer
- * 5: ring 1 head pointer (915-class)
- * 6: ring 2 head pointer (915-class)
+ * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
+ * 0x04: ring 0 head pointer
+ * 0x05: ring 1 head pointer (915-class)
+ * 0x06: ring 2 head pointer (915-class)
+ * 0x10-0x1b: Context status DWords (GM45)
+ * 0x1f: Last written status offset. (GM45)
  *
- * The area from dword 0x10 to 0x3ff is available for driver usage.
+ * The area from dword 0x20 to 0x3ff is available for driver usage.
  */
 #define READ_HWSP(dev_priv, reg)  (((volatile u32*)(dev_priv->hw_status_page))[reg])
-#define I915_GEM_HWS_INDEX             0x10
-
-/* MCH MMIO space */
-/** 915-945 and GM965 MCH register controlling DRAM channel access */
-#define DCC            0x200
-#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL             (0 << 0)
-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC    (1 << 0)
-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED   (2 << 0)
-#define DCC_ADDRESSING_MODE_MASK                       (3 << 0)
-#define DCC_CHANNEL_XOR_DISABLE                                (1 << 10)
-
-/** 965 MCH register controlling DRAM channel configuration */
-#define CHDECMISC              0x111
-#define CHDECMISC_FLEXMEMORY           (1 << 1)
-
-/*
- * The Bridge device's PCI config space has information about the
- * fb aperture size and the amount of pre-reserved memory.
- */
-#define INTEL_GMCH_CTRL                0x52
-#define INTEL_GMCH_ENABLED     0x4
-#define INTEL_GMCH_MEM_MASK    0x1
-#define INTEL_GMCH_MEM_64M     0x1
-#define INTEL_GMCH_MEM_128M    0
-
-#define INTEL_855_GMCH_GMS_MASK                (0x7 << 4)
-#define INTEL_855_GMCH_GMS_DISABLED    (0x0 << 4)
-#define INTEL_855_GMCH_GMS_STOLEN_1M   (0x1 << 4)
-#define INTEL_855_GMCH_GMS_STOLEN_4M   (0x2 << 4)
-#define INTEL_855_GMCH_GMS_STOLEN_8M   (0x3 << 4)
-#define INTEL_855_GMCH_GMS_STOLEN_16M  (0x4 << 4)
-#define INTEL_855_GMCH_GMS_STOLEN_32M  (0x5 << 4)
-
-#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
-#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
-
-/* PCI config space */
-
-#define HPLLCC 0xc0 /* 855 only */
-#define   GC_CLOCK_CONTROL_MASK                (3 << 0)
-#define   GC_CLOCK_133_200             (0 << 0)
-#define   GC_CLOCK_100_200             (1 << 0)
-#define   GC_CLOCK_100_133             (2 << 0)
-#define   GC_CLOCK_166_250             (3 << 0)
-#define GCFGC  0xf0 /* 915+ only */
-#define   GC_LOW_FREQUENCY_ENABLE      (1 << 7)
-#define   GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
-#define   GC_DISPLAY_CLOCK_333_MHZ     (4 << 4)
-#define   GC_DISPLAY_CLOCK_MASK                (7 << 4)
-#define LBB    0xf4
-
-/* VGA stuff */
-
-#define VGA_ST01_MDA 0x3ba
-#define VGA_ST01_CGA 0x3da
-
-#define VGA_MSR_WRITE 0x3c2
-#define VGA_MSR_READ 0x3cc
-#define   VGA_MSR_MEM_EN (1<<1)
-#define   VGA_MSR_CGA_MODE (1<<0)
-
-#define VGA_SR_INDEX 0x3c4
-#define VGA_SR_DATA 0x3c5
-
-#define VGA_AR_INDEX 0x3c0
-#define   VGA_AR_VID_EN (1<<5)
-#define VGA_AR_DATA_WRITE 0x3c0
-#define VGA_AR_DATA_READ 0x3c1
-
-#define VGA_GR_INDEX 0x3ce
-#define VGA_GR_DATA 0x3cf
-/* GR05 */
-#define   VGA_GR_MEM_READ_MODE_SHIFT 3
-#define     VGA_GR_MEM_READ_MODE_PLANE 1
-/* GR06 */
-#define   VGA_GR_MEM_MODE_MASK 0xc
-#define   VGA_GR_MEM_MODE_SHIFT 2
-#define   VGA_GR_MEM_A0000_AFFFF 0
-#define   VGA_GR_MEM_A0000_BFFFF 1
-#define   VGA_GR_MEM_B0000_B7FFF 2
-#define   VGA_GR_MEM_B0000_BFFFF 3
-
-#define VGA_DACMASK 0x3c6
-#define VGA_DACRX 0x3c7
-#define VGA_DACWX 0x3c8
-#define VGA_DACDATA 0x3c9
-
-#define VGA_CR_INDEX_MDA 0x3b4
-#define VGA_CR_DATA_MDA 0x3b5
-#define VGA_CR_INDEX_CGA 0x3d4
-#define VGA_CR_DATA_CGA 0x3d5
-
-/*
- * Memory interface instructions used by the kernel
- */
-#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
-
-#define MI_NOOP                        MI_INSTR(0, 0)
-#define MI_USER_INTERRUPT      MI_INSTR(0x02, 0)
-#define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
-#define   MI_WAIT_FOR_PLANE_B_FLIP      (1<<6)
-#define   MI_WAIT_FOR_PLANE_A_FLIP      (1<<2)
-#define   MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
-#define MI_FLUSH               MI_INSTR(0x04, 0)
-#define   MI_READ_FLUSH                (1 << 0)
-#define   MI_EXE_FLUSH         (1 << 1)
-#define   MI_NO_WRITE_FLUSH    (1 << 2)
-#define   MI_SCENE_COUNT       (1 << 3) /* just increment scene count */
-#define   MI_END_SCENE         (1 << 4) /* flush binner and incr scene count */
-#define MI_BATCH_BUFFER_END    MI_INSTR(0x0a, 0)
-#define MI_REPORT_HEAD         MI_INSTR(0x07, 0)
-#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
-#define MI_STORE_DWORD_IMM     MI_INSTR(0x20, 1)
-#define   MI_MEM_VIRTUAL       (1 << 22) /* 965+ only */
-#define MI_STORE_DWORD_INDEX   MI_INSTR(0x21, 1)
-#define   MI_STORE_DWORD_INDEX_SHIFT 2
-#define MI_LOAD_REGISTER_IMM   MI_INSTR(0x22, 1)
-#define MI_BATCH_BUFFER                MI_INSTR(0x30, 1)
-#define   MI_BATCH_NON_SECURE  (1)
-#define   MI_BATCH_NON_SECURE_I965 (1<<8)
-#define MI_BATCH_BUFFER_START  MI_INSTR(0x31, 0)
-
-/*
- * 3D instructions used by the kernel
- */
-#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
-
-#define GFX_OP_RASTER_RULES    ((0x3<<29)|(0x7<<24))
-#define GFX_OP_SCISSOR         ((0x3<<29)|(0x1c<<24)|(0x10<<19))
-#define   SC_UPDATE_SCISSOR       (0x1<<1)
-#define   SC_ENABLE_MASK          (0x1<<0)
-#define   SC_ENABLE               (0x1<<0)
-#define GFX_OP_LOAD_INDIRECT   ((0x3<<29)|(0x1d<<24)|(0x7<<16))
-#define GFX_OP_SCISSOR_INFO    ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
-#define   SCI_YMIN_MASK      (0xffff<<16)
-#define   SCI_XMIN_MASK      (0xffff<<0)
-#define   SCI_YMAX_MASK      (0xffff<<16)
-#define   SCI_XMAX_MASK      (0xffff<<0)
-#define GFX_OP_SCISSOR_ENABLE   ((0x3<<29)|(0x1c<<24)|(0x10<<19))
-#define GFX_OP_SCISSOR_RECT     ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
-#define GFX_OP_COLOR_FACTOR      ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
-#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
-#define GFX_OP_MAP_INFO          ((0x3<<29)|(0x1d<<24)|0x4)
-#define GFX_OP_DESTBUFFER_VARS   ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
-#define GFX_OP_DESTBUFFER_INFO  ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
-#define GFX_OP_DRAWRECT_INFO     ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
-#define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
-#define SRC_COPY_BLT_CMD                ((2<<29)|(0x43<<22)|4)
-#define XY_SRC_COPY_BLT_CMD            ((2<<29)|(0x53<<22)|6)
-#define XY_MONO_SRC_COPY_IMM_BLT       ((2<<29)|(0x71<<22)|5)
-#define XY_SRC_COPY_BLT_WRITE_ALPHA    (1<<21)
-#define XY_SRC_COPY_BLT_WRITE_RGB      (1<<20)
-#define   BLT_DEPTH_8                  (0<<24)
-#define   BLT_DEPTH_16_565             (1<<24)
-#define   BLT_DEPTH_16_1555            (2<<24)
-#define   BLT_DEPTH_32                 (3<<24)
-#define   BLT_ROP_GXCOPY               (0xcc<<16)
-#define XY_SRC_COPY_BLT_SRC_TILED      (1<<15) /* 965+ only */
-#define XY_SRC_COPY_BLT_DST_TILED      (1<<11) /* 965+ only */
-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
-#define   ASYNC_FLIP                (1<<22)
-#define   DISPLAY_PLANE_A           (0<<20)
-#define   DISPLAY_PLANE_B           (1<<20)
+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX)
+#define I915_GEM_HWS_INDEX             0x20
+#define I915_BREADCRUMB_INDEX          0x21
 
-/*
- * Instruction and interrupt control regs
- */
-
-#define PRB0_TAIL      0x02030
-#define PRB0_HEAD      0x02034
-#define PRB0_START     0x02038
-#define PRB0_CTL       0x0203c
-#define   TAIL_ADDR            0x001FFFF8
-#define   HEAD_WRAP_COUNT      0xFFE00000
-#define   HEAD_WRAP_ONE                0x00200000
-#define   HEAD_ADDR            0x001FFFFC
-#define   RING_NR_PAGES                0x001FF000
-#define   RING_REPORT_MASK     0x00000006
-#define   RING_REPORT_64K      0x00000002
-#define   RING_REPORT_128K     0x00000004
-#define   RING_NO_REPORT       0x00000000
-#define   RING_VALID_MASK      0x00000001
-#define   RING_VALID           0x00000001
-#define   RING_INVALID         0x00000000
-#define PRB1_TAIL      0x02040 /* 915+ only */
-#define PRB1_HEAD      0x02044 /* 915+ only */
-#define PRB1_START     0x02048 /* 915+ only */
-#define PRB1_CTL       0x0204c /* 915+ only */
-#define ACTHD_I965     0x02074
-#define HWS_PGA                0x02080
-#define HWS_ADDRESS_MASK       0xfffff000
-#define HWS_START_ADDRESS_SHIFT        4
-#define IPEIR          0x02088
-#define NOPID          0x02094
-#define HWSTAM         0x02098
-#define SCPD0          0x0209c /* 915+ only */
-#define IER            0x020a0
-#define IIR            0x020a4
-#define IMR            0x020a8
-#define ISR            0x020ac
-#define   I915_PIPE_CONTROL_NOTIFY_INTERRUPT           (1<<18)
-#define   I915_DISPLAY_PORT_INTERRUPT                  (1<<17)
-#define   I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT   (1<<15)
-#define   I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT     (1<<14)
-#define   I915_HWB_OOM_INTERRUPT                       (1<<13)
-#define   I915_SYNC_STATUS_INTERRUPT                   (1<<12)
-#define   I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT  (1<<11)
-#define   I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT  (1<<10)
-#define   I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT    (1<<9)
-#define   I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT  (1<<8)
-#define   I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT         (1<<7)
-#define   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT          (1<<6)
-#define   I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT         (1<<5)
-#define   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT          (1<<4)
-#define   I915_DEBUG_INTERRUPT                         (1<<2)
-#define   I915_USER_INTERRUPT                          (1<<1)
-#define   I915_ASLE_INTERRUPT                          (1<<0)
-#define EIR            0x020b0
-#define EMR            0x020b4
-#define ESR            0x020b8
-#define INSTPM         0x020c0
-#define ACTHD          0x020c8
-#define FW_BLC         0x020d8
-#define FW_BLC_SELF    0x020e0 /* 915+ only */
-#define MI_ARB_STATE   0x020e4 /* 915+ only */
-#define CACHE_MODE_0   0x02120 /* 915+ only */
-#define   CM0_MASK_SHIFT          16
-#define   CM0_IZ_OPT_DISABLE      (1<<6)
-#define   CM0_ZR_OPT_DISABLE      (1<<5)
-#define   CM0_DEPTH_EVICT_DISABLE (1<<4)
-#define   CM0_COLOR_EVICT_DISABLE (1<<3)
-#define   CM0_DEPTH_WRITE_DISABLE (1<<1)
-#define   CM0_RC_OP_FLUSH_DISABLE (1<<0)
-#define GFX_FLSH_CNTL  0x02170 /* 915+ only */
-
-/*
- * Framebuffer compression (915+ only)
- */
-
-#define FBC_CFB_BASE           0x03200 /* 4k page aligned */
-#define FBC_LL_BASE            0x03204 /* 4k page aligned */
-#define FBC_CONTROL            0x03208
-#define   FBC_CTL_EN           (1<<31)
-#define   FBC_CTL_PERIODIC     (1<<30)
-#define   FBC_CTL_INTERVAL_SHIFT (16)
-#define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
-#define   FBC_CTL_STRIDE_SHIFT (5)
-#define   FBC_CTL_FENCENO      (1<<0)
-#define FBC_COMMAND            0x0320c
-#define   FBC_CMD_COMPRESS     (1<<0)
-#define FBC_STATUS             0x03210
-#define   FBC_STAT_COMPRESSING (1<<31)
-#define   FBC_STAT_COMPRESSED  (1<<30)
-#define   FBC_STAT_MODIFIED    (1<<29)
-#define   FBC_STAT_CURRENT_LINE        (1<<0)
-#define FBC_CONTROL2           0x03214
-#define   FBC_CTL_FENCE_DBL    (0<<4)
-#define   FBC_CTL_IDLE_IMM     (0<<2)
-#define   FBC_CTL_IDLE_FULL    (1<<2)
-#define   FBC_CTL_IDLE_LINE    (2<<2)
-#define   FBC_CTL_IDLE_DEBUG   (3<<2)
-#define   FBC_CTL_CPU_FENCE    (1<<1)
-#define   FBC_CTL_PLANEA       (0<<0)
-#define   FBC_CTL_PLANEB       (1<<0)
-#define FBC_FENCE_OFF          0x0321b
-
-#define FBC_LL_SIZE            (1536)
-
-/*
- * GPIO regs
- */
-#define GPIOA                  0x5010
-#define GPIOB                  0x5014
-#define GPIOC                  0x5018
-#define GPIOD                  0x501c
-#define GPIOE                  0x5020
-#define GPIOF                  0x5024
-#define GPIOG                  0x5028
-#define GPIOH                  0x502c
-# define GPIO_CLOCK_DIR_MASK           (1 << 0)
-# define GPIO_CLOCK_DIR_IN             (0 << 1)
-# define GPIO_CLOCK_DIR_OUT            (1 << 1)
-# define GPIO_CLOCK_VAL_MASK           (1 << 2)
-# define GPIO_CLOCK_VAL_OUT            (1 << 3)
-# define GPIO_CLOCK_VAL_IN             (1 << 4)
-# define GPIO_CLOCK_PULLUP_DISABLE     (1 << 5)
-# define GPIO_DATA_DIR_MASK            (1 << 8)
-# define GPIO_DATA_DIR_IN              (0 << 9)
-# define GPIO_DATA_DIR_OUT             (1 << 9)
-# define GPIO_DATA_VAL_MASK            (1 << 10)
-# define GPIO_DATA_VAL_OUT             (1 << 11)
-# define GPIO_DATA_VAL_IN              (1 << 12)
-# define GPIO_DATA_PULLUP_DISABLE      (1 << 13)
-
-/*
- * Clock control & power management
- */
-
-#define VGA0   0x6000
-#define VGA1   0x6004
-#define VGA_PD 0x6010
-#define   VGA0_PD_P2_DIV_4     (1 << 7)
-#define   VGA0_PD_P1_DIV_2     (1 << 5)
-#define   VGA0_PD_P1_SHIFT     0
-#define   VGA0_PD_P1_MASK      (0x1f << 0)
-#define   VGA1_PD_P2_DIV_4     (1 << 15)
-#define   VGA1_PD_P1_DIV_2     (1 << 13)
-#define   VGA1_PD_P1_SHIFT     8
-#define   VGA1_PD_P1_MASK      (0x1f << 8)
-#define DPLL_A 0x06014
-#define DPLL_B 0x06018
-#define   DPLL_VCO_ENABLE              (1 << 31)
-#define   DPLL_DVO_HIGH_SPEED          (1 << 30)
-#define   DPLL_SYNCLOCK_ENABLE         (1 << 29)
-#define   DPLL_VGA_MODE_DIS            (1 << 28)
-#define   DPLLB_MODE_DAC_SERIAL                (1 << 26) /* i915 */
-#define   DPLLB_MODE_LVDS              (2 << 26) /* i915 */
-#define   DPLL_MODE_MASK               (3 << 26)
-#define   DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
-#define   DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
-#define   DPLLB_LVDS_P2_CLOCK_DIV_14   (0 << 24) /* i915 */
-#define   DPLLB_LVDS_P2_CLOCK_DIV_7    (1 << 24) /* i915 */
-#define   DPLL_P2_CLOCK_DIV_MASK       0x03000000 /* i915 */
-#define   DPLL_FPA01_P1_POST_DIV_MASK  0x00ff0000 /* i915 */
-
-#define I915_FIFO_UNDERRUN_STATUS              (1UL<<31)
-#define I915_CRC_ERROR_ENABLE                  (1UL<<29)
-#define I915_CRC_DONE_ENABLE                   (1UL<<28)
-#define I915_GMBUS_EVENT_ENABLE                        (1UL<<27)
-#define I915_VSYNC_INTERRUPT_ENABLE            (1UL<<25)
-#define I915_DISPLAY_LINE_COMPARE_ENABLE       (1UL<<24)
-#define I915_DPST_EVENT_ENABLE                 (1UL<<23)
-#define I915_LEGACY_BLC_EVENT_ENABLE           (1UL<<22)
-#define I915_ODD_FIELD_INTERRUPT_ENABLE                (1UL<<21)
-#define I915_EVEN_FIELD_INTERRUPT_ENABLE       (1UL<<20)
-#define I915_START_VBLANK_INTERRUPT_ENABLE     (1UL<<18)       /* 965 or later */
-#define I915_VBLANK_INTERRUPT_ENABLE           (1UL<<17)
-#define I915_OVERLAY_UPDATED_ENABLE            (1UL<<16)
-#define I915_CRC_ERROR_INTERRUPT_STATUS                (1UL<<13)
-#define I915_CRC_DONE_INTERRUPT_STATUS         (1UL<<12)
-#define I915_GMBUS_INTERRUPT_STATUS            (1UL<<11)
-#define I915_VSYNC_INTERRUPT_STATUS            (1UL<<9)
-#define I915_DISPLAY_LINE_COMPARE_STATUS       (1UL<<8)
-#define I915_DPST_EVENT_STATUS                 (1UL<<7)
-#define I915_LEGACY_BLC_EVENT_STATUS           (1UL<<6)
-#define I915_ODD_FIELD_INTERRUPT_STATUS                (1UL<<5)
-#define I915_EVEN_FIELD_INTERRUPT_STATUS       (1UL<<4)
-#define I915_START_VBLANK_INTERRUPT_STATUS     (1UL<<2)        /* 965 or later */
-#define I915_VBLANK_INTERRUPT_STATUS           (1UL<<1)
-#define I915_OVERLAY_UPDATED_STATUS            (1UL<<0)
-
-#define SRX_INDEX              0x3c4
-#define SRX_DATA               0x3c5
-#define SR01                   1
-#define SR01_SCREEN_OFF                (1<<5)
-
-#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 ADPA_DPMS_SUSPEND      (1<<10)
-#define ADPA_DPMS_STANDBY      (2<<10)
-#define ADPA_DPMS_OFF          (3<<10)
-
-#define RING_TAIL              0x00
-#define TAIL_ADDR              0x001FFFF8
-#define RING_HEAD              0x04
-#define HEAD_WRAP_COUNT                0xFFE00000
-#define HEAD_WRAP_ONE          0x00200000
-#define HEAD_ADDR              0x001FFFFC
-#define RING_START             0x08
-#define START_ADDR             0xFFFFF000
-#define RING_LEN               0x0C
-#define RING_NR_PAGES          0x001FF000
-#define RING_REPORT_MASK       0x00000006
-#define RING_REPORT_64K                0x00000002
-#define RING_REPORT_128K       0x00000004
-#define RING_NO_REPORT         0x00000000
-#define RING_VALID_MASK                0x00000001
-#define RING_VALID             0x00000001
-#define RING_INVALID           0x00000000
-
-/* Scratch pad debug 0 reg:
- */
-#define   DPLL_FPA01_P1_POST_DIV_MASK_I830     0x001f0000
-/*
- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
- * this field (only one bit may be set).
- */
-#define   DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS        0x003f0000
-#define   DPLL_FPA01_P1_POST_DIV_SHIFT 16
-/* i830, required in DVO non-gang */
-#define   PLL_P2_DIVIDE_BY_4           (1 << 23)
-#define   PLL_P1_DIVIDE_BY_TWO         (1 << 21) /* i830 */
-#define   PLL_REF_INPUT_DREFCLK                (0 << 13)
-#define   PLL_REF_INPUT_TVCLKINA       (1 << 13) /* i830 */
-#define   PLL_REF_INPUT_TVCLKINBC      (2 << 13) /* SDVO TVCLKIN */
-#define   PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
-#define   PLL_REF_INPUT_MASK           (3 << 13)
-#define   PLL_LOAD_PULSE_PHASE_SHIFT           9
-/*
- * Parallel to Serial Load Pulse phase selection.
- * Selects the phase for the 10X DPLL clock for the PCIe
- * digital display port. The range is 4 to 13; 10 or more
- * is just a flip delay. The default is 6
- */
-#define   PLL_LOAD_PULSE_PHASE_MASK            (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
-#define   DISPLAY_RATE_SELECT_FPA1             (1 << 8)
-/*
- * SDVO multiplier for 945G/GM. Not used on 965.
- */
-#define   SDVO_MULTIPLIER_MASK                 0x000000ff
-#define   SDVO_MULTIPLIER_SHIFT_HIRES          4
-#define   SDVO_MULTIPLIER_SHIFT_VGA            0
-#define DPLL_A_MD 0x0601c /* 965+ only */
-/*
- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
- *
- * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
- */
-#define   DPLL_MD_UDI_DIVIDER_MASK             0x3f000000
-#define   DPLL_MD_UDI_DIVIDER_SHIFT            24
-/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
-#define   DPLL_MD_VGA_UDI_DIVIDER_MASK         0x003f0000
-#define   DPLL_MD_VGA_UDI_DIVIDER_SHIFT                16
-/*
- * SDVO/UDI pixel multiplier.
- *
- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
- * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
- * dummy bytes in the datastream at an increased clock rate, with both sides of
- * the link knowing how many bytes are fill.
- *
- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
- * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
- * through an SDVO command.
- *
- * This register field has values of multiplication factor minus 1, with
- * a maximum multiplier of 5 for SDVO.
- */
-#define   DPLL_MD_UDI_MULTIPLIER_MASK          0x00003f00
-#define   DPLL_MD_UDI_MULTIPLIER_SHIFT         8
-/*
- * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
- * This best be set to the default value (3) or the CRT won't work. No,
- * I don't entirely understand what this does...
- */
-#define   DPLL_MD_VGA_UDI_MULTIPLIER_MASK      0x0000003f
-#define   DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT     0
-#define DPLL_B_MD 0x06020 /* 965+ only */
-#define FPA0   0x06040
-#define FPA1   0x06044
-#define FPB0   0x06048
-#define FPB1   0x0604c
-#define   FP_N_DIV_MASK                0x003f0000
-#define   FP_N_DIV_SHIFT               16
-#define   FP_M1_DIV_MASK       0x00003f00
-#define   FP_M1_DIV_SHIFT               8
-#define   FP_M2_DIV_MASK       0x0000003f
-#define   FP_M2_DIV_SHIFT               0
-#define DPLL_TEST      0x606c
-#define   DPLLB_TEST_SDVO_DIV_1                (0 << 22)
-#define   DPLLB_TEST_SDVO_DIV_2                (1 << 22)
-#define   DPLLB_TEST_SDVO_DIV_4                (2 << 22)
-#define   DPLLB_TEST_SDVO_DIV_MASK     (3 << 22)
-#define   DPLLB_TEST_N_BYPASS          (1 << 19)
-#define   DPLLB_TEST_M_BYPASS          (1 << 18)
-#define   DPLLB_INPUT_BUFFER_ENABLE    (1 << 16)
-#define   DPLLA_TEST_N_BYPASS          (1 << 3)
-#define   DPLLA_TEST_M_BYPASS          (1 << 2)
-#define   DPLLA_INPUT_BUFFER_ENABLE    (1 << 0)
-#define D_STATE                0x6104
-#define CG_2D_DIS      0x6200
-#define CG_3D_DIS      0x6204
-
-/*
- * Palette regs
- */
-
-#define PALETTE_A              0x0a000
-#define PALETTE_B              0x0a800
-
-/*
- * Overlay regs
- */
-
-#define OVADD                  0x30000
-#define DOVSTA                 0x30008
-#define OC_BUF                 (0x3<<20)
-#define OGAMC5                 0x30010
-#define OGAMC4                 0x30014
-#define OGAMC3                 0x30018
-#define OGAMC2                 0x3001c
-#define OGAMC1                 0x30020
-#define OGAMC0                 0x30024
-
-/*
- * Display engine regs
- */
-
-/* Pipe A timing regs */
-#define HTOTAL_A       0x60000
-#define HBLANK_A       0x60004
-#define HSYNC_A                0x60008
-#define VTOTAL_A       0x6000c
-#define VBLANK_A       0x60010
-#define VSYNC_A                0x60014
-#define PIPEASRC       0x6001c
-#define BCLRPAT_A      0x60020
-
-/* Pipe B timing regs */
-#define HTOTAL_B       0x61000
-#define HBLANK_B       0x61004
-#define HSYNC_B                0x61008
-#define VTOTAL_B       0x6100c
-#define VBLANK_B       0x61010
-#define VSYNC_B                0x61014
-#define PIPEBSRC       0x6101c
-#define BCLRPAT_B      0x61020
-
-/* VGA port control */
-#define ADPA                   0x61100
-#define   ADPA_DAC_ENABLE      (1<<31)
-#define   ADPA_DAC_DISABLE     0
-#define   ADPA_PIPE_SELECT_MASK        (1<<30)
-#define   ADPA_PIPE_A_SELECT   0
-#define   ADPA_PIPE_B_SELECT   (1<<30)
-#define   ADPA_USE_VGA_HVPOLARITY (1<<15)
-#define   ADPA_SETS_HVPOLARITY 0
-#define   ADPA_VSYNC_CNTL_DISABLE (1<<11)
-#define   ADPA_VSYNC_CNTL_ENABLE 0
-#define   ADPA_HSYNC_CNTL_DISABLE (1<<10)
-#define   ADPA_HSYNC_CNTL_ENABLE 0
-#define   ADPA_VSYNC_ACTIVE_HIGH (1<<4)
-#define   ADPA_VSYNC_ACTIVE_LOW        0
-#define   ADPA_HSYNC_ACTIVE_HIGH (1<<3)
-#define   ADPA_HSYNC_ACTIVE_LOW        0
-#define   ADPA_DPMS_MASK       (~(3<<10))
-#define   ADPA_DPMS_ON         (0<<10)
-#define   ADPA_DPMS_SUSPEND    (1<<10)
-#define   ADPA_DPMS_STANDBY    (2<<10)
-#define   ADPA_DPMS_OFF                (3<<10)
-
-/* Hotplug control (945+ only) */
-#define PORT_HOTPLUG_EN                0x61110
-#define   SDVOB_HOTPLUG_INT_EN                 (1 << 26)
-#define   SDVOC_HOTPLUG_INT_EN                 (1 << 25)
-#define   TV_HOTPLUG_INT_EN                    (1 << 18)
-#define   CRT_HOTPLUG_INT_EN                   (1 << 9)
-#define   CRT_HOTPLUG_FORCE_DETECT             (1 << 3)
-
-#define PORT_HOTPLUG_STAT      0x61114
-#define   CRT_HOTPLUG_INT_STATUS               (1 << 11)
-#define   TV_HOTPLUG_INT_STATUS                        (1 << 10)
-#define   CRT_HOTPLUG_MONITOR_MASK             (3 << 8)
-#define   CRT_HOTPLUG_MONITOR_COLOR            (3 << 8)
-#define   CRT_HOTPLUG_MONITOR_MONO             (2 << 8)
-#define   CRT_HOTPLUG_MONITOR_NONE             (0 << 8)
-#define   SDVOC_HOTPLUG_INT_STATUS             (1 << 7)
-#define   SDVOB_HOTPLUG_INT_STATUS             (1 << 6)
-
-/* SDVO port control */
-#define SDVOB                  0x61140
-#define SDVOC                  0x61160
-#define   SDVO_ENABLE          (1 << 31)
-#define   SDVO_PIPE_B_SELECT   (1 << 30)
-#define   SDVO_STALL_SELECT    (1 << 29)
-#define   SDVO_INTERRUPT_ENABLE        (1 << 26)
-/**
- * 915G/GM SDVO pixel multiplier.
- *
- * Programmed value is multiplier - 1, up to 5x.
- *
- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
- */
-#define   SDVO_PORT_MULTIPLY_MASK      (7 << 23)
-#define   SDVO_PORT_MULTIPLY_SHIFT             23
-#define   SDVO_PHASE_SELECT_MASK       (15 << 19)
-#define   SDVO_PHASE_SELECT_DEFAULT    (6 << 19)
-#define   SDVO_CLOCK_OUTPUT_INVERT     (1 << 18)
-#define   SDVOC_GANG_MODE              (1 << 16)
-#define   SDVO_BORDER_ENABLE           (1 << 7)
-#define   SDVOB_PCIE_CONCURRENCY       (1 << 3)
-#define   SDVO_DETECTED                        (1 << 2)
-/* Bits to be preserved when writing */
-#define   SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
-#define   SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
-
-/* DVO port control */
-#define DVOA                   0x61120
-#define DVOB                   0x61140
-#define DVOC                   0x61160
-#define   DVO_ENABLE                   (1 << 31)
-#define   DVO_PIPE_B_SELECT            (1 << 30)
-#define   DVO_PIPE_STALL_UNUSED                (0 << 28)
-#define   DVO_PIPE_STALL               (1 << 28)
-#define   DVO_PIPE_STALL_TV            (2 << 28)
-#define   DVO_PIPE_STALL_MASK          (3 << 28)
-#define   DVO_USE_VGA_SYNC             (1 << 15)
-#define   DVO_DATA_ORDER_I740          (0 << 14)
-#define   DVO_DATA_ORDER_FP            (1 << 14)
-#define   DVO_VSYNC_DISABLE            (1 << 11)
-#define   DVO_HSYNC_DISABLE            (1 << 10)
-#define   DVO_VSYNC_TRISTATE           (1 << 9)
-#define   DVO_HSYNC_TRISTATE           (1 << 8)
-#define   DVO_BORDER_ENABLE            (1 << 7)
-#define   DVO_DATA_ORDER_GBRG          (1 << 6)
-#define   DVO_DATA_ORDER_RGGB          (0 << 6)
-#define   DVO_DATA_ORDER_GBRG_ERRATA   (0 << 6)
-#define   DVO_DATA_ORDER_RGGB_ERRATA   (1 << 6)
-#define   DVO_VSYNC_ACTIVE_HIGH                (1 << 4)
-#define   DVO_HSYNC_ACTIVE_HIGH                (1 << 3)
-#define   DVO_BLANK_ACTIVE_HIGH                (1 << 2)
-#define   DVO_OUTPUT_CSTATE_PIXELS     (1 << 1)        /* SDG only */
-#define   DVO_OUTPUT_SOURCE_SIZE_PIXELS        (1 << 0)        /* SDG only */
-#define   DVO_PRESERVE_MASK            (0x7<<24)
-#define DVOA_SRCDIM            0x61124
-#define DVOB_SRCDIM            0x61144
-#define DVOC_SRCDIM            0x61164
-#define   DVO_SRCDIM_HORIZONTAL_SHIFT  12
-#define   DVO_SRCDIM_VERTICAL_SHIFT    0
-
-/* LVDS port control */
-#define LVDS                   0x61180
-/*
- * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
- * the DPLL semantics change when the LVDS is assigned to that pipe.
- */
-#define   LVDS_PORT_EN                 (1 << 31)
-/* Selects pipe B for LVDS data.  Must be set on pre-965. */
-#define   LVDS_PIPEB_SELECT            (1 << 30)
-/*
- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
- * pixel.
- */
-#define   LVDS_A0A2_CLKA_POWER_MASK    (3 << 8)
-#define   LVDS_A0A2_CLKA_POWER_DOWN    (0 << 8)
-#define   LVDS_A0A2_CLKA_POWER_UP      (3 << 8)
-/*
- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
- * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
- * on.
- */
-#define   LVDS_A3_POWER_MASK           (3 << 6)
-#define   LVDS_A3_POWER_DOWN           (0 << 6)
-#define   LVDS_A3_POWER_UP             (3 << 6)
-/*
- * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
- * is set.
- */
-#define   LVDS_CLKB_POWER_MASK         (3 << 4)
-#define   LVDS_CLKB_POWER_DOWN         (0 << 4)
-#define   LVDS_CLKB_POWER_UP           (3 << 4)
-/*
- * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
- * setting for whether we are in dual-channel mode.  The B3 pair will
- * additionally only be powered up when LVDS_A3_POWER_UP is set.
- */
-#define   LVDS_B0B3_POWER_MASK         (3 << 2)
-#define   LVDS_B0B3_POWER_DOWN         (0 << 2)
-#define   LVDS_B0B3_POWER_UP           (3 << 2)
-
-/* Panel power sequencing */
-#define PP_STATUS      0x61200
-#define   PP_ON                (1 << 31)
-/*
- * Indicates that all dependencies of the panel are on:
- *
- * - PLL enabled
- * - pipe enabled
- * - LVDS/DVOB/DVOC on
- */
-#define   PP_READY             (1 << 30)
-#define   PP_SEQUENCE_NONE     (0 << 28)
-#define   PP_SEQUENCE_ON       (1 << 28)
-#define   PP_SEQUENCE_OFF      (2 << 28)
-#define   PP_SEQUENCE_MASK     0x30000000
-#define PP_CONTROL     0x61204
-#define   POWER_TARGET_ON      (1 << 0)
-#define PP_ON_DELAYS   0x61208
-#define PP_OFF_DELAYS  0x6120c
-#define PP_DIVISOR     0x61210
-
-/* Panel fitting */
-#define PFIT_CONTROL   0x61230
-#define   PFIT_ENABLE          (1 << 31)
-#define   PFIT_PIPE_MASK       (3 << 29)
-#define   PFIT_PIPE_SHIFT      29
-#define   VERT_INTERP_DISABLE  (0 << 10)
-#define   VERT_INTERP_BILINEAR (1 << 10)
-#define   VERT_INTERP_MASK     (3 << 10)
-#define   VERT_AUTO_SCALE      (1 << 9)
-#define   HORIZ_INTERP_DISABLE (0 << 6)
-#define   HORIZ_INTERP_BILINEAR        (1 << 6)
-#define   HORIZ_INTERP_MASK    (3 << 6)
-#define   HORIZ_AUTO_SCALE     (1 << 5)
-#define   PANEL_8TO6_DITHER_ENABLE (1 << 3)
-#define PFIT_PGM_RATIOS        0x61234
-#define   PFIT_VERT_SCALE_MASK                 0xfff00000
-#define   PFIT_HORIZ_SCALE_MASK                        0x0000fff0
-#define PFIT_AUTO_RATIOS 0x61238
-
-/* Backlight control */
-#define BLC_PWM_CTL            0x61254
-#define   BACKLIGHT_MODULATION_FREQ_SHIFT              (17)
-#define BLC_PWM_CTL2           0x61250 /* 965+ only */
-/*
- * This is the most significant 15 bits of the number of backlight cycles in a
- * complete cycle of the modulated backlight control.
- *
- * The actual value is this field multiplied by two.
- */
-#define   BACKLIGHT_MODULATION_FREQ_MASK               (0x7fff << 17)
-#define   BLM_LEGACY_MODE                              (1 << 16)
-/*
- * This is the number of cycles out of the backlight modulation cycle for which
- * the backlight is on.
- *
- * This field must be no greater than the number of cycles in the complete
- * backlight modulation cycle.
- */
-#define   BACKLIGHT_DUTY_CYCLE_SHIFT           (0)
-#define   BACKLIGHT_DUTY_CYCLE_MASK            (0xffff)
-
-/* TV port control */
-#define TV_CTL                 0x68000
-/** Enables the TV encoder */
-# define TV_ENC_ENABLE                 (1 << 31)
-/** Sources the TV encoder input from pipe B instead of A. */
-# define TV_ENC_PIPEB_SELECT           (1 << 30)
-/** Outputs composite video (DAC A only) */
-# define TV_ENC_OUTPUT_COMPOSITE       (0 << 28)
-/** Outputs SVideo video (DAC B/C) */
-# define TV_ENC_OUTPUT_SVIDEO          (1 << 28)
-/** Outputs Component video (DAC A/B/C) */
-# define TV_ENC_OUTPUT_COMPONENT       (2 << 28)
-/** Outputs Composite and SVideo (DAC A/B/C) */
-# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE        (3 << 28)
-# define TV_TRILEVEL_SYNC              (1 << 21)
-/** Enables slow sync generation (945GM only) */
-# define TV_SLOW_SYNC                  (1 << 20)
-/** Selects 4x oversampling for 480i and 576p */
-# define TV_OVERSAMPLE_4X              (0 << 18)
-/** Selects 2x oversampling for 720p and 1080i */
-# define TV_OVERSAMPLE_2X              (1 << 18)
-/** Selects no oversampling for 1080p */
-# define TV_OVERSAMPLE_NONE            (2 << 18)
-/** Selects 8x oversampling */
-# define TV_OVERSAMPLE_8X              (3 << 18)
-/** Selects progressive mode rather than interlaced */
-# define TV_PROGRESSIVE                        (1 << 17)
-/** Sets the colorburst to PAL mode.  Required for non-M PAL modes. */
-# define TV_PAL_BURST                  (1 << 16)
-/** Field for setting delay of Y compared to C */
-# define TV_YC_SKEW_MASK               (7 << 12)
-/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
-# define TV_ENC_SDP_FIX                        (1 << 11)
-/**
- * Enables a fix for the 915GM only.
- *
- * Not sure what it does.
- */
-# define TV_ENC_C0_FIX                 (1 << 10)
-/** Bits that must be preserved by software */
-# define TV_CTL_SAVE                   ((3 << 8) | (3 << 6))
-# define TV_FUSE_STATE_MASK            (3 << 4)
-/** Read-only state that reports all features enabled */
-# define TV_FUSE_STATE_ENABLED         (0 << 4)
-/** Read-only state that reports that Macrovision is disabled in hardware*/
-# define TV_FUSE_STATE_NO_MACROVISION  (1 << 4)
-/** Read-only state that reports that TV-out is disabled in hardware. */
-# define TV_FUSE_STATE_DISABLED                (2 << 4)
-/** Normal operation */
-# define TV_TEST_MODE_NORMAL           (0 << 0)
-/** Encoder test pattern 1 - combo pattern */
-# define TV_TEST_MODE_PATTERN_1                (1 << 0)
-/** Encoder test pattern 2 - full screen vertical 75% color bars */
-# define TV_TEST_MODE_PATTERN_2                (2 << 0)
-/** Encoder test pattern 3 - full screen horizontal 75% color bars */
-# define TV_TEST_MODE_PATTERN_3                (3 << 0)
-/** Encoder test pattern 4 - random noise */
-# define TV_TEST_MODE_PATTERN_4                (4 << 0)
-/** Encoder test pattern 5 - linear color ramps */
-# define TV_TEST_MODE_PATTERN_5                (5 << 0)
-/**
- * This test mode forces the DACs to 50% of full output.
- *
- * This is used for load detection in combination with TVDAC_SENSE_MASK
- */
-# define TV_TEST_MODE_MONITOR_DETECT   (7 << 0)
-# define TV_TEST_MODE_MASK             (7 << 0)
-
-#define TV_DAC                 0x68004
-/**
- * Reports that DAC state change logic has reported change (RO).
- *
- * This gets cleared when TV_DAC_STATE_EN is cleared
-*/
-# define TVDAC_STATE_CHG               (1 << 31)
-# define TVDAC_SENSE_MASK              (7 << 28)
-/** Reports that DAC A voltage is above the detect threshold */
-# define TVDAC_A_SENSE                 (1 << 30)
-/** Reports that DAC B voltage is above the detect threshold */
-# define TVDAC_B_SENSE                 (1 << 29)
-/** Reports that DAC C voltage is above the detect threshold */
-# define TVDAC_C_SENSE                 (1 << 28)
-/**
- * Enables DAC state detection logic, for load-based TV detection.
- *
- * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
- * to off, for load detection to work.
- */
-# define TVDAC_STATE_CHG_EN            (1 << 27)
-/** Sets the DAC A sense value to high */
-# define TVDAC_A_SENSE_CTL             (1 << 26)
-/** Sets the DAC B sense value to high */
-# define TVDAC_B_SENSE_CTL             (1 << 25)
-/** Sets the DAC C sense value to high */
-# define TVDAC_C_SENSE_CTL             (1 << 24)
-/** Overrides the ENC_ENABLE and DAC voltage levels */
-# define DAC_CTL_OVERRIDE              (1 << 7)
-/** Sets the slew rate.  Must be preserved in software */
-# define ENC_TVDAC_SLEW_FAST           (1 << 6)
-# define DAC_A_1_3_V                   (0 << 4)
-# define DAC_A_1_1_V                   (1 << 4)
-# define DAC_A_0_7_V                   (2 << 4)
-# define DAC_A_OFF                     (3 << 4)
-# define DAC_B_1_3_V                   (0 << 2)
-# define DAC_B_1_1_V                   (1 << 2)
-# define DAC_B_0_7_V                   (2 << 2)
-# define DAC_B_OFF                     (3 << 2)
-# define DAC_C_1_3_V                   (0 << 0)
-# define DAC_C_1_1_V                   (1 << 0)
-# define DAC_C_0_7_V                   (2 << 0)
-# define DAC_C_OFF                     (3 << 0)
-
-/**
- * CSC coefficients are stored in a floating point format with 9 bits of
- * mantissa and 2 or 3 bits of exponent.  The exponent is represented as 2**-n,
- * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
- * -1 (0x3) being the only legal negative value.
- */
-#define TV_CSC_Y               0x68010
-# define TV_RY_MASK                    0x07ff0000
-# define TV_RY_SHIFT                   16
-# define TV_GY_MASK                    0x00000fff
-# define TV_GY_SHIFT                   0
-
-#define TV_CSC_Y2              0x68014
-# define TV_BY_MASK                    0x07ff0000
-# define TV_BY_SHIFT                   16
-/**
- * Y attenuation for component video.
- *
- * Stored in 1.9 fixed point.
- */
-# define TV_AY_MASK                    0x000003ff
-# define TV_AY_SHIFT                   0
-
-#define TV_CSC_U               0x68018
-# define TV_RU_MASK                    0x07ff0000
-# define TV_RU_SHIFT                   16
-# define TV_GU_MASK                    0x000007ff
-# define TV_GU_SHIFT                   0
-
-#define TV_CSC_U2              0x6801c
-# define TV_BU_MASK                    0x07ff0000
-# define TV_BU_SHIFT                   16
-/**
- * U attenuation for component video.
- *
- * Stored in 1.9 fixed point.
- */
-# define TV_AU_MASK                    0x000003ff
-# define TV_AU_SHIFT                   0
-
-#define TV_CSC_V               0x68020
-# define TV_RV_MASK                    0x0fff0000
-# define TV_RV_SHIFT                   16
-# define TV_GV_MASK                    0x000007ff
-# define TV_GV_SHIFT                   0
-
-#define TV_CSC_V2              0x68024
-# define TV_BV_MASK                    0x07ff0000
-# define TV_BV_SHIFT                   16
-/**
- * V attenuation for component video.
- *
- * Stored in 1.9 fixed point.
- */
-# define TV_AV_MASK                    0x000007ff
-# define TV_AV_SHIFT                   0
-
-#define TV_CLR_KNOBS           0x68028
-/** 2s-complement brightness adjustment */
-# define TV_BRIGHTNESS_MASK            0xff000000
-# define TV_BRIGHTNESS_SHIFT           24
-/** Contrast adjustment, as a 2.6 unsigned floating point number */
-# define TV_CONTRAST_MASK              0x00ff0000
-# define TV_CONTRAST_SHIFT             16
-/** Saturation adjustment, as a 2.6 unsigned floating point number */
-# define TV_SATURATION_MASK            0x0000ff00
-# define TV_SATURATION_SHIFT           8
-/** Hue adjustment, as an integer phase angle in degrees */
-# define TV_HUE_MASK                   0x000000ff
-# define TV_HUE_SHIFT                  0
-
-#define TV_CLR_LEVEL           0x6802c
-/** Controls the DAC level for black */
-# define TV_BLACK_LEVEL_MASK           0x01ff0000
-# define TV_BLACK_LEVEL_SHIFT          16
-/** Controls the DAC level for blanking */
-# define TV_BLANK_LEVEL_MASK           0x000001ff
-# define TV_BLANK_LEVEL_SHIFT          0
-
-#define TV_H_CTL_1             0x68030
-/** Number of pixels in the hsync. */
-# define TV_HSYNC_END_MASK             0x1fff0000
-# define TV_HSYNC_END_SHIFT            16
-/** Total number of pixels minus one in the line (display and blanking). */
-# define TV_HTOTAL_MASK                        0x00001fff
-# define TV_HTOTAL_SHIFT               0
-
-#define TV_H_CTL_2             0x68034
-/** Enables the colorburst (needed for non-component color) */
-# define TV_BURST_ENA                  (1 << 31)
-/** Offset of the colorburst from the start of hsync, in pixels minus one. */
-# define TV_HBURST_START_SHIFT         16
-# define TV_HBURST_START_MASK          0x1fff0000
-/** Length of the colorburst */
-# define TV_HBURST_LEN_SHIFT           0
-# define TV_HBURST_LEN_MASK            0x0001fff
-
-#define TV_H_CTL_3             0x68038
-/** End of hblank, measured in pixels minus one from start of hsync */
-# define TV_HBLANK_END_SHIFT           16
-# define TV_HBLANK_END_MASK            0x1fff0000
-/** Start of hblank, measured in pixels minus one from start of hsync */
-# define TV_HBLANK_START_SHIFT         0
-# define TV_HBLANK_START_MASK          0x0001fff
-
-#define TV_V_CTL_1             0x6803c
-/** XXX */
-# define TV_NBR_END_SHIFT              16
-# define TV_NBR_END_MASK               0x07ff0000
-/** XXX */
-# define TV_VI_END_F1_SHIFT            8
-# define TV_VI_END_F1_MASK             0x00003f00
-/** XXX */
-# define TV_VI_END_F2_SHIFT            0
-# define TV_VI_END_F2_MASK             0x0000003f
-
-#define TV_V_CTL_2             0x68040
-/** Length of vsync, in half lines */
-# define TV_VSYNC_LEN_MASK             0x07ff0000
-# define TV_VSYNC_LEN_SHIFT            16
-/** Offset of the start of vsync in field 1, measured in one less than the
- * number of half lines.
- */
-# define TV_VSYNC_START_F1_MASK                0x00007f00
-# define TV_VSYNC_START_F1_SHIFT       8
-/**
- * Offset of the start of vsync in field 2, measured in one less than the
- * number of half lines.
- */
-# define TV_VSYNC_START_F2_MASK                0x0000007f
-# define TV_VSYNC_START_F2_SHIFT       0
-
-#define TV_V_CTL_3             0x68044
-/** Enables generation of the equalization signal */
-# define TV_EQUAL_ENA                  (1 << 31)
-/** Length of vsync, in half lines */
-# define TV_VEQ_LEN_MASK               0x007f0000
-# define TV_VEQ_LEN_SHIFT              16
-/** Offset of the start of equalization in field 1, measured in one less than
- * the number of half lines.
- */
-# define TV_VEQ_START_F1_MASK          0x0007f00
-# define TV_VEQ_START_F1_SHIFT         8
-/**
- * Offset of the start of equalization in field 2, measured in one less than
- * the number of half lines.
- */
-# define TV_VEQ_START_F2_MASK          0x000007f
-# define TV_VEQ_START_F2_SHIFT         0
-
-#define TV_V_CTL_4             0x68048
-/**
- * Offset to start of vertical colorburst, measured in one less than the
- * number of lines from vertical start.
- */
-# define TV_VBURST_START_F1_MASK       0x003f0000
-# define TV_VBURST_START_F1_SHIFT      16
-/**
- * Offset to the end of vertical colorburst, measured in one less than the
- * number of lines from the start of NBR.
- */
-# define TV_VBURST_END_F1_MASK         0x000000ff
-# define TV_VBURST_END_F1_SHIFT                0
-
-#define TV_V_CTL_5             0x6804c
-/**
- * Offset to start of vertical colorburst, measured in one less than the
- * number of lines from vertical start.
- */
-# define TV_VBURST_START_F2_MASK       0x003f0000
-# define TV_VBURST_START_F2_SHIFT      16
-/**
- * Offset to the end of vertical colorburst, measured in one less than the
- * number of lines from the start of NBR.
- */
-# define TV_VBURST_END_F2_MASK         0x000000ff
-# define TV_VBURST_END_F2_SHIFT                0
-
-#define TV_V_CTL_6             0x68050
-/**
- * Offset to start of vertical colorburst, measured in one less than the
- * number of lines from vertical start.
- */
-# define TV_VBURST_START_F3_MASK       0x003f0000
-# define TV_VBURST_START_F3_SHIFT      16
-/**
- * Offset to the end of vertical colorburst, measured in one less than the
- * number of lines from the start of NBR.
- */
-# define TV_VBURST_END_F3_MASK         0x000000ff
-# define TV_VBURST_END_F3_SHIFT                0
-
-#define TV_V_CTL_7             0x68054
-/**
- * Offset to start of vertical colorburst, measured in one less than the
- * number of lines from vertical start.
- */
-# define TV_VBURST_START_F4_MASK       0x003f0000
-# define TV_VBURST_START_F4_SHIFT      16
-/**
- * Offset to the end of vertical colorburst, measured in one less than the
- * number of lines from the start of NBR.
- */
-# define TV_VBURST_END_F4_MASK         0x000000ff
-# define TV_VBURST_END_F4_SHIFT                0
-
-#define TV_SC_CTL_1            0x68060
-/** Turns on the first subcarrier phase generation DDA */
-# define TV_SC_DDA1_EN                 (1 << 31)
-/** Turns on the first subcarrier phase generation DDA */
-# define TV_SC_DDA2_EN                 (1 << 30)
-/** Turns on the first subcarrier phase generation DDA */
-# define TV_SC_DDA3_EN                 (1 << 29)
-/** Sets the subcarrier DDA to reset frequency every other field */
-# define TV_SC_RESET_EVERY_2           (0 << 24)
-/** Sets the subcarrier DDA to reset frequency every fourth field */
-# define TV_SC_RESET_EVERY_4           (1 << 24)
-/** Sets the subcarrier DDA to reset frequency every eighth field */
-# define TV_SC_RESET_EVERY_8           (2 << 24)
-/** Sets the subcarrier DDA to never reset the frequency */
-# define TV_SC_RESET_NEVER             (3 << 24)
-/** Sets the peak amplitude of the colorburst.*/
-# define TV_BURST_LEVEL_MASK           0x00ff0000
-# define TV_BURST_LEVEL_SHIFT          16
-/** Sets the increment of the first subcarrier phase generation DDA */
-# define TV_SCDDA1_INC_MASK            0x00000fff
-# define TV_SCDDA1_INC_SHIFT           0
-
-#define TV_SC_CTL_2            0x68064
-/** Sets the rollover for the second subcarrier phase generation DDA */
-# define TV_SCDDA2_SIZE_MASK           0x7fff0000
-# define TV_SCDDA2_SIZE_SHIFT          16
-/** Sets the increent of the second subcarrier phase generation DDA */
-# define TV_SCDDA2_INC_MASK            0x00007fff
-# define TV_SCDDA2_INC_SHIFT           0
-
-#define TV_SC_CTL_3            0x68068
-/** Sets the rollover for the third subcarrier phase generation DDA */
-# define TV_SCDDA3_SIZE_MASK           0x7fff0000
-# define TV_SCDDA3_SIZE_SHIFT          16
-/** Sets the increent of the third subcarrier phase generation DDA */
-# define TV_SCDDA3_INC_MASK            0x00007fff
-# define TV_SCDDA3_INC_SHIFT           0
-
-#define TV_WIN_POS             0x68070
-/** X coordinate of the display from the start of horizontal active */
-# define TV_XPOS_MASK                  0x1fff0000
-# define TV_XPOS_SHIFT                 16
-/** Y coordinate of the display from the start of vertical active (NBR) */
-# define TV_YPOS_MASK                  0x00000fff
-# define TV_YPOS_SHIFT                 0
-
-#define TV_WIN_SIZE            0x68074
-/** Horizontal size of the display window, measured in pixels*/
-# define TV_XSIZE_MASK                 0x1fff0000
-# define TV_XSIZE_SHIFT                        16
-/**
- * Vertical size of the display window, measured in pixels.
- *
- * Must be even for interlaced modes.
- */
-# define TV_YSIZE_MASK                 0x00000fff
-# define TV_YSIZE_SHIFT                        0
-
-#define TV_FILTER_CTL_1                0x68080
-/**
- * Enables automatic scaling calculation.
- *
- * If set, the rest of the registers are ignored, and the calculated values can
- * be read back from the register.
- */
-# define TV_AUTO_SCALE                 (1 << 31)
-/**
- * Disables the vertical filter.
- *
- * This is required on modes more than 1024 pixels wide */
-# define TV_V_FILTER_BYPASS            (1 << 29)
-/** Enables adaptive vertical filtering */
-# define TV_VADAPT                     (1 << 28)
-# define TV_VADAPT_MODE_MASK           (3 << 26)
-/** Selects the least adaptive vertical filtering mode */
-# define TV_VADAPT_MODE_LEAST          (0 << 26)
-/** Selects the moderately adaptive vertical filtering mode */
-# define TV_VADAPT_MODE_MODERATE       (1 << 26)
-/** Selects the most adaptive vertical filtering mode */
-# define TV_VADAPT_MODE_MOST           (3 << 26)
-/**
- * Sets the horizontal scaling factor.
- *
- * This should be the fractional part of the horizontal scaling factor divided
- * by the oversampling rate.  TV_HSCALE should be less than 1, and set to:
- *
- * (src width - 1) / ((oversample * dest width) - 1)
- */
-# define TV_HSCALE_FRAC_MASK           0x00003fff
-# define TV_HSCALE_FRAC_SHIFT          0
-
-#define TV_FILTER_CTL_2                0x68084
-/**
- * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
- *
- * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
- */
-# define TV_VSCALE_INT_MASK            0x00038000
-# define TV_VSCALE_INT_SHIFT           15
-/**
- * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
- *
- * \sa TV_VSCALE_INT_MASK
- */
-# define TV_VSCALE_FRAC_MASK           0x00007fff
-# define TV_VSCALE_FRAC_SHIFT          0
-
-#define TV_FILTER_CTL_3                0x68088
-/**
- * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
- *
- * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
- *
- * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
- */
-# define TV_VSCALE_IP_INT_MASK         0x00038000
-# define TV_VSCALE_IP_INT_SHIFT                15
-/**
- * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
- *
- * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
- *
- * \sa TV_VSCALE_IP_INT_MASK
- */
-# define TV_VSCALE_IP_FRAC_MASK                0x00007fff
-# define TV_VSCALE_IP_FRAC_SHIFT               0
-
-#define TV_CC_CONTROL          0x68090
-# define TV_CC_ENABLE                  (1 << 31)
-/**
- * Specifies which field to send the CC data in.
- *
- * CC data is usually sent in field 0.
- */
-# define TV_CC_FID_MASK                        (1 << 27)
-# define TV_CC_FID_SHIFT               27
-/** Sets the horizontal position of the CC data.  Usually 135. */
-# define TV_CC_HOFF_MASK               0x03ff0000
-# define TV_CC_HOFF_SHIFT              16
-/** Sets the vertical position of the CC data.  Usually 21 */
-# define TV_CC_LINE_MASK               0x0000003f
-# define TV_CC_LINE_SHIFT              0
-
-#define TV_CC_DATA             0x68094
-# define TV_CC_RDY                     (1 << 31)
-/** Second word of CC data to be transmitted. */
-# define TV_CC_DATA_2_MASK             0x007f0000
-# define TV_CC_DATA_2_SHIFT            16
-/** First word of CC data to be transmitted. */
-# define TV_CC_DATA_1_MASK             0x0000007f
-# define TV_CC_DATA_1_SHIFT            0
-
-#define TV_H_LUMA_0            0x68100
-#define TV_H_LUMA_59           0x681ec
-#define TV_H_CHROMA_0          0x68200
-#define TV_H_CHROMA_59         0x682ec
-#define TV_V_LUMA_0            0x68300
-#define TV_V_LUMA_42           0x683a8
-#define TV_V_CHROMA_0          0x68400
-#define TV_V_CHROMA_42         0x684a8
-
-/* Display & cursor control */
-
-/* Pipe A */
-#define PIPEADSL               0x70000
-#define PIPEACONF               0x70008
-#define   PIPEACONF_ENABLE     (1<<31)
-#define   PIPEACONF_DISABLE    0
-#define   PIPEACONF_DOUBLE_WIDE        (1<<30)
-#define   I965_PIPECONF_ACTIVE (1<<30)
-#define   PIPEACONF_SINGLE_WIDE        0
-#define   PIPEACONF_PIPE_UNLOCKED 0
-#define   PIPEACONF_PIPE_LOCKED        (1<<25)
-#define   PIPEACONF_PALETTE    0
-#define   PIPEACONF_GAMMA              (1<<24)
-#define   PIPECONF_FORCE_BORDER        (1<<25)
-#define   PIPECONF_PROGRESSIVE (0 << 21)
-#define   PIPECONF_INTERLACE_W_FIELD_INDICATION        (6 << 21)
-#define   PIPECONF_INTERLACE_FIELD_0_ONLY              (7 << 21)
-#define PIPEASTAT              0x70024
-#define   PIPE_FIFO_UNDERRUN_STATUS            (1UL<<31)
-#define   PIPE_CRC_ERROR_ENABLE                        (1UL<<29)
-#define   PIPE_CRC_DONE_ENABLE                 (1UL<<28)
-#define   PIPE_GMBUS_EVENT_ENABLE              (1UL<<27)
-#define   PIPE_HOTPLUG_INTERRUPT_ENABLE                (1UL<<26)
-#define   PIPE_VSYNC_INTERRUPT_ENABLE          (1UL<<25)
-#define   PIPE_DISPLAY_LINE_COMPARE_ENABLE     (1UL<<24)
-#define   PIPE_DPST_EVENT_ENABLE               (1UL<<23)
-#define   PIPE_LEGACY_BLC_EVENT_ENABLE         (1UL<<22)
-#define   PIPE_ODD_FIELD_INTERRUPT_ENABLE      (1UL<<21)
-#define   PIPE_EVEN_FIELD_INTERRUPT_ENABLE     (1UL<<20)
-#define   PIPE_HOTPLUG_TV_INTERRUPT_ENABLE     (1UL<<18) /* pre-965 */
-#define   PIPE_START_VBLANK_INTERRUPT_ENABLE   (1UL<<18) /* 965 or later */
-#define   PIPE_VBLANK_INTERRUPT_ENABLE         (1UL<<17)
-#define   PIPE_OVERLAY_UPDATED_ENABLE          (1UL<<16)
-#define   PIPE_CRC_ERROR_INTERRUPT_STATUS      (1UL<<13)
-#define   PIPE_CRC_DONE_INTERRUPT_STATUS       (1UL<<12)
-#define   PIPE_GMBUS_INTERRUPT_STATUS          (1UL<<11)
-#define   PIPE_HOTPLUG_INTERRUPT_STATUS                (1UL<<10)
-#define   PIPE_VSYNC_INTERRUPT_STATUS          (1UL<<9)
-#define   PIPE_DISPLAY_LINE_COMPARE_STATUS     (1UL<<8)
-#define   PIPE_DPST_EVENT_STATUS               (1UL<<7)
-#define   PIPE_LEGACY_BLC_EVENT_STATUS         (1UL<<6)
-#define   PIPE_ODD_FIELD_INTERRUPT_STATUS      (1UL<<5)
-#define   PIPE_EVEN_FIELD_INTERRUPT_STATUS     (1UL<<4)
-#define   PIPE_HOTPLUG_TV_INTERRUPT_STATUS     (1UL<<2) /* pre-965 */
-#define   PIPE_START_VBLANK_INTERRUPT_STATUS   (1UL<<2) /* 965 or later */
-#define   PIPE_VBLANK_INTERRUPT_STATUS         (1UL<<1)
-#define   PIPE_OVERLAY_UPDATED_STATUS          (1UL<<0)
-
-#define DSPARB                 0x70030
-#define   DSPARB_CSTART_MASK   (0x7f << 7)
-#define   DSPARB_CSTART_SHIFT  7
-#define   DSPARB_BSTART_MASK   (0x7f)           
-#define   DSPARB_BSTART_SHIFT  0
-/*
- * The two pipe frame counter registers are not synchronized, so
- * reading a stable value is somewhat tricky. The following code 
- * should work:
- *
- *  do {
- *    high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
- *             PIPE_FRAME_HIGH_SHIFT;
- *    low1 =  ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
- *             PIPE_FRAME_LOW_SHIFT);
- *    high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
- *             PIPE_FRAME_HIGH_SHIFT);
- *  } while (high1 != high2);
- *  frame = (high1 << 8) | low1;
- */
-#define PIPEAFRAMEHIGH          0x70040
-#define   PIPE_FRAME_HIGH_MASK    0x0000ffff
-#define   PIPE_FRAME_HIGH_SHIFT   0
-#define PIPEAFRAMEPIXEL         0x70044
-#define   PIPE_FRAME_LOW_MASK     0xff000000
-#define   PIPE_FRAME_LOW_SHIFT    24
-#define   PIPE_PIXEL_MASK         0x00ffffff
-#define   PIPE_PIXEL_SHIFT        0
-
-/* Cursor A & B regs */
-#define CURACNTR               0x70080
-#define   CURSOR_MODE_DISABLE   0x00
-#define   CURSOR_MODE_64_32B_AX 0x07
-#define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
-#define   MCURSOR_GAMMA_ENABLE  (1 << 26)
-#define CURABASE               0x70084
-#define CURAPOS                        0x70088
-#define   CURSOR_POS_MASK       0x007FF
-#define   CURSOR_POS_SIGN       0x8000
-#define   CURSOR_X_SHIFT        0
-#define   CURSOR_Y_SHIFT        16
-#define CURBCNTR               0x700c0
-#define CURBBASE               0x700c4
-#define CURBPOS                        0x700c8
-
-/* Display A control */
-#define DSPACNTR                0x70180
-#define   DISPLAY_PLANE_ENABLE                 (1<<31)
-#define   DISPLAY_PLANE_DISABLE                        0
-#define   DISPPLANE_GAMMA_ENABLE               (1<<30)
-#define   DISPPLANE_GAMMA_DISABLE              0
-#define   DISPPLANE_PIXFORMAT_MASK             (0xf<<26)
-#define   DISPPLANE_8BPP                       (0x2<<26)
-#define   DISPPLANE_15_16BPP                   (0x4<<26)
-#define   DISPPLANE_16BPP                      (0x5<<26)
-#define   DISPPLANE_32BPP_NO_ALPHA             (0x6<<26)
-#define   DISPPLANE_32BPP                      (0x7<<26)
-#define   DISPPLANE_STEREO_ENABLE              (1<<25)
-#define   DISPPLANE_STEREO_DISABLE             0
-#define   DISPPLANE_SEL_PIPE_MASK              (1<<24)
-#define   DISPPLANE_SEL_PIPE_A                 0
-#define   DISPPLANE_SEL_PIPE_B                 (1<<24)
-#define   DISPPLANE_SRC_KEY_ENABLE             (1<<22)
-#define   DISPPLANE_SRC_KEY_DISABLE            0
-#define   DISPPLANE_LINE_DOUBLE                        (1<<20)
-#define   DISPPLANE_NO_LINE_DOUBLE             0
-#define   DISPPLANE_STEREO_POLARITY_FIRST      0
-#define   DISPPLANE_STEREO_POLARITY_SECOND     (1<<18)
-#define DSPAADDR               0x70184
-#define DSPASTRIDE             0x70188
-#define DSPAPOS                        0x7018C /* reserved */
-#define DSPASIZE               0x70190
-#define DSPASURF               0x7019C /* 965+ only */
-#define DSPATILEOFF            0x701A4 /* 965+ only */
-
-/* VBIOS flags */
-#define SWF00                  0x71410
-#define SWF01                  0x71414
-#define SWF02                  0x71418
-#define SWF03                  0x7141c
-#define SWF04                  0x71420
-#define SWF05                  0x71424
-#define SWF06                  0x71428
-#define SWF10                  0x70410
-#define SWF11                  0x70414
-#define SWF14                  0x71420
-#define SWF30                  0x72414
-#define SWF31                  0x72418
-#define SWF32                  0x7241c
-
-/* Pipe B */
-#define PIPEBDSL               0x71000
-#define PIPEBCONF              0x71008
-#define PIPEBSTAT              0x71024
-#define PIPEBFRAMEHIGH         0x71040
-#define PIPEBFRAMEPIXEL                0x71044
-
-/* Display B control */
-#define DSPBCNTR               0x71180
-#define   DISPPLANE_ALPHA_TRANS_ENABLE         (1<<15)
-#define   DISPPLANE_ALPHA_TRANS_DISABLE                0
-#define   DISPPLANE_SPRITE_ABOVE_DISPLAY       0
-#define   DISPPLANE_SPRITE_ABOVE_OVERLAY       (1)
-#define DSPBADDR               0x71184
-#define DSPBSTRIDE             0x71188
-#define DSPBPOS                        0x7118C
-#define DSPBSIZE               0x71190
-#define DSPBSURF               0x7119C
-#define DSPBTILEOFF            0x711A4
-
-/* VBIOS regs */
-#define VGACNTRL               0x71400
-# define VGA_DISP_DISABLE                      (1 << 31)
-# define VGA_2X_MODE                           (1 << 30)
-# define VGA_PIPE_B_SELECT                     (1 << 29)
-
-/* Chipset type macros */
+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
@@ -2117,4 +659,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
 
+#define PRIMARY_RINGBUFFER_SIZE         (128*1024)
+
 #endif
index 6764295..43dc024 100644 (file)
 
 #define MAX_NOPID ((u32)~0)
 
-/*
- * These are the interrupts used by the driver
+/**
+ * Interrupts that are always left unmasked.
+ * 
+ * Since pipe events are edge-triggered from the PIPESTAT register to IIR,
+ * we leave them always unmasked in IMR and then control enabling them through
+ * PIPESTAT alone.
  */
-#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
-                                   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
-                                   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+#define I915_INTERRUPT_ENABLE_FIX (I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
+                                  I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+
+/** Interrupts that we mask and unmask at runtime. */
+#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
+
+/** These are all of the interrupts used by the driver */
+#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
+                                   I915_INTERRUPT_ENABLE_VAR)
 
 static inline void
-i915_enable_irq(drm_i915_private_t *dev_priv, uint32_t mask)
+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
+       DRM_DEBUG("irq_enable_reg = 0x%08x, mask = 0x%08x\n",
+           dev_priv->irq_mask_reg, mask);
+       mask &= I915_INTERRUPT_ENABLE_VAR;
        if ((dev_priv->irq_mask_reg & mask) != 0) {
                dev_priv->irq_mask_reg &= ~mask;
                I915_WRITE(IMR, dev_priv->irq_mask_reg);
@@ -51,8 +64,9 @@ i915_enable_irq(drm_i915_private_t *dev_priv, uint32_t mask)
 }
 
 static inline void
-i915_disable_irq(drm_i915_private_t *dev_priv, uint32_t mask)
+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
+       mask &= I915_INTERRUPT_ENABLE_VAR;
        if ((dev_priv->irq_mask_reg & mask) != mask) {
                dev_priv->irq_mask_reg |= mask;
                I915_WRITE(IMR, dev_priv->irq_mask_reg);
@@ -60,43 +74,41 @@ i915_disable_irq(drm_i915_private_t *dev_priv, uint32_t mask)
        }
 }
 
-/**
- * i915_get_pipe - return the the pipe associated with a given plane
- * @dev: DRM device
- * @plane: plane to look for
- *
- * The Intel Mesa & 2D drivers call the vblank routines with a plane number
- * rather than a pipe number, since they may not always be equal.  This routine
- * maps the given @plane back to a pipe number.
- */
-static int
-i915_get_pipe(struct drm_device *dev, int plane)
+static inline u32
+i915_pipestat(int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 dspcntr;
+       if (pipe == 0)
+           return PIPEASTAT;
+       if (pipe == 1)
+           return PIPEBSTAT;
+       return -EINVAL;
+}
 
-       dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
+void
+i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
+{
+       if ((dev_priv->pipestat[pipe] & mask) != mask) {
+               u32 reg = i915_pipestat(pipe);
 
-       return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
+               dev_priv->pipestat[pipe] |= mask;
+               /* Enable the interrupt, clear any pending status */
+               I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16));
+               (void) I915_READ(reg);
+       }
 }
 
-/**
- * i915_get_plane - return the the plane associated with a given pipe
- * @dev: DRM device
- * @pipe: pipe to look for
- *
- * The Intel Mesa & 2D drivers call the vblank routines with a plane number
- * rather than a plane number, since they may not always be equal.  This routine
- * maps the given @pipe back to a plane number.
- */
-static int
-i915_get_plane(struct drm_device *dev, int pipe)
+void
+i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
 {
-       if (i915_get_pipe(dev, 0) == pipe)
-               return 0;
-       return 1;
-}
+       if ((dev_priv->pipestat[pipe] & mask) != 0) {
+               u32 reg = i915_pipestat(pipe);
 
+               dev_priv->pipestat[pipe] &= ~mask;
+               I915_WRITE(reg, dev_priv->pipestat[pipe]);
+               (void) I915_READ(reg);
+       }
+}
 /**
  * i915_pipe_enabled - check if a pipe is enabled
  * @dev: DRM device
@@ -118,21 +130,22 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
        return 0;
 }
 
-u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
+/* Called from drm generic code, passed a 'crtc', which
+ * we use as a pipe index
+ */
+u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long high_frame;
        unsigned long low_frame;
        u32 high1, high2, low, count;
-       int pipe;
 
-       pipe = i915_get_pipe(dev, plane);
        high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
        low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 
        if (!i915_pipe_enabled(dev, pipe)) {
-           DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
-           return 0;
+               DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+               return 0;
        }
 
        /*
@@ -158,104 +171,65 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 iir;
-       u32 pipea_stats = 0, pipeb_stats = 0;
-       int vblank = 0;
-#ifdef __linux__
-       if (dev->pdev->msi_enabled)
-               I915_WRITE(IMR, ~0);
-#endif
-       iir = I915_READ(IIR);
-#if 0
-       DRM_DEBUG("flag=%08x\n", iir);
-#endif
+       u32 iir, new_iir;
+       u32 pipea_stats, pipeb_stats;
+
        atomic_inc(&dev_priv->irq_received);
-       if (iir == 0) {
-#ifdef __linux__
-               if (dev->pdev->msi_enabled) {
-                       I915_WRITE(IMR, dev_priv->irq_mask_reg);
-                       (void) I915_READ(IMR);
-               }
-#endif
-               return IRQ_NONE;
-       }
 
-       /*
-        * Clear the PIPE(A|B)STAT regs before the IIR otherwise
-        * we may get extra interrupts.
-        */
-       if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
-               pipea_stats = I915_READ(PIPEASTAT);
-
-               /* The vblank interrupt gets enabled even if we didn't ask for
-                  it, so make sure it's shut down again */
-               if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
-                       pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                                        PIPE_VBLANK_INTERRUPT_ENABLE);
-               else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
-                                       PIPE_VBLANK_INTERRUPT_STATUS))
-               {
-                       vblank++;
-                       drm_handle_vblank(dev, i915_get_plane(dev, 0));
-               }
+       for (iir = I915_READ(IIR) ; iir != 0 ; iir = new_iir) {
 
-               I915_WRITE(PIPEASTAT, pipea_stats);
-       }
-       if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
-               pipeb_stats = I915_READ(PIPEBSTAT);
-
-               /* The vblank interrupt gets enabled even if we didn't ask for
-                  it, so make sure it's shut down again */
-               if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
-                       pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                                        PIPE_VBLANK_INTERRUPT_ENABLE);
-               else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
-                                       PIPE_VBLANK_INTERRUPT_STATUS))
-               {
-                       vblank++;
-                       drm_handle_vblank(dev, i915_get_plane(dev, 1));
+               pipea_stats = pipeb_stats = 0;
+
+               /*
+                * Clear the PIPE(A|B)STAT regs before the IIR
+                */
+               if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
+                       DRM_SPINLOCK(&dev_priv->user_irq_lock);
+                       pipea_stats = I915_READ(PIPEASTAT);
+                       I915_WRITE(PIPEASTAT, pipea_stats);
+                       DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
                }
 
-#ifdef __linux__
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
-               if (pipeb_stats & I915_LEGACY_BLC_EVENT_ENABLE)
-                       opregion_asle_intr(dev);
-#endif
-#endif
-               I915_WRITE(PIPEBSTAT, pipeb_stats);
-       }
+               if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
+                       DRM_SPINLOCK(&dev_priv->user_irq_lock);
+                       pipeb_stats = I915_READ(PIPEBSTAT);
+                       I915_WRITE(PIPEBSTAT, pipeb_stats);
+                       DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
+               }
 
-#ifdef __linux__
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
-       if (iir & I915_ASLE_INTERRUPT)
-               opregion_asle_intr(dev);
-#endif
-#endif
+               I915_WRITE(IIR, iir);
+               new_iir = I915_READ(IIR);
 
-       if (dev_priv->sarea_priv)
-           dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+               DRM_DEBUG("iir = 0x%08x, pipestats a = 0x%08x, b = 0x%08x\n",
+                   iir, pipea_stats, pipeb_stats);
 
-       I915_WRITE(IIR, iir);
-#ifdef __linux__
-       if (dev->pdev->msi_enabled)
-               I915_WRITE(IMR, dev_priv->irq_mask_reg);
-#endif
-       (void) I915_READ(IIR); /* Flush posted writes */
+               if (dev_priv->sarea_priv)
+                       dev_priv->sarea_priv->last_dispatch =
+                           READ_BREADCRUMB(dev_priv);
 
-       if (iir & I915_USER_INTERRUPT) {
+               if (iir & I915_USER_INTERRUPT) {
 #ifdef I915_HAVE_GEM
-               dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
+                       dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
 #endif
-               DRM_WAKEUP(&dev_priv->irq_queue);
-#ifdef I915_HAVE_FENCE
-               i915_fence_handler(dev);
+                       DRM_WAKEUP(&dev_priv->irq_queue);
+               }
+
+               if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS |
+                   PIPE_VBLANK_INTERRUPT_STATUS))
+                       drm_handle_vblank(dev, 0);
+
+               if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS |
+                   PIPE_VBLANK_INTERRUPT_STATUS))
+                       drm_handle_vblank(dev, 1);
+#ifdef __linux__
+               if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
+                   (iir & I915_ASLE_INTERRUPT))
+                       opregion_asle_intr(dev);
 #endif
        }
-
-       return IRQ_HANDLED;
 }
 
-int i915_emit_irq(struct drm_device *dev)
+static int i915_emit_irq(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
@@ -264,60 +238,71 @@ int i915_emit_irq(struct drm_device *dev)
 
        DRM_DEBUG("\n");
 
-       i915_emit_breadcrumb(dev);
+       dev_priv->counter++;
+       if (dev_priv->counter > 0x7FFFFFFFUL)
+               dev_priv->counter = 1;
+       if (dev_priv->sarea_priv)
+               dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
 
-       BEGIN_LP_RING(2);
-       OUT_RING(0);
+       BEGIN_LP_RING(4);
+       OUT_RING(MI_STORE_DWORD_INDEX);
+       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+       OUT_RING(dev_priv->counter);
        OUT_RING(MI_USER_INTERRUPT);
        ADVANCE_LP_RING();
 
        return dev_priv->counter;
 }
 
-void i915_user_irq_on(drm_i915_private_t *dev_priv)
+void i915_user_irq_get(struct drm_device *dev)
 {
-       DRM_SPINLOCK(&dev_priv->user_irq_lock);
-       if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1))
+       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
+
+       DRM_DEBUG("\n");
+       DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
+       if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
                i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
-       DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
+       DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
 }
 
-void i915_user_irq_off(drm_i915_private_t *dev_priv)
+void i915_user_irq_put(struct drm_device *dev)
 {
-       DRM_SPINLOCK(&dev_priv->user_irq_lock);
+       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
+
+       DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
 #ifdef __linux__
-       BUG_ON(dev_priv->irq_enabled && dev_priv->user_irq_refcount <= 0);
+       BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
 #endif
-       if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0))
+       if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
                i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
-       DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
+       DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
 }
 
-
-int i915_wait_irq(struct drm_device * dev, int irq_nr)
+static int i915_wait_irq(struct drm_device * dev, int irq_nr)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int ret = 0;
 
-       if (!dev_priv) {
-               DRM_ERROR("called with no initialization\n");
-               return -EINVAL;
-       }
-
        DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
                  READ_BREADCRUMB(dev_priv));
 
        if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
-               if (dev_priv->sarea_priv)
+               if (dev_priv->sarea_priv) {
                        dev_priv->sarea_priv->last_dispatch =
                                READ_BREADCRUMB(dev_priv);
+               }
                return 0;
        }
 
-       i915_user_irq_on(dev_priv);
+       if (dev_priv->sarea_priv)
+               dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+
+       i915_user_irq_get(dev);
        DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
                    READ_BREADCRUMB(dev_priv) >= irq_nr);
-       i915_user_irq_off(dev_priv);
+       i915_user_irq_put(dev);
 
        if (ret == -EBUSY) {
                DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
@@ -327,6 +312,7 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr)
        if (dev_priv->sarea_priv)
                dev_priv->sarea_priv->last_dispatch =
                        READ_BREADCRUMB(dev_priv);
+
        return ret;
 }
 
@@ -339,7 +325,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
        drm_i915_irq_emit_t *emit = data;
        int result;
 
-       LOCK_TEST_WITH_RETURN(dev, file_priv);
+       RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
 
        if (!dev_priv) {
                DRM_ERROR("called with no initialization\n");
@@ -359,7 +345,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
 /* Doesn't need the hardware lock.
  */
 int i915_irq_wait(struct drm_device *dev, void *data,
-                 struct drm_file *file_priv)
+                        struct drm_file *file_priv)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        drm_i915_irq_wait_t *irqwait = data;
@@ -372,112 +358,42 @@ int i915_irq_wait(struct drm_device *dev, void *data,
        return i915_wait_irq(dev, irqwait->irq_seq);
 }
 
-int i915_enable_vblank(struct drm_device *dev, int plane)
+/* Called from drm generic code, passed 'crtc' which
+ * we use as a pipe index
+ */
+int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       int pipe = i915_get_pipe(dev, plane);
-       u32     pipestat_reg = 0;
-       u32     mask_reg = 0;
-       u32     pipestat;
-
-       switch (pipe) {
-       case 0:
-               pipestat_reg = PIPEASTAT;
-               mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
-               break;
-       case 1:
-               pipestat_reg = PIPEBSTAT;
-               mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
-               break;
-       default:
-               DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
-                         pipe);
-               break;
-       }
-
-       if (pipestat_reg)
-       {
-               pipestat = I915_READ (pipestat_reg);
-               /*
-                * Older chips didn't have the start vblank interrupt,
-                * but 
-                */
-               if (IS_I965G (dev))
-                       pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
-               else
-                       pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
-               /*
-                * Clear any pending status
-                */
-               pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
-                            PIPE_VBLANK_INTERRUPT_STATUS);
-               I915_WRITE(pipestat_reg, pipestat);
-       }
-       DRM_SPINLOCK(&dev_priv->user_irq_lock);
-       i915_enable_irq(dev_priv, mask_reg);
-       DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
+       unsigned long irqflags;
+       u32 pipestat;
 
+       /*
+        * Older chips didn't have the start vblank interrupt,
+        * but
+        */
+       if (IS_I965G (dev))
+               pipestat = PIPE_START_VBLANK_INTERRUPT_ENABLE;
+       else
+               pipestat = PIPE_VBLANK_INTERRUPT_ENABLE;
+
+       DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
+       i915_enable_pipestat(dev_priv, pipe, pipestat);
+       DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
        return 0;
 }
 
-void i915_disable_vblank(struct drm_device *dev, int plane)
-{
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       int pipe = i915_get_pipe(dev, plane);
-       u32     pipestat_reg = 0;
-       u32     mask_reg = 0;
-       u32     pipestat;
-
-       switch (pipe) {
-       case 0:
-               pipestat_reg = PIPEASTAT;
-               mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
-               break;
-       case 1:
-               pipestat_reg = PIPEBSTAT;
-               mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
-               break;
-       default:
-               DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
-                         pipe);
-               break;
-       }
-
-       DRM_SPINLOCK(&dev_priv->user_irq_lock);
-       i915_disable_irq(dev_priv, mask_reg);
-       DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
-
-       if (pipestat_reg)
-       {
-               pipestat = I915_READ (pipestat_reg);
-               pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                             PIPE_VBLANK_INTERRUPT_ENABLE);
-               /*
-                * Clear any pending status
-                */
-               pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
-                            PIPE_VBLANK_INTERRUPT_STATUS);
-               I915_WRITE(pipestat_reg, pipestat);
-               (void) I915_READ(pipestat_reg);
-       }
-}
-
-static void i915_enable_interrupt (struct drm_device *dev)
+/* Called from drm generic code, passed 'crtc' which
+ * we use as a pipe index
+ */
+void i915_disable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       unsigned long irqflags;
 
-       dev_priv->irq_mask_reg = ~0;
-       I915_WRITE(IMR, dev_priv->irq_mask_reg);
-       I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
-       (void) I915_READ (IER);
-
-#ifdef __linux__
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
-       opregion_enable_asle(dev);
-#endif
-#endif
-
-       dev_priv->irq_enabled = 1;
+       DRM_SPINLOCK_IRQSAVE(&dev_priv->user_irq_lock, irqflags);
+       i915_disable_pipestat(dev_priv, pipe,
+           PIPE_START_VBLANK_INTERRUPT_ENABLE | PIPE_VBLANK_INTERRUPT_ENABLE);
+       DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->user_irq_lock, irqflags);
 }
 
 /* Set the vblank monitor pipe
@@ -542,55 +458,69 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
        I915_WRITE(HWSTAM, 0xeffe);
+       I915_WRITE(PIPEASTAT, 0);
+       I915_WRITE(PIPEBSTAT, 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
+       (void) I915_READ(IER);
 }
 
-int i915_driver_irq_postinstall(struct drm_device * dev)
+int i915_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int ret, num_pipes = 2;
 
-       dev_priv->user_irq_refcount = 0;
-       dev_priv->irq_mask_reg = ~0;
-
        ret = drm_vblank_init(dev, num_pipes);
        if (ret)
                return ret;
 
        dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
+
        dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
 
-       i915_enable_interrupt(dev);
+       /* Unmask the interrupts that we always want on. */
+       dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
+
+       dev_priv->pipestat[0] = 0;
+       dev_priv->pipestat[1] = 0;
+
+       /* Disable pipe interrupt enables, clear pending pipe status */
+       I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
+       I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
+
+       /* Clear pending interrupt status */
+       I915_WRITE(IIR, I915_READ(IIR));
+
+       I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+       I915_WRITE(IMR, dev_priv->irq_mask_reg);
+       (void) I915_READ(IER);
+#ifdef __linux__
+       opregion_enable_asle(dev);
+#endif
        DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
 
-       /*
-        * Initialize the hardware status page IRQ location.
-        */
+       i915_enable_vblank(dev, 0);
+       i915_enable_vblank(dev, 1);
 
-       I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
        return 0;
 }
 
 void i915_driver_irq_uninstall(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 temp;
 
        if (!dev_priv)
                return;
 
        dev_priv->vblank_pipe = 0;
 
-       dev_priv->irq_enabled = 0;
        I915_WRITE(HWSTAM, 0xffffffff);
+       I915_WRITE(PIPEASTAT, 0);
+       I915_WRITE(PIPEBSTAT, 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
 
-       temp = I915_READ(PIPEASTAT);
-       I915_WRITE(PIPEASTAT, temp);
-       temp = I915_READ(PIPEBSTAT);
-       I915_WRITE(PIPEBSTAT, temp);
-       temp = I915_READ(IIR);
-       I915_WRITE(IIR, temp);
+       I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
+       I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
+       I915_WRITE(IIR, I915_READ(IIR));
 }
diff --git a/shared-core/i915_reg.h b/shared-core/i915_reg.h
new file mode 100644 (file)
index 0000000..5c2d9f2
--- /dev/null
@@ -0,0 +1,1417 @@
+/* Copyright 2003 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, 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 TUNGSTEN GRAPHICS 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.
+ */
+
+#ifndef _I915_REG_H_
+#define _I915_REG_H_
+
+/*
+ * The Bridge device's PCI config space has information about the
+ * fb aperture size and the amount of pre-reserved memory.
+ */
+#define INTEL_GMCH_CTRL                0x52
+#define INTEL_GMCH_ENABLED     0x4
+#define INTEL_GMCH_MEM_MASK    0x1
+#define INTEL_GMCH_MEM_64M     0x1
+#define INTEL_GMCH_MEM_128M    0
+
+#define INTEL_855_GMCH_GMS_MASK                (0x7 << 4)
+#define INTEL_855_GMCH_GMS_DISABLED    (0x0 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_1M   (0x1 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_4M   (0x2 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_8M   (0x3 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_16M  (0x4 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_32M  (0x5 << 4)
+
+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
+
+/* PCI config space */
+
+#define HPLLCC 0xc0 /* 855 only */
+#define   GC_CLOCK_CONTROL_MASK                (3 << 0)
+#define   GC_CLOCK_133_200             (0 << 0)
+#define   GC_CLOCK_100_200             (1 << 0)
+#define   GC_CLOCK_100_133             (2 << 0)
+#define   GC_CLOCK_166_250             (3 << 0)
+#define GCFGC  0xf0 /* 915+ only */
+#define   GC_LOW_FREQUENCY_ENABLE      (1 << 7)
+#define   GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
+#define   GC_DISPLAY_CLOCK_333_MHZ     (4 << 4)
+#define   GC_DISPLAY_CLOCK_MASK                (7 << 4)
+#define LBB    0xf4
+
+/* VGA stuff */
+
+#define VGA_ST01_MDA 0x3ba
+#define VGA_ST01_CGA 0x3da
+
+#define VGA_MSR_WRITE 0x3c2
+#define VGA_MSR_READ 0x3cc
+#define   VGA_MSR_MEM_EN (1<<1)
+#define   VGA_MSR_CGA_MODE (1<<0)
+
+#define VGA_SR_INDEX 0x3c4
+#define VGA_SR_DATA 0x3c5
+
+#define VGA_AR_INDEX 0x3c0
+#define   VGA_AR_VID_EN (1<<5)
+#define VGA_AR_DATA_WRITE 0x3c0
+#define VGA_AR_DATA_READ 0x3c1
+
+#define VGA_GR_INDEX 0x3ce
+#define VGA_GR_DATA 0x3cf
+/* GR05 */
+#define   VGA_GR_MEM_READ_MODE_SHIFT 3
+#define     VGA_GR_MEM_READ_MODE_PLANE 1
+/* GR06 */
+#define   VGA_GR_MEM_MODE_MASK 0xc
+#define   VGA_GR_MEM_MODE_SHIFT 2
+#define   VGA_GR_MEM_A0000_AFFFF 0
+#define   VGA_GR_MEM_A0000_BFFFF 1
+#define   VGA_GR_MEM_B0000_B7FFF 2
+#define   VGA_GR_MEM_B0000_BFFFF 3
+
+#define VGA_DACMASK 0x3c6
+#define VGA_DACRX 0x3c7
+#define VGA_DACWX 0x3c8
+#define VGA_DACDATA 0x3c9
+
+#define VGA_CR_INDEX_MDA 0x3b4
+#define VGA_CR_DATA_MDA 0x3b5
+#define VGA_CR_INDEX_CGA 0x3d4
+#define VGA_CR_DATA_CGA 0x3d5
+
+/*
+ * Memory interface instructions used by the kernel
+ */
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+
+#define MI_NOOP                        MI_INSTR(0, 0)
+#define MI_USER_INTERRUPT      MI_INSTR(0x02, 0)
+#define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
+#define   MI_WAIT_FOR_PLANE_B_FLIP      (1<<6)
+#define   MI_WAIT_FOR_PLANE_A_FLIP      (1<<2)
+#define   MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
+#define MI_FLUSH               MI_INSTR(0x04, 0)
+#define   MI_READ_FLUSH                (1 << 0)
+#define   MI_EXE_FLUSH         (1 << 1)
+#define   MI_NO_WRITE_FLUSH    (1 << 2)
+#define   MI_SCENE_COUNT       (1 << 3) /* just increment scene count */
+#define   MI_END_SCENE         (1 << 4) /* flush binner and incr scene count */
+#define MI_BATCH_BUFFER_END    MI_INSTR(0x0a, 0)
+#define MI_REPORT_HEAD         MI_INSTR(0x07, 0)
+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
+#define MI_STORE_DWORD_IMM     MI_INSTR(0x20, 1)
+#define   MI_MEM_VIRTUAL       (1 << 22) /* 965+ only */
+#define MI_STORE_DWORD_INDEX   MI_INSTR(0x21, 1)
+#define   MI_STORE_DWORD_INDEX_SHIFT 2
+#define MI_LOAD_REGISTER_IMM   MI_INSTR(0x22, 1)
+#define MI_BATCH_BUFFER                MI_INSTR(0x30, 1)
+#define   MI_BATCH_NON_SECURE  (1)
+#define   MI_BATCH_NON_SECURE_I965 (1<<8)
+#define MI_BATCH_BUFFER_START  MI_INSTR(0x31, 0)
+
+/*
+ * 3D instructions used by the kernel
+ */
+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
+
+#define GFX_OP_RASTER_RULES    ((0x3<<29)|(0x7<<24))
+#define GFX_OP_SCISSOR         ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define   SC_UPDATE_SCISSOR       (0x1<<1)
+#define   SC_ENABLE_MASK          (0x1<<0)
+#define   SC_ENABLE               (0x1<<0)
+#define GFX_OP_LOAD_INDIRECT   ((0x3<<29)|(0x1d<<24)|(0x7<<16))
+#define GFX_OP_SCISSOR_INFO    ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define   SCI_YMIN_MASK      (0xffff<<16)
+#define   SCI_XMIN_MASK      (0xffff<<0)
+#define   SCI_YMAX_MASK      (0xffff<<16)
+#define   SCI_XMAX_MASK      (0xffff<<0)
+#define GFX_OP_SCISSOR_ENABLE   ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define GFX_OP_SCISSOR_RECT     ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
+#define GFX_OP_COLOR_FACTOR      ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define GFX_OP_MAP_INFO          ((0x3<<29)|(0x1d<<24)|0x4)
+#define GFX_OP_DESTBUFFER_VARS   ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define GFX_OP_DESTBUFFER_INFO  ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
+#define GFX_OP_DRAWRECT_INFO     ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2)
+#define SRC_COPY_BLT_CMD                ((2<<29)|(0x43<<22)|4)
+#define XY_SRC_COPY_BLT_CMD            ((2<<29)|(0x53<<22)|6)
+#define XY_MONO_SRC_COPY_IMM_BLT       ((2<<29)|(0x71<<22)|5)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA    (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB      (1<<20)
+#define   BLT_DEPTH_8                  (0<<24)
+#define   BLT_DEPTH_16_565             (1<<24)
+#define   BLT_DEPTH_16_1555            (2<<24)
+#define   BLT_DEPTH_32                 (3<<24)
+#define   BLT_ROP_GXCOPY               (0xcc<<16)
+#define XY_SRC_COPY_BLT_SRC_TILED      (1<<15) /* 965+ only */
+#define XY_SRC_COPY_BLT_DST_TILED      (1<<11) /* 965+ only */
+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
+#define   ASYNC_FLIP                (1<<22)
+#define   DISPLAY_PLANE_A           (0<<20)
+#define   DISPLAY_PLANE_B           (1<<20)
+
+/*
+ * Instruction and interrupt control regs
+ */
+
+#define PRB0_TAIL      0x02030
+#define PRB0_HEAD      0x02034
+#define PRB0_START     0x02038
+#define PRB0_CTL       0x0203c
+#define   TAIL_ADDR            0x001FFFF8
+#define   HEAD_WRAP_COUNT      0xFFE00000
+#define   HEAD_WRAP_ONE                0x00200000
+#define   HEAD_ADDR            0x001FFFFC
+#define   RING_NR_PAGES                0x001FF000
+#define   RING_REPORT_MASK     0x00000006
+#define   RING_REPORT_64K      0x00000002
+#define   RING_REPORT_128K     0x00000004
+#define   RING_NO_REPORT       0x00000000
+#define   RING_VALID_MASK      0x00000001
+#define   RING_VALID           0x00000001
+#define   RING_INVALID         0x00000000
+#define PRB1_TAIL      0x02040 /* 915+ only */
+#define PRB1_HEAD      0x02044 /* 915+ only */
+#define PRB1_START     0x02048 /* 915+ only */
+#define PRB1_CTL       0x0204c /* 915+ only */
+#define ACTHD_I965     0x02074
+#define HWS_PGA                0x02080
+#define HWS_ADDRESS_MASK       0xfffff000
+#define HWS_START_ADDRESS_SHIFT        4
+#define IPEIR          0x02088
+#define NOPID          0x02094
+#define HWSTAM         0x02098
+#define SCPD0          0x0209c /* 915+ only */
+#define IER            0x020a0
+#define IIR            0x020a4
+#define IMR            0x020a8
+#define ISR            0x020ac
+#define   I915_PIPE_CONTROL_NOTIFY_INTERRUPT           (1<<18)
+#define   I915_DISPLAY_PORT_INTERRUPT                  (1<<17)
+#define   I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT   (1<<15)
+#define   I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT     (1<<14)
+#define   I915_HWB_OOM_INTERRUPT                       (1<<13)
+#define   I915_SYNC_STATUS_INTERRUPT                   (1<<12)
+#define   I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT  (1<<11)
+#define   I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT  (1<<10)
+#define   I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT    (1<<9)
+#define   I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT  (1<<8)
+#define   I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT         (1<<7)
+#define   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT          (1<<6)
+#define   I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT         (1<<5)
+#define   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT          (1<<4)
+#define   I915_DEBUG_INTERRUPT                         (1<<2)
+#define   I915_USER_INTERRUPT                          (1<<1)
+#define   I915_ASLE_INTERRUPT                          (1<<0)
+#define EIR            0x020b0
+#define EMR            0x020b4
+#define ESR            0x020b8
+#define INSTPM         0x020c0
+#define ACTHD          0x020c8
+#define FW_BLC         0x020d8
+#define FW_BLC_SELF    0x020e0 /* 915+ only */
+#define MI_ARB_STATE   0x020e4 /* 915+ only */
+#define CACHE_MODE_0   0x02120 /* 915+ only */
+#define   CM0_MASK_SHIFT          16
+#define   CM0_IZ_OPT_DISABLE      (1<<6)
+#define   CM0_ZR_OPT_DISABLE      (1<<5)
+#define   CM0_DEPTH_EVICT_DISABLE (1<<4)
+#define   CM0_COLOR_EVICT_DISABLE (1<<3)
+#define   CM0_DEPTH_WRITE_DISABLE (1<<1)
+#define   CM0_RC_OP_FLUSH_DISABLE (1<<0)
+#define GFX_FLSH_CNTL  0x02170 /* 915+ only */
+
+/*
+ * Framebuffer compression (915+ only)
+ */
+
+#define FBC_CFB_BASE           0x03200 /* 4k page aligned */
+#define FBC_LL_BASE            0x03204 /* 4k page aligned */
+#define FBC_CONTROL            0x03208
+#define   FBC_CTL_EN           (1<<31)
+#define   FBC_CTL_PERIODIC     (1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
+#define   FBC_CTL_STRIDE_SHIFT (5)
+#define   FBC_CTL_FENCENO      (1<<0)
+#define FBC_COMMAND            0x0320c
+#define   FBC_CMD_COMPRESS     (1<<0)
+#define FBC_STATUS             0x03210
+#define   FBC_STAT_COMPRESSING (1<<31)
+#define   FBC_STAT_COMPRESSED  (1<<30)
+#define   FBC_STAT_MODIFIED    (1<<29)
+#define   FBC_STAT_CURRENT_LINE        (1<<0)
+#define FBC_CONTROL2           0x03214
+#define   FBC_CTL_FENCE_DBL    (0<<4)
+#define   FBC_CTL_IDLE_IMM     (0<<2)
+#define   FBC_CTL_IDLE_FULL    (1<<2)
+#define   FBC_CTL_IDLE_LINE    (2<<2)
+#define   FBC_CTL_IDLE_DEBUG   (3<<2)
+#define   FBC_CTL_CPU_FENCE    (1<<1)
+#define   FBC_CTL_PLANEA       (0<<0)
+#define   FBC_CTL_PLANEB       (1<<0)
+#define FBC_FENCE_OFF          0x0321b
+
+#define FBC_LL_SIZE            (1536)
+
+/*
+ * GPIO regs
+ */
+#define GPIOA                  0x5010
+#define GPIOB                  0x5014
+#define GPIOC                  0x5018
+#define GPIOD                  0x501c
+#define GPIOE                  0x5020
+#define GPIOF                  0x5024
+#define GPIOG                  0x5028
+#define GPIOH                  0x502c
+# define GPIO_CLOCK_DIR_MASK           (1 << 0)
+# define GPIO_CLOCK_DIR_IN             (0 << 1)
+# define GPIO_CLOCK_DIR_OUT            (1 << 1)
+# define GPIO_CLOCK_VAL_MASK           (1 << 2)
+# define GPIO_CLOCK_VAL_OUT            (1 << 3)
+# define GPIO_CLOCK_VAL_IN             (1 << 4)
+# define GPIO_CLOCK_PULLUP_DISABLE     (1 << 5)
+# define GPIO_DATA_DIR_MASK            (1 << 8)
+# define GPIO_DATA_DIR_IN              (0 << 9)
+# define GPIO_DATA_DIR_OUT             (1 << 9)
+# define GPIO_DATA_VAL_MASK            (1 << 10)
+# define GPIO_DATA_VAL_OUT             (1 << 11)
+# define GPIO_DATA_VAL_IN              (1 << 12)
+# define GPIO_DATA_PULLUP_DISABLE      (1 << 13)
+
+/*
+ * Clock control & power management
+ */
+
+#define VGA0   0x6000
+#define VGA1   0x6004
+#define VGA_PD 0x6010
+#define   VGA0_PD_P2_DIV_4     (1 << 7)
+#define   VGA0_PD_P1_DIV_2     (1 << 5)
+#define   VGA0_PD_P1_SHIFT     0
+#define   VGA0_PD_P1_MASK      (0x1f << 0)
+#define   VGA1_PD_P2_DIV_4     (1 << 15)
+#define   VGA1_PD_P1_DIV_2     (1 << 13)
+#define   VGA1_PD_P1_SHIFT     8
+#define   VGA1_PD_P1_MASK      (0x1f << 8)
+#define DPLL_A 0x06014
+#define DPLL_B 0x06018
+#define   DPLL_VCO_ENABLE              (1 << 31)
+#define   DPLL_DVO_HIGH_SPEED          (1 << 30)
+#define   DPLL_SYNCLOCK_ENABLE         (1 << 29)
+#define   DPLL_VGA_MODE_DIS            (1 << 28)
+#define   DPLLB_MODE_DAC_SERIAL                (1 << 26) /* i915 */
+#define   DPLLB_MODE_LVDS              (2 << 26) /* i915 */
+#define   DPLL_MODE_MASK               (3 << 26)
+#define   DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
+#define   DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
+#define   DPLLB_LVDS_P2_CLOCK_DIV_14   (0 << 24) /* i915 */
+#define   DPLLB_LVDS_P2_CLOCK_DIV_7    (1 << 24) /* i915 */
+#define   DPLL_P2_CLOCK_DIV_MASK       0x03000000 /* i915 */
+#define   DPLL_FPA01_P1_POST_DIV_MASK  0x00ff0000 /* i915 */
+
+#define I915_FIFO_UNDERRUN_STATUS              (1UL<<31)
+#define I915_CRC_ERROR_ENABLE                  (1UL<<29)
+#define I915_CRC_DONE_ENABLE                   (1UL<<28)
+#define I915_GMBUS_EVENT_ENABLE                        (1UL<<27)
+#define I915_VSYNC_INTERRUPT_ENABLE            (1UL<<25)
+#define I915_DISPLAY_LINE_COMPARE_ENABLE       (1UL<<24)
+#define I915_DPST_EVENT_ENABLE                 (1UL<<23)
+#define I915_LEGACY_BLC_EVENT_ENABLE           (1UL<<22)
+#define I915_ODD_FIELD_INTERRUPT_ENABLE                (1UL<<21)
+#define I915_EVEN_FIELD_INTERRUPT_ENABLE       (1UL<<20)
+#define I915_START_VBLANK_INTERRUPT_ENABLE     (1UL<<18)       /* 965 or later */
+#define I915_VBLANK_INTERRUPT_ENABLE           (1UL<<17)
+#define I915_OVERLAY_UPDATED_ENABLE            (1UL<<16)
+#define I915_CRC_ERROR_INTERRUPT_STATUS                (1UL<<13)
+#define I915_CRC_DONE_INTERRUPT_STATUS         (1UL<<12)
+#define I915_GMBUS_INTERRUPT_STATUS            (1UL<<11)
+#define I915_VSYNC_INTERRUPT_STATUS            (1UL<<9)
+#define I915_DISPLAY_LINE_COMPARE_STATUS       (1UL<<8)
+#define I915_DPST_EVENT_STATUS                 (1UL<<7)
+#define I915_LEGACY_BLC_EVENT_STATUS           (1UL<<6)
+#define I915_ODD_FIELD_INTERRUPT_STATUS                (1UL<<5)
+#define I915_EVEN_FIELD_INTERRUPT_STATUS       (1UL<<4)
+#define I915_START_VBLANK_INTERRUPT_STATUS     (1UL<<2)        /* 965 or later */
+#define I915_VBLANK_INTERRUPT_STATUS           (1UL<<1)
+#define I915_OVERLAY_UPDATED_STATUS            (1UL<<0)
+
+#define SRX_INDEX              0x3c4
+#define SRX_DATA               0x3c5
+#define SR01                   1
+#define SR01_SCREEN_OFF                (1<<5)
+
+#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 ADPA_DPMS_SUSPEND      (1<<10)
+#define ADPA_DPMS_STANDBY      (2<<10)
+#define ADPA_DPMS_OFF          (3<<10)
+
+#define RING_TAIL              0x00
+#define TAIL_ADDR              0x001FFFF8
+#define RING_HEAD              0x04
+#define HEAD_WRAP_COUNT                0xFFE00000
+#define HEAD_WRAP_ONE          0x00200000
+#define HEAD_ADDR              0x001FFFFC
+#define RING_START             0x08
+#define START_ADDR             0xFFFFF000
+#define RING_LEN               0x0C
+#define RING_NR_PAGES          0x001FF000
+#define RING_REPORT_MASK       0x00000006
+#define RING_REPORT_64K                0x00000002
+#define RING_REPORT_128K       0x00000004
+#define RING_NO_REPORT         0x00000000
+#define RING_VALID_MASK                0x00000001
+#define RING_VALID             0x00000001
+#define RING_INVALID           0x00000000
+
+/* Scratch pad debug 0 reg:
+ */
+#define   DPLL_FPA01_P1_POST_DIV_MASK_I830     0x001f0000
+/*
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+#define   DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS        0x003f0000
+#define   DPLL_FPA01_P1_POST_DIV_SHIFT 16
+/* i830, required in DVO non-gang */
+#define   PLL_P2_DIVIDE_BY_4           (1 << 23)
+#define   PLL_P1_DIVIDE_BY_TWO         (1 << 21) /* i830 */
+#define   PLL_REF_INPUT_DREFCLK                (0 << 13)
+#define   PLL_REF_INPUT_TVCLKINA       (1 << 13) /* i830 */
+#define   PLL_REF_INPUT_TVCLKINBC      (2 << 13) /* SDVO TVCLKIN */
+#define   PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
+#define   PLL_REF_INPUT_MASK           (3 << 13)
+#define   PLL_LOAD_PULSE_PHASE_SHIFT           9
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+#define   PLL_LOAD_PULSE_PHASE_MASK            (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
+#define   DISPLAY_RATE_SELECT_FPA1             (1 << 8)
+/*
+ * SDVO multiplier for 945G/GM. Not used on 965.
+ */
+#define   SDVO_MULTIPLIER_MASK                 0x000000ff
+#define   SDVO_MULTIPLIER_SHIFT_HIRES          4
+#define   SDVO_MULTIPLIER_SHIFT_VGA            0
+#define DPLL_A_MD 0x0601c /* 965+ only */
+/*
+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
+ *
+ * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
+ */
+#define   DPLL_MD_UDI_DIVIDER_MASK             0x3f000000
+#define   DPLL_MD_UDI_DIVIDER_SHIFT            24
+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
+#define   DPLL_MD_VGA_UDI_DIVIDER_MASK         0x003f0000
+#define   DPLL_MD_VGA_UDI_DIVIDER_SHIFT                16
+/*
+ * SDVO/UDI pixel multiplier.
+ *
+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
+ * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
+ * dummy bytes in the datastream at an increased clock rate, with both sides of
+ * the link knowing how many bytes are fill.
+ *
+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
+ * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
+ * through an SDVO command.
+ *
+ * This register field has values of multiplication factor minus 1, with
+ * a maximum multiplier of 5 for SDVO.
+ */
+#define   DPLL_MD_UDI_MULTIPLIER_MASK          0x00003f00
+#define   DPLL_MD_UDI_MULTIPLIER_SHIFT         8
+/*
+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
+#define   DPLL_MD_VGA_UDI_MULTIPLIER_MASK      0x0000003f
+#define   DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT     0
+#define DPLL_B_MD 0x06020 /* 965+ only */
+#define FPA0   0x06040
+#define FPA1   0x06044
+#define FPB0   0x06048
+#define FPB1   0x0604c
+#define   FP_N_DIV_MASK                0x003f0000
+#define   FP_N_DIV_SHIFT               16
+#define   FP_M1_DIV_MASK       0x00003f00
+#define   FP_M1_DIV_SHIFT               8
+#define   FP_M2_DIV_MASK       0x0000003f
+#define   FP_M2_DIV_SHIFT               0
+#define DPLL_TEST      0x606c
+#define   DPLLB_TEST_SDVO_DIV_1                (0 << 22)
+#define   DPLLB_TEST_SDVO_DIV_2                (1 << 22)
+#define   DPLLB_TEST_SDVO_DIV_4                (2 << 22)
+#define   DPLLB_TEST_SDVO_DIV_MASK     (3 << 22)
+#define   DPLLB_TEST_N_BYPASS          (1 << 19)
+#define   DPLLB_TEST_M_BYPASS          (1 << 18)
+#define   DPLLB_INPUT_BUFFER_ENABLE    (1 << 16)
+#define   DPLLA_TEST_N_BYPASS          (1 << 3)
+#define   DPLLA_TEST_M_BYPASS          (1 << 2)
+#define   DPLLA_INPUT_BUFFER_ENABLE    (1 << 0)
+#define D_STATE                0x6104
+#define CG_2D_DIS      0x6200
+#define CG_3D_DIS      0x6204
+
+/*
+ * Palette regs
+ */
+
+#define PALETTE_A              0x0a000
+#define PALETTE_B              0x0a800
+
+/* MCH MMIO space */
+
+/*
+ * MCHBAR mirror.
+ *
+ * This mirrors the MCHBAR MMIO space whose location is determined by
+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
+ * every way.  It is not accessible from the CP register read instructions.
+ *
+ */
+#define MCHBAR_MIRROR_BASE     0x10000
+
+/** 915-945 and GM965 MCH register controlling DRAM channel access */
+#define DCC                    0x10200
+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL             (0 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC    (1 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED   (2 << 0)
+#define DCC_ADDRESSING_MODE_MASK                       (3 << 0)
+#define DCC_CHANNEL_XOR_DISABLE                                (1 << 10)
+
+/** 965 MCH register controlling DRAM channel configuration */
+#define C0DRB3                 0x10206
+#define C1DRB3                 0x10606
+
+/*
+ * Overlay regs
+ */
+
+#define OVADD                  0x30000
+#define DOVSTA                 0x30008
+#define OC_BUF                 (0x3<<20)
+#define OGAMC5                 0x30010
+#define OGAMC4                 0x30014
+#define OGAMC3                 0x30018
+#define OGAMC2                 0x3001c
+#define OGAMC1                 0x30020
+#define OGAMC0                 0x30024
+
+/*
+ * Display engine regs
+ */
+
+/* Pipe A timing regs */
+#define HTOTAL_A       0x60000
+#define HBLANK_A       0x60004
+#define HSYNC_A                0x60008
+#define VTOTAL_A       0x6000c
+#define VBLANK_A       0x60010
+#define VSYNC_A                0x60014
+#define PIPEASRC       0x6001c
+#define BCLRPAT_A      0x60020
+
+/* Pipe B timing regs */
+#define HTOTAL_B       0x61000
+#define HBLANK_B       0x61004
+#define HSYNC_B                0x61008
+#define VTOTAL_B       0x6100c
+#define VBLANK_B       0x61010
+#define VSYNC_B                0x61014
+#define PIPEBSRC       0x6101c
+#define BCLRPAT_B      0x61020
+
+/* VGA port control */
+#define ADPA                   0x61100
+#define   ADPA_DAC_ENABLE      (1<<31)
+#define   ADPA_DAC_DISABLE     0
+#define   ADPA_PIPE_SELECT_MASK        (1<<30)
+#define   ADPA_PIPE_A_SELECT   0
+#define   ADPA_PIPE_B_SELECT   (1<<30)
+#define   ADPA_USE_VGA_HVPOLARITY (1<<15)
+#define   ADPA_SETS_HVPOLARITY 0
+#define   ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define   ADPA_VSYNC_CNTL_ENABLE 0
+#define   ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define   ADPA_HSYNC_CNTL_ENABLE 0
+#define   ADPA_VSYNC_ACTIVE_HIGH (1<<4)
+#define   ADPA_VSYNC_ACTIVE_LOW        0
+#define   ADPA_HSYNC_ACTIVE_HIGH (1<<3)
+#define   ADPA_HSYNC_ACTIVE_LOW        0
+#define   ADPA_DPMS_MASK       (~(3<<10))
+#define   ADPA_DPMS_ON         (0<<10)
+#define   ADPA_DPMS_SUSPEND    (1<<10)
+#define   ADPA_DPMS_STANDBY    (2<<10)
+#define   ADPA_DPMS_OFF                (3<<10)
+
+/* Hotplug control (945+ only) */
+#define PORT_HOTPLUG_EN                0x61110
+#define   SDVOB_HOTPLUG_INT_EN                 (1 << 26)
+#define   SDVOC_HOTPLUG_INT_EN                 (1 << 25)
+#define   TV_HOTPLUG_INT_EN                    (1 << 18)
+#define   CRT_HOTPLUG_INT_EN                   (1 << 9)
+#define   CRT_HOTPLUG_FORCE_DETECT             (1 << 3)
+
+#define PORT_HOTPLUG_STAT      0x61114
+#define   CRT_HOTPLUG_INT_STATUS               (1 << 11)
+#define   TV_HOTPLUG_INT_STATUS                        (1 << 10)
+#define   CRT_HOTPLUG_MONITOR_MASK             (3 << 8)
+#define   CRT_HOTPLUG_MONITOR_COLOR            (3 << 8)
+#define   CRT_HOTPLUG_MONITOR_MONO             (2 << 8)
+#define   CRT_HOTPLUG_MONITOR_NONE             (0 << 8)
+#define   SDVOC_HOTPLUG_INT_STATUS             (1 << 7)
+#define   SDVOB_HOTPLUG_INT_STATUS             (1 << 6)
+
+/* SDVO port control */
+#define SDVOB                  0x61140
+#define SDVOC                  0x61160
+#define   SDVO_ENABLE          (1 << 31)
+#define   SDVO_PIPE_B_SELECT   (1 << 30)
+#define   SDVO_STALL_SELECT    (1 << 29)
+#define   SDVO_INTERRUPT_ENABLE        (1 << 26)
+/**
+ * 915G/GM SDVO pixel multiplier.
+ *
+ * Programmed value is multiplier - 1, up to 5x.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+#define   SDVO_PORT_MULTIPLY_MASK      (7 << 23)
+#define   SDVO_PORT_MULTIPLY_SHIFT             23
+#define   SDVO_PHASE_SELECT_MASK       (15 << 19)
+#define   SDVO_PHASE_SELECT_DEFAULT    (6 << 19)
+#define   SDVO_CLOCK_OUTPUT_INVERT     (1 << 18)
+#define   SDVOC_GANG_MODE              (1 << 16)
+#define   SDVO_BORDER_ENABLE           (1 << 7)
+#define   SDVOB_PCIE_CONCURRENCY       (1 << 3)
+#define   SDVO_DETECTED                        (1 << 2)
+/* Bits to be preserved when writing */
+#define   SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
+#define   SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
+
+/* DVO port control */
+#define DVOA                   0x61120
+#define DVOB                   0x61140
+#define DVOC                   0x61160
+#define   DVO_ENABLE                   (1 << 31)
+#define   DVO_PIPE_B_SELECT            (1 << 30)
+#define   DVO_PIPE_STALL_UNUSED                (0 << 28)
+#define   DVO_PIPE_STALL               (1 << 28)
+#define   DVO_PIPE_STALL_TV            (2 << 28)
+#define   DVO_PIPE_STALL_MASK          (3 << 28)
+#define   DVO_USE_VGA_SYNC             (1 << 15)
+#define   DVO_DATA_ORDER_I740          (0 << 14)
+#define   DVO_DATA_ORDER_FP            (1 << 14)
+#define   DVO_VSYNC_DISABLE            (1 << 11)
+#define   DVO_HSYNC_DISABLE            (1 << 10)
+#define   DVO_VSYNC_TRISTATE           (1 << 9)
+#define   DVO_HSYNC_TRISTATE           (1 << 8)
+#define   DVO_BORDER_ENABLE            (1 << 7)
+#define   DVO_DATA_ORDER_GBRG          (1 << 6)
+#define   DVO_DATA_ORDER_RGGB          (0 << 6)
+#define   DVO_DATA_ORDER_GBRG_ERRATA   (0 << 6)
+#define   DVO_DATA_ORDER_RGGB_ERRATA   (1 << 6)
+#define   DVO_VSYNC_ACTIVE_HIGH                (1 << 4)
+#define   DVO_HSYNC_ACTIVE_HIGH                (1 << 3)
+#define   DVO_BLANK_ACTIVE_HIGH                (1 << 2)
+#define   DVO_OUTPUT_CSTATE_PIXELS     (1 << 1)        /* SDG only */
+#define   DVO_OUTPUT_SOURCE_SIZE_PIXELS        (1 << 0)        /* SDG only */
+#define   DVO_PRESERVE_MASK            (0x7<<24)
+#define DVOA_SRCDIM            0x61124
+#define DVOB_SRCDIM            0x61144
+#define DVOC_SRCDIM            0x61164
+#define   DVO_SRCDIM_HORIZONTAL_SHIFT  12
+#define   DVO_SRCDIM_VERTICAL_SHIFT    0
+
+/* LVDS port control */
+#define LVDS                   0x61180
+/*
+ * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
+ * the DPLL semantics change when the LVDS is assigned to that pipe.
+ */
+#define   LVDS_PORT_EN                 (1 << 31)
+/* Selects pipe B for LVDS data.  Must be set on pre-965. */
+#define   LVDS_PIPEB_SELECT            (1 << 30)
+/*
+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
+ * pixel.
+ */
+#define   LVDS_A0A2_CLKA_POWER_MASK    (3 << 8)
+#define   LVDS_A0A2_CLKA_POWER_DOWN    (0 << 8)
+#define   LVDS_A0A2_CLKA_POWER_UP      (3 << 8)
+/*
+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
+ * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
+ * on.
+ */
+#define   LVDS_A3_POWER_MASK           (3 << 6)
+#define   LVDS_A3_POWER_DOWN           (0 << 6)
+#define   LVDS_A3_POWER_UP             (3 << 6)
+/*
+ * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
+ * is set.
+ */
+#define   LVDS_CLKB_POWER_MASK         (3 << 4)
+#define   LVDS_CLKB_POWER_DOWN         (0 << 4)
+#define   LVDS_CLKB_POWER_UP           (3 << 4)
+/*
+ * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
+ * setting for whether we are in dual-channel mode.  The B3 pair will
+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
+ */
+#define   LVDS_B0B3_POWER_MASK         (3 << 2)
+#define   LVDS_B0B3_POWER_DOWN         (0 << 2)
+#define   LVDS_B0B3_POWER_UP           (3 << 2)
+
+/* Panel power sequencing */
+#define PP_STATUS      0x61200
+#define   PP_ON                (1 << 31)
+/*
+ * Indicates that all dependencies of the panel are on:
+ *
+ * - PLL enabled
+ * - pipe enabled
+ * - LVDS/DVOB/DVOC on
+ */
+#define   PP_READY             (1 << 30)
+#define   PP_SEQUENCE_NONE     (0 << 28)
+#define   PP_SEQUENCE_ON       (1 << 28)
+#define   PP_SEQUENCE_OFF      (2 << 28)
+#define   PP_SEQUENCE_MASK     0x30000000
+#define PP_CONTROL     0x61204
+#define   POWER_TARGET_ON      (1 << 0)
+#define PP_ON_DELAYS   0x61208
+#define PP_OFF_DELAYS  0x6120c
+#define PP_DIVISOR     0x61210
+
+/* Panel fitting */
+#define PFIT_CONTROL   0x61230
+#define   PFIT_ENABLE          (1 << 31)
+#define   PFIT_PIPE_MASK       (3 << 29)
+#define   PFIT_PIPE_SHIFT      29
+#define   VERT_INTERP_DISABLE  (0 << 10)
+#define   VERT_INTERP_BILINEAR (1 << 10)
+#define   VERT_INTERP_MASK     (3 << 10)
+#define   VERT_AUTO_SCALE      (1 << 9)
+#define   HORIZ_INTERP_DISABLE (0 << 6)
+#define   HORIZ_INTERP_BILINEAR        (1 << 6)
+#define   HORIZ_INTERP_MASK    (3 << 6)
+#define   HORIZ_AUTO_SCALE     (1 << 5)
+#define   PANEL_8TO6_DITHER_ENABLE (1 << 3)
+#define PFIT_PGM_RATIOS        0x61234
+#define   PFIT_VERT_SCALE_MASK                 0xfff00000
+#define   PFIT_HORIZ_SCALE_MASK                        0x0000fff0
+#define PFIT_AUTO_RATIOS 0x61238
+
+/* Backlight control */
+#define BLC_PWM_CTL            0x61254
+#define   BACKLIGHT_MODULATION_FREQ_SHIFT              (17)
+#define BLC_PWM_CTL2           0x61250 /* 965+ only */
+#define   BLM_COMBINATION_MODE (1 << 30)
+/*
+ * This is the most significant 15 bits of the number of backlight cycles in a
+ * complete cycle of the modulated backlight control.
+ *
+ * The actual value is this field multiplied by two.
+ */
+#define   BACKLIGHT_MODULATION_FREQ_MASK               (0x7fff << 17)
+#define   BLM_LEGACY_MODE                              (1 << 16)
+/*
+ * This is the number of cycles out of the backlight modulation cycle for which
+ * the backlight is on.
+ *
+ * This field must be no greater than the number of cycles in the complete
+ * backlight modulation cycle.
+ */
+#define   BACKLIGHT_DUTY_CYCLE_SHIFT           (0)
+#define   BACKLIGHT_DUTY_CYCLE_MASK            (0xffff)
+
+/* TV port control */
+#define TV_CTL                 0x68000
+/** Enables the TV encoder */
+# define TV_ENC_ENABLE                 (1 << 31)
+/** Sources the TV encoder input from pipe B instead of A. */
+# define TV_ENC_PIPEB_SELECT           (1 << 30)
+/** Outputs composite video (DAC A only) */
+# define TV_ENC_OUTPUT_COMPOSITE       (0 << 28)
+/** Outputs SVideo video (DAC B/C) */
+# define TV_ENC_OUTPUT_SVIDEO          (1 << 28)
+/** Outputs Component video (DAC A/B/C) */
+# define TV_ENC_OUTPUT_COMPONENT       (2 << 28)
+/** Outputs Composite and SVideo (DAC A/B/C) */
+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE        (3 << 28)
+# define TV_TRILEVEL_SYNC              (1 << 21)
+/** Enables slow sync generation (945GM only) */
+# define TV_SLOW_SYNC                  (1 << 20)
+/** Selects 4x oversampling for 480i and 576p */
+# define TV_OVERSAMPLE_4X              (0 << 18)
+/** Selects 2x oversampling for 720p and 1080i */
+# define TV_OVERSAMPLE_2X              (1 << 18)
+/** Selects no oversampling for 1080p */
+# define TV_OVERSAMPLE_NONE            (2 << 18)
+/** Selects 8x oversampling */
+# define TV_OVERSAMPLE_8X              (3 << 18)
+/** Selects progressive mode rather than interlaced */
+# define TV_PROGRESSIVE                        (1 << 17)
+/** Sets the colorburst to PAL mode.  Required for non-M PAL modes. */
+# define TV_PAL_BURST                  (1 << 16)
+/** Field for setting delay of Y compared to C */
+# define TV_YC_SKEW_MASK               (7 << 12)
+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
+# define TV_ENC_SDP_FIX                        (1 << 11)
+/**
+ * Enables a fix for the 915GM only.
+ *
+ * Not sure what it does.
+ */
+# define TV_ENC_C0_FIX                 (1 << 10)
+/** Bits that must be preserved by software */
+# define TV_CTL_SAVE                   ((3 << 8) | (3 << 6))
+# define TV_FUSE_STATE_MASK            (3 << 4)
+/** Read-only state that reports all features enabled */
+# define TV_FUSE_STATE_ENABLED         (0 << 4)
+/** Read-only state that reports that Macrovision is disabled in hardware*/
+# define TV_FUSE_STATE_NO_MACROVISION  (1 << 4)
+/** Read-only state that reports that TV-out is disabled in hardware. */
+# define TV_FUSE_STATE_DISABLED                (2 << 4)
+/** Normal operation */
+# define TV_TEST_MODE_NORMAL           (0 << 0)
+/** Encoder test pattern 1 - combo pattern */
+# define TV_TEST_MODE_PATTERN_1                (1 << 0)
+/** Encoder test pattern 2 - full screen vertical 75% color bars */
+# define TV_TEST_MODE_PATTERN_2                (2 << 0)
+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
+# define TV_TEST_MODE_PATTERN_3                (3 << 0)
+/** Encoder test pattern 4 - random noise */
+# define TV_TEST_MODE_PATTERN_4                (4 << 0)
+/** Encoder test pattern 5 - linear color ramps */
+# define TV_TEST_MODE_PATTERN_5                (5 << 0)
+/**
+ * This test mode forces the DACs to 50% of full output.
+ *
+ * This is used for load detection in combination with TVDAC_SENSE_MASK
+ */
+# define TV_TEST_MODE_MONITOR_DETECT   (7 << 0)
+# define TV_TEST_MODE_MASK             (7 << 0)
+
+#define TV_DAC                 0x68004
+/**
+ * Reports that DAC state change logic has reported change (RO).
+ *
+ * This gets cleared when TV_DAC_STATE_EN is cleared
+*/
+# define TVDAC_STATE_CHG               (1 << 31)
+# define TVDAC_SENSE_MASK              (7 << 28)
+/** Reports that DAC A voltage is above the detect threshold */
+# define TVDAC_A_SENSE                 (1 << 30)
+/** Reports that DAC B voltage is above the detect threshold */
+# define TVDAC_B_SENSE                 (1 << 29)
+/** Reports that DAC C voltage is above the detect threshold */
+# define TVDAC_C_SENSE                 (1 << 28)
+/**
+ * Enables DAC state detection logic, for load-based TV detection.
+ *
+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
+ * to off, for load detection to work.
+ */
+# define TVDAC_STATE_CHG_EN            (1 << 27)
+/** Sets the DAC A sense value to high */
+# define TVDAC_A_SENSE_CTL             (1 << 26)
+/** Sets the DAC B sense value to high */
+# define TVDAC_B_SENSE_CTL             (1 << 25)
+/** Sets the DAC C sense value to high */
+# define TVDAC_C_SENSE_CTL             (1 << 24)
+/** Overrides the ENC_ENABLE and DAC voltage levels */
+# define DAC_CTL_OVERRIDE              (1 << 7)
+/** Sets the slew rate.  Must be preserved in software */
+# define ENC_TVDAC_SLEW_FAST           (1 << 6)
+# define DAC_A_1_3_V                   (0 << 4)
+# define DAC_A_1_1_V                   (1 << 4)
+# define DAC_A_0_7_V                   (2 << 4)
+# define DAC_A_OFF                     (3 << 4)
+# define DAC_B_1_3_V                   (0 << 2)
+# define DAC_B_1_1_V                   (1 << 2)
+# define DAC_B_0_7_V                   (2 << 2)
+# define DAC_B_OFF                     (3 << 2)
+# define DAC_C_1_3_V                   (0 << 0)
+# define DAC_C_1_1_V                   (1 << 0)
+# define DAC_C_0_7_V                   (2 << 0)
+# define DAC_C_OFF                     (3 << 0)
+
+/**
+ * CSC coefficients are stored in a floating point format with 9 bits of
+ * mantissa and 2 or 3 bits of exponent.  The exponent is represented as 2**-n,
+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
+ * -1 (0x3) being the only legal negative value.
+ */
+#define TV_CSC_Y               0x68010
+# define TV_RY_MASK                    0x07ff0000
+# define TV_RY_SHIFT                   16
+# define TV_GY_MASK                    0x00000fff
+# define TV_GY_SHIFT                   0
+
+#define TV_CSC_Y2              0x68014
+# define TV_BY_MASK                    0x07ff0000
+# define TV_BY_SHIFT                   16
+/**
+ * Y attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AY_MASK                    0x000003ff
+# define TV_AY_SHIFT                   0
+
+#define TV_CSC_U               0x68018
+# define TV_RU_MASK                    0x07ff0000
+# define TV_RU_SHIFT                   16
+# define TV_GU_MASK                    0x000007ff
+# define TV_GU_SHIFT                   0
+
+#define TV_CSC_U2              0x6801c
+# define TV_BU_MASK                    0x07ff0000
+# define TV_BU_SHIFT                   16
+/**
+ * U attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AU_MASK                    0x000003ff
+# define TV_AU_SHIFT                   0
+
+#define TV_CSC_V               0x68020
+# define TV_RV_MASK                    0x0fff0000
+# define TV_RV_SHIFT                   16
+# define TV_GV_MASK                    0x000007ff
+# define TV_GV_SHIFT                   0
+
+#define TV_CSC_V2              0x68024
+# define TV_BV_MASK                    0x07ff0000
+# define TV_BV_SHIFT                   16
+/**
+ * V attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AV_MASK                    0x000007ff
+# define TV_AV_SHIFT                   0
+
+#define TV_CLR_KNOBS           0x68028
+/** 2s-complement brightness adjustment */
+# define TV_BRIGHTNESS_MASK            0xff000000
+# define TV_BRIGHTNESS_SHIFT           24
+/** Contrast adjustment, as a 2.6 unsigned floating point number */
+# define TV_CONTRAST_MASK              0x00ff0000
+# define TV_CONTRAST_SHIFT             16
+/** Saturation adjustment, as a 2.6 unsigned floating point number */
+# define TV_SATURATION_MASK            0x0000ff00
+# define TV_SATURATION_SHIFT           8
+/** Hue adjustment, as an integer phase angle in degrees */
+# define TV_HUE_MASK                   0x000000ff
+# define TV_HUE_SHIFT                  0
+
+#define TV_CLR_LEVEL           0x6802c
+/** Controls the DAC level for black */
+# define TV_BLACK_LEVEL_MASK           0x01ff0000
+# define TV_BLACK_LEVEL_SHIFT          16
+/** Controls the DAC level for blanking */
+# define TV_BLANK_LEVEL_MASK           0x000001ff
+# define TV_BLANK_LEVEL_SHIFT          0
+
+#define TV_H_CTL_1             0x68030
+/** Number of pixels in the hsync. */
+# define TV_HSYNC_END_MASK             0x1fff0000
+# define TV_HSYNC_END_SHIFT            16
+/** Total number of pixels minus one in the line (display and blanking). */
+# define TV_HTOTAL_MASK                        0x00001fff
+# define TV_HTOTAL_SHIFT               0
+
+#define TV_H_CTL_2             0x68034
+/** Enables the colorburst (needed for non-component color) */
+# define TV_BURST_ENA                  (1 << 31)
+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
+# define TV_HBURST_START_SHIFT         16
+# define TV_HBURST_START_MASK          0x1fff0000
+/** Length of the colorburst */
+# define TV_HBURST_LEN_SHIFT           0
+# define TV_HBURST_LEN_MASK            0x0001fff
+
+#define TV_H_CTL_3             0x68038
+/** End of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_END_SHIFT           16
+# define TV_HBLANK_END_MASK            0x1fff0000
+/** Start of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_START_SHIFT         0
+# define TV_HBLANK_START_MASK          0x0001fff
+
+#define TV_V_CTL_1             0x6803c
+/** XXX */
+# define TV_NBR_END_SHIFT              16
+# define TV_NBR_END_MASK               0x07ff0000
+/** XXX */
+# define TV_VI_END_F1_SHIFT            8
+# define TV_VI_END_F1_MASK             0x00003f00
+/** XXX */
+# define TV_VI_END_F2_SHIFT            0
+# define TV_VI_END_F2_MASK             0x0000003f
+
+#define TV_V_CTL_2             0x68040
+/** Length of vsync, in half lines */
+# define TV_VSYNC_LEN_MASK             0x07ff0000
+# define TV_VSYNC_LEN_SHIFT            16
+/** Offset of the start of vsync in field 1, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F1_MASK                0x00007f00
+# define TV_VSYNC_START_F1_SHIFT       8
+/**
+ * Offset of the start of vsync in field 2, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F2_MASK                0x0000007f
+# define TV_VSYNC_START_F2_SHIFT       0
+
+#define TV_V_CTL_3             0x68044
+/** Enables generation of the equalization signal */
+# define TV_EQUAL_ENA                  (1 << 31)
+/** Length of vsync, in half lines */
+# define TV_VEQ_LEN_MASK               0x007f0000
+# define TV_VEQ_LEN_SHIFT              16
+/** Offset of the start of equalization in field 1, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F1_MASK          0x0007f00
+# define TV_VEQ_START_F1_SHIFT         8
+/**
+ * Offset of the start of equalization in field 2, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F2_MASK          0x000007f
+# define TV_VEQ_START_F2_SHIFT         0
+
+#define TV_V_CTL_4             0x68048
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F1_MASK       0x003f0000
+# define TV_VBURST_START_F1_SHIFT      16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F1_MASK         0x000000ff
+# define TV_VBURST_END_F1_SHIFT                0
+
+#define TV_V_CTL_5             0x6804c
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F2_MASK       0x003f0000
+# define TV_VBURST_START_F2_SHIFT      16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F2_MASK         0x000000ff
+# define TV_VBURST_END_F2_SHIFT                0
+
+#define TV_V_CTL_6             0x68050
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F3_MASK       0x003f0000
+# define TV_VBURST_START_F3_SHIFT      16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F3_MASK         0x000000ff
+# define TV_VBURST_END_F3_SHIFT                0
+
+#define TV_V_CTL_7             0x68054
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F4_MASK       0x003f0000
+# define TV_VBURST_START_F4_SHIFT      16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F4_MASK         0x000000ff
+# define TV_VBURST_END_F4_SHIFT                0
+
+#define TV_SC_CTL_1            0x68060
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA1_EN                 (1 << 31)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA2_EN                 (1 << 30)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA3_EN                 (1 << 29)
+/** Sets the subcarrier DDA to reset frequency every other field */
+# define TV_SC_RESET_EVERY_2           (0 << 24)
+/** Sets the subcarrier DDA to reset frequency every fourth field */
+# define TV_SC_RESET_EVERY_4           (1 << 24)
+/** Sets the subcarrier DDA to reset frequency every eighth field */
+# define TV_SC_RESET_EVERY_8           (2 << 24)
+/** Sets the subcarrier DDA to never reset the frequency */
+# define TV_SC_RESET_NEVER             (3 << 24)
+/** Sets the peak amplitude of the colorburst.*/
+# define TV_BURST_LEVEL_MASK           0x00ff0000
+# define TV_BURST_LEVEL_SHIFT          16
+/** Sets the increment of the first subcarrier phase generation DDA */
+# define TV_SCDDA1_INC_MASK            0x00000fff
+# define TV_SCDDA1_INC_SHIFT           0
+
+#define TV_SC_CTL_2            0x68064
+/** Sets the rollover for the second subcarrier phase generation DDA */
+# define TV_SCDDA2_SIZE_MASK           0x7fff0000
+# define TV_SCDDA2_SIZE_SHIFT          16
+/** Sets the increent of the second subcarrier phase generation DDA */
+# define TV_SCDDA2_INC_MASK            0x00007fff
+# define TV_SCDDA2_INC_SHIFT           0
+
+#define TV_SC_CTL_3            0x68068
+/** Sets the rollover for the third subcarrier phase generation DDA */
+# define TV_SCDDA3_SIZE_MASK           0x7fff0000
+# define TV_SCDDA3_SIZE_SHIFT          16
+/** Sets the increent of the third subcarrier phase generation DDA */
+# define TV_SCDDA3_INC_MASK            0x00007fff
+# define TV_SCDDA3_INC_SHIFT           0
+
+#define TV_WIN_POS             0x68070
+/** X coordinate of the display from the start of horizontal active */
+# define TV_XPOS_MASK                  0x1fff0000
+# define TV_XPOS_SHIFT                 16
+/** Y coordinate of the display from the start of vertical active (NBR) */
+# define TV_YPOS_MASK                  0x00000fff
+# define TV_YPOS_SHIFT                 0
+
+#define TV_WIN_SIZE            0x68074
+/** Horizontal size of the display window, measured in pixels*/
+# define TV_XSIZE_MASK                 0x1fff0000
+# define TV_XSIZE_SHIFT                        16
+/**
+ * Vertical size of the display window, measured in pixels.
+ *
+ * Must be even for interlaced modes.
+ */
+# define TV_YSIZE_MASK                 0x00000fff
+# define TV_YSIZE_SHIFT                        0
+
+#define TV_FILTER_CTL_1                0x68080
+/**
+ * Enables automatic scaling calculation.
+ *
+ * If set, the rest of the registers are ignored, and the calculated values can
+ * be read back from the register.
+ */
+# define TV_AUTO_SCALE                 (1 << 31)
+/**
+ * Disables the vertical filter.
+ *
+ * This is required on modes more than 1024 pixels wide */
+# define TV_V_FILTER_BYPASS            (1 << 29)
+/** Enables adaptive vertical filtering */
+# define TV_VADAPT                     (1 << 28)
+# define TV_VADAPT_MODE_MASK           (3 << 26)
+/** Selects the least adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_LEAST          (0 << 26)
+/** Selects the moderately adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MODERATE       (1 << 26)
+/** Selects the most adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MOST           (3 << 26)
+/**
+ * Sets the horizontal scaling factor.
+ *
+ * This should be the fractional part of the horizontal scaling factor divided
+ * by the oversampling rate.  TV_HSCALE should be less than 1, and set to:
+ *
+ * (src width - 1) / ((oversample * dest width) - 1)
+ */
+# define TV_HSCALE_FRAC_MASK           0x00003fff
+# define TV_HSCALE_FRAC_SHIFT          0
+
+#define TV_FILTER_CTL_2                0x68084
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
+ */
+# define TV_VSCALE_INT_MASK            0x00038000
+# define TV_VSCALE_INT_SHIFT           15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * \sa TV_VSCALE_INT_MASK
+ */
+# define TV_VSCALE_FRAC_MASK           0x00007fff
+# define TV_VSCALE_FRAC_SHIFT          0
+
+#define TV_FILTER_CTL_3                0x68088
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ */
+# define TV_VSCALE_IP_INT_MASK         0x00038000
+# define TV_VSCALE_IP_INT_SHIFT                15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ *
+ * \sa TV_VSCALE_IP_INT_MASK
+ */
+# define TV_VSCALE_IP_FRAC_MASK                0x00007fff
+# define TV_VSCALE_IP_FRAC_SHIFT               0
+
+#define TV_CC_CONTROL          0x68090
+# define TV_CC_ENABLE                  (1 << 31)
+/**
+ * Specifies which field to send the CC data in.
+ *
+ * CC data is usually sent in field 0.
+ */
+# define TV_CC_FID_MASK                        (1 << 27)
+# define TV_CC_FID_SHIFT               27
+/** Sets the horizontal position of the CC data.  Usually 135. */
+# define TV_CC_HOFF_MASK               0x03ff0000
+# define TV_CC_HOFF_SHIFT              16
+/** Sets the vertical position of the CC data.  Usually 21 */
+# define TV_CC_LINE_MASK               0x0000003f
+# define TV_CC_LINE_SHIFT              0
+
+#define TV_CC_DATA             0x68094
+# define TV_CC_RDY                     (1 << 31)
+/** Second word of CC data to be transmitted. */
+# define TV_CC_DATA_2_MASK             0x007f0000
+# define TV_CC_DATA_2_SHIFT            16
+/** First word of CC data to be transmitted. */
+# define TV_CC_DATA_1_MASK             0x0000007f
+# define TV_CC_DATA_1_SHIFT            0
+
+#define TV_H_LUMA_0            0x68100
+#define TV_H_LUMA_59           0x681ec
+#define TV_H_CHROMA_0          0x68200
+#define TV_H_CHROMA_59         0x682ec
+#define TV_V_LUMA_0            0x68300
+#define TV_V_LUMA_42           0x683a8
+#define TV_V_CHROMA_0          0x68400
+#define TV_V_CHROMA_42         0x684a8
+
+/* Display & cursor control */
+
+/* Pipe A */
+#define PIPEADSL               0x70000
+#define PIPEACONF              0x70008
+#define   PIPEACONF_ENABLE     (1<<31)
+#define   PIPEACONF_DISABLE    0
+#define   PIPEACONF_DOUBLE_WIDE        (1<<30)
+#define   I965_PIPECONF_ACTIVE (1<<30)
+#define   PIPEACONF_SINGLE_WIDE        0
+#define   PIPEACONF_PIPE_UNLOCKED 0
+#define   PIPEACONF_PIPE_LOCKED        (1<<25)
+#define   PIPEACONF_PALETTE    0
+#define   PIPEACONF_GAMMA              (1<<24)
+#define   PIPECONF_FORCE_BORDER        (1<<25)
+#define   PIPECONF_PROGRESSIVE (0 << 21)
+#define   PIPECONF_INTERLACE_W_FIELD_INDICATION        (6 << 21)
+#define   PIPECONF_INTERLACE_FIELD_0_ONLY              (7 << 21)
+#define PIPEASTAT              0x70024
+#define   PIPE_FIFO_UNDERRUN_STATUS            (1UL<<31)
+#define   PIPE_CRC_ERROR_ENABLE                        (1UL<<29)
+#define   PIPE_CRC_DONE_ENABLE                 (1UL<<28)
+#define   PIPE_GMBUS_EVENT_ENABLE              (1UL<<27)
+#define   PIPE_HOTPLUG_INTERRUPT_ENABLE                (1UL<<26)
+#define   PIPE_VSYNC_INTERRUPT_ENABLE          (1UL<<25)
+#define   PIPE_DISPLAY_LINE_COMPARE_ENABLE     (1UL<<24)
+#define   PIPE_DPST_EVENT_ENABLE               (1UL<<23)
+#define   PIPE_LEGACY_BLC_EVENT_ENABLE         (1UL<<22)
+#define   PIPE_ODD_FIELD_INTERRUPT_ENABLE      (1UL<<21)
+#define   PIPE_EVEN_FIELD_INTERRUPT_ENABLE     (1UL<<20)
+#define   PIPE_HOTPLUG_TV_INTERRUPT_ENABLE     (1UL<<18) /* pre-965 */
+#define   PIPE_START_VBLANK_INTERRUPT_ENABLE   (1UL<<18) /* 965 or later */
+#define   PIPE_VBLANK_INTERRUPT_ENABLE         (1UL<<17)
+#define   PIPE_OVERLAY_UPDATED_ENABLE          (1UL<<16)
+#define   PIPE_CRC_ERROR_INTERRUPT_STATUS      (1UL<<13)
+#define   PIPE_CRC_DONE_INTERRUPT_STATUS       (1UL<<12)
+#define   PIPE_GMBUS_INTERRUPT_STATUS          (1UL<<11)
+#define   PIPE_HOTPLUG_INTERRUPT_STATUS                (1UL<<10)
+#define   PIPE_VSYNC_INTERRUPT_STATUS          (1UL<<9)
+#define   PIPE_DISPLAY_LINE_COMPARE_STATUS     (1UL<<8)
+#define   PIPE_DPST_EVENT_STATUS               (1UL<<7)
+#define   PIPE_LEGACY_BLC_EVENT_STATUS         (1UL<<6)
+#define   PIPE_ODD_FIELD_INTERRUPT_STATUS      (1UL<<5)
+#define   PIPE_EVEN_FIELD_INTERRUPT_STATUS     (1UL<<4)
+#define   PIPE_HOTPLUG_TV_INTERRUPT_STATUS     (1UL<<2) /* pre-965 */
+#define   PIPE_START_VBLANK_INTERRUPT_STATUS   (1UL<<2) /* 965 or later */
+#define   PIPE_VBLANK_INTERRUPT_STATUS         (1UL<<1)
+#define   PIPE_OVERLAY_UPDATED_STATUS          (1UL<<0)
+
+#define DSPARB                 0x70030
+#define   DSPARB_CSTART_MASK   (0x7f << 7)
+#define   DSPARB_CSTART_SHIFT  7
+#define   DSPARB_BSTART_MASK   (0x7f)
+#define   DSPARB_BSTART_SHIFT  0
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code
+ * should work:
+ *
+ *  do {
+ *    high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ *             PIPE_FRAME_HIGH_SHIFT;
+ *    low1 =  ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
+ *             PIPE_FRAME_LOW_SHIFT);
+ *    high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ *             PIPE_FRAME_HIGH_SHIFT);
+ *  } while (high1 != high2);
+ *  frame = (high1 << 8) | low1;
+ */
+#define PIPEAFRAMEHIGH          0x70040
+#define   PIPE_FRAME_HIGH_MASK    0x0000ffff
+#define   PIPE_FRAME_HIGH_SHIFT   0
+#define PIPEAFRAMEPIXEL         0x70044
+#define   PIPE_FRAME_LOW_MASK     0xff000000
+#define   PIPE_FRAME_LOW_SHIFT    24
+#define   PIPE_PIXEL_MASK         0x00ffffff
+#define   PIPE_PIXEL_SHIFT        0
+
+/* Cursor A & B regs */
+#define CURACNTR               0x70080
+#define   CURSOR_MODE_DISABLE   0x00
+#define   CURSOR_MODE_64_32B_AX 0x07
+#define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_GAMMA_ENABLE  (1 << 26)
+#define CURABASE               0x70084
+#define CURAPOS                        0x70088
+#define   CURSOR_POS_MASK       0x007FF
+#define   CURSOR_POS_SIGN       0x8000
+#define   CURSOR_X_SHIFT        0
+#define   CURSOR_Y_SHIFT        16
+#define CURBCNTR               0x700c0
+#define CURBBASE               0x700c4
+#define CURBPOS                        0x700c8
+
+/* Display A control */
+#define DSPACNTR                0x70180
+#define   DISPLAY_PLANE_ENABLE                 (1<<31)
+#define   DISPLAY_PLANE_DISABLE                        0
+#define   DISPPLANE_GAMMA_ENABLE               (1<<30)
+#define   DISPPLANE_GAMMA_DISABLE              0
+#define   DISPPLANE_PIXFORMAT_MASK             (0xf<<26)
+#define   DISPPLANE_8BPP                       (0x2<<26)
+#define   DISPPLANE_15_16BPP                   (0x4<<26)
+#define   DISPPLANE_16BPP                      (0x5<<26)
+#define   DISPPLANE_32BPP_NO_ALPHA             (0x6<<26)
+#define   DISPPLANE_32BPP                      (0x7<<26)
+#define   DISPPLANE_STEREO_ENABLE              (1<<25)
+#define   DISPPLANE_STEREO_DISABLE             0
+#define   DISPPLANE_SEL_PIPE_MASK              (1<<24)
+#define   DISPPLANE_SEL_PIPE_A                 0
+#define   DISPPLANE_SEL_PIPE_B                 (1<<24)
+#define   DISPPLANE_SRC_KEY_ENABLE             (1<<22)
+#define   DISPPLANE_SRC_KEY_DISABLE            0
+#define   DISPPLANE_LINE_DOUBLE                        (1<<20)
+#define   DISPPLANE_NO_LINE_DOUBLE             0
+#define   DISPPLANE_STEREO_POLARITY_FIRST      0
+#define   DISPPLANE_STEREO_POLARITY_SECOND     (1<<18)
+#define DSPAADDR               0x70184
+#define DSPASTRIDE             0x70188
+#define DSPAPOS                        0x7018C /* reserved */
+#define DSPASIZE               0x70190
+#define DSPASURF               0x7019C /* 965+ only */
+#define DSPATILEOFF            0x701A4 /* 965+ only */
+
+/* VBIOS flags */
+#define SWF00                  0x71410
+#define SWF01                  0x71414
+#define SWF02                  0x71418
+#define SWF03                  0x7141c
+#define SWF04                  0x71420
+#define SWF05                  0x71424
+#define SWF06                  0x71428
+#define SWF10                  0x70410
+#define SWF11                  0x70414
+#define SWF14                  0x71420
+#define SWF30                  0x72414
+#define SWF31                  0x72418
+#define SWF32                  0x7241c
+
+/* Pipe B */
+#define PIPEBDSL               0x71000
+#define PIPEBCONF              0x71008
+#define PIPEBSTAT              0x71024
+#define PIPEBFRAMEHIGH         0x71040
+#define PIPEBFRAMEPIXEL                0x71044
+
+/* Display B control */
+#define DSPBCNTR               0x71180
+#define   DISPPLANE_ALPHA_TRANS_ENABLE         (1<<15)
+#define   DISPPLANE_ALPHA_TRANS_DISABLE                0
+#define   DISPPLANE_SPRITE_ABOVE_DISPLAY       0
+#define   DISPPLANE_SPRITE_ABOVE_OVERLAY       (1)
+#define DSPBADDR               0x71184
+#define DSPBSTRIDE             0x71188
+#define DSPBPOS                        0x7118C
+#define DSPBSIZE               0x71190
+#define DSPBSURF               0x7119C
+#define DSPBTILEOFF            0x711A4
+
+/* VBIOS regs */
+#define VGACNTRL               0x71400
+# define VGA_DISP_DISABLE                      (1 << 31)
+# define VGA_2X_MODE                           (1 << 30)
+# define VGA_PIPE_B_SELECT                     (1 << 29)
+
+#endif /* _I915_REG_H_ */