A few months ago jcs@ got a sandybridge laptop, he did some work to get
it almost working. I continued this a few months ago in edmonton at
c2k11. Since then kettenis@ who has hardware has made yet more progress.

Now the plan is to get this into the tree, but first some precursors.

This kernel patch is just the very basic bits needed to get sandybridge
working, the extra ringsbuffers (BSD, blit) are not in this patch (I
have half to 2/3 of a diff for that). Nor are the requisit xserver bits.
For now some extra testing is required to make sure these patches don't
break any existing setups so that they can go in and work can progress.

So please mail me and kettenis@ privately if this patch regresses your
inteldrm(4) using hardware. Reports that this does nothing other than
attach for sandybridge right now are not necessary. We know.

Cheers,

-0-
-- 
It took me fifteen years to discover that I had no talent for writing,
but I couldn't give up because by that time I was too famous.
                -- Robert Benchley


diff --git dev/pci/agp_i810.c dev/pci/agp_i810.c
index 41b9189..b62610e 100644
--- dev/pci/agp_i810.c
+++ dev/pci/agp_i810.c
@@ -71,6 +71,7 @@ enum {
        CHIP_G4X        = 7,    /* G4X */
        CHIP_PINEVIEW   = 8,    /* Pineview/Pineview M */
        CHIP_IRONLAKE   = 9,    /* Clarkdale/Arrandale */
+       CHIP_SANDYBRIDGE=10,    /* Sandybridge */
 };
 
 struct agp_i810_softc {
@@ -183,13 +184,23 @@ agp_i810_get_chiptype(struct pci_attach_args *pa)
        case PCI_PRODUCT_INTEL_82G45_IGD_1:
        case PCI_PRODUCT_INTEL_82G41_IGD_1:
                return (CHIP_G4X);
+               break;
        case PCI_PRODUCT_INTEL_PINEVIEW_IGC_1:
        case PCI_PRODUCT_INTEL_PINEVIEW_M_IGC_1:
                return (CHIP_PINEVIEW);
+               break;
        case PCI_PRODUCT_INTEL_CLARKDALE_IGD:
        case PCI_PRODUCT_INTEL_ARRANDALE_IGD:
                return (CHIP_IRONLAKE);
                break;
+       case PCI_PRODUCT_INTEL_CORE2G_GT1:
+       case PCI_PRODUCT_INTEL_CORE2G_M_GT1:
+       case PCI_PRODUCT_INTEL_CORE2G_GT2:
+       case PCI_PRODUCT_INTEL_CORE2G_M_GT2:
+       case PCI_PRODUCT_INTEL_CORE2G_GT2_PLUS:
+       case PCI_PRODUCT_INTEL_CORE2G_M_GT2_PLUS:
+               return (CHIP_SANDYBRIDGE);
+               break;
        }
        return (CHIP_NONE);
 }
@@ -246,6 +257,7 @@ agp_i810_attach(struct device *parent, struct device *self, 
void *aux)
        case CHIP_I965:
        case CHIP_G4X:
        case CHIP_IRONLAKE:
+       case CHIP_SANDYBRIDGE:
                gmaddr = AGP_I965_GMADR;
                mmaddr = AGP_I965_MMADR;
                memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT;
@@ -477,6 +489,85 @@ agp_i810_attach(struct device *parent, struct device 
*self, void *aux)
                gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1;
                break;
 
+       case CHIP_SANDYBRIDGE:
+
+               /* Stolen memory is set up at the beginning of the aperture by
+                * the BIOS, consisting of the GATT followed by 4kb for the
+                * BIOS display.
+                */
+
+               gcc1 = (u_int16_t)pci_conf_read(bpa.pa_pc, bpa.pa_tag,
+                   AGP_INTEL_SNB_GMCH_CTRL);
+
+               stolen = 4;
+
+               switch (gcc1 & AGP_INTEL_SNB_GMCH_GMS_STOLEN_MASK) {
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_32M:
+                       isc->stolen = (32768 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_64M:
+                       isc->stolen = (65536 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_96M:
+                       isc->stolen = (98304 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_128M:
+                       isc->stolen = (131072 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_160M:
+                       isc->stolen = (163840 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_192M:
+                       isc->stolen = (196608 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_224M:
+                       isc->stolen = (229376 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_256M:
+                       isc->stolen = (262144 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_288M:
+                       isc->stolen = (294912 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_320M:
+                       isc->stolen = (327680 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_352M:
+                       isc->stolen = (360448 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_384M:
+                       isc->stolen = (393216 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_416M:
+                       isc->stolen = (425984 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_448M:
+                       isc->stolen = (458752 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_480M:
+                       isc->stolen = (491520 - stolen) * 1024 / 4096;
+                       break;
+               case AGP_INTEL_SNB_GMCH_GMS_STOLEN_512M:
+                       isc->stolen = (524288 - stolen) * 1024 / 4096;
+                       break;
+               default:
+                       isc->stolen = 0;
+                       printf("unknown memory configuration, disabling\n");
+                       goto out;
+               }
+
+#ifdef DEBUG
+               if (isc->stolen > 0) {
+                       printf(": detected %dk stolen memory",
+                           isc->stolen * 4);
+               } else
+                       printf(": no preallocated video memory\n");
+#endif
+
+               /* GATT address is already in there, make sure it's enabled */
+               gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1;
+               break;
+
        default:
                printf(": unknown initialisation\n");
                return;
@@ -532,6 +623,7 @@ agp_i810_activate(struct device *arg, int act)
                break;
        case CHIP_G4X:
        case CHIP_IRONLAKE:
+       case CHIP_SANDYBRIDGE:
                offset = AGP_G4X_GTT;
                break;
        default:
@@ -833,7 +925,8 @@ intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t 
off, paddr_t v)
 
        if (isc->chiptype != CHIP_I810 &&
            (off >> AGP_PAGE_SHIFT) < isc->stolen) {
-               printf("intagp: binding into stolen memory!\n");
+               printf("intagp: binding into stolen memory! (0x%lx)\n",
+                       (off >> AGP_PAGE_SHIFT));
        }
 
        if (v != 0) {
@@ -843,7 +936,8 @@ intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t 
off, paddr_t v)
                    isc->chiptype == CHIP_G4X ||
                    isc->chiptype == CHIP_PINEVIEW ||
                    isc->chiptype == CHIP_G33 ||
-                   isc->chiptype == CHIP_IRONLAKE) {
+                   isc->chiptype == CHIP_IRONLAKE ||
+                   isc->chiptype == CHIP_SANDYBRIDGE) {
                        pte |= (v & 0x0000000f00000000ULL) >> 28;
                }
        }
@@ -863,6 +957,7 @@ intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t 
off, paddr_t v)
                break;
        case CHIP_G4X:
        case CHIP_IRONLAKE:
+       case CHIP_SANDYBRIDGE:
                baseoff = AGP_G4X_GTT;
                break;
        default:
diff --git dev/pci/agpreg.h dev/pci/agpreg.h
index 4e3af78..47d5748 100644
--- dev/pci/agpreg.h
+++ dev/pci/agpreg.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD$       */
+/*     $OpenBSD: agpreg.h,v 1.12 2008/12/24 05:42:58 oga Exp $ */
 /*     $NetBSD: agpreg.h,v 1.1 2001/09/10 10:01:02 fvdl Exp $  */
 
 /*-
@@ -275,4 +275,26 @@
 #define AGP_INTEL_GMCH_GMS_STOLEN_352M 0xd0
 #define        AGP_G4X_GTT                     0x200000
 
+/*
+ * Intel Sandybridge registers and values
+ */
+#define AGP_INTEL_SNB_GMCH_CTRL                        0x50
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_MASK     0xF8
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_32M      (1 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_64M      (2 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_96M      (3 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_128M     (4 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_160M     (5 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_192M     (6 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_224M     (7 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_256M     (8 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_288M     (9 << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_320M     (0xa << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_352M     (0xb << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_384M     (0xc << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_416M     (0xd << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_448M     (0xe << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_480M     (0xf << 3)
+#define AGP_INTEL_SNB_GMCH_GMS_STOLEN_512M     (0x10 << 3)
+
 #endif /* !_PCI_AGPREG_H_ */
diff --git dev/pci/drm/i915_drv.c dev/pci/drm/i915_drv.c
index edb5f32..ab9cf34 100644
--- dev/pci/drm/i915_drv.c
+++ dev/pci/drm/i915_drv.c
@@ -194,6 +194,7 @@ bus_size_t  i915_gem_get_gtt_alignment(struct drm_obj *);
 bus_size_t     i915_get_fence_size(struct inteldrm_softc *, bus_size_t);
 int    i915_tiling_ok(struct drm_device *, int, int, int);
 int    i915_gem_object_fence_offset_ok(struct drm_obj *, int);
+void   sandybridge_write_fence_reg(struct inteldrm_fence *);
 void   i965_write_fence_reg(struct inteldrm_fence *);
 void   i915_write_fence_reg(struct inteldrm_fence *);
 void   i830_write_fence_reg(struct inteldrm_fence *);
@@ -272,6 +273,18 @@ const static struct drm_pcidev inteldrm_pciidlist[] = {
            CHIP_IRONLAKE|CHIP_IRONLAKE_D|CHIP_I965|CHIP_I9XX|CHIP_HWS},
        {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ARRANDALE_IGD,
            CHIP_IRONLAKE|CHIP_M|CHIP_IRONLAKE_M|CHIP_I965|CHIP_I9XX|CHIP_HWS},
+       {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE2G_GT1,
+           CHIP_SANDYBRIDGE|CHIP_I965|CHIP_I9XX|CHIP_HWS|CHIP_GEN6},
+       {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE2G_M_GT1,
+           CHIP_SANDYBRIDGE|CHIP_M|CHIP_I965|CHIP_I9XX|CHIP_HWS|CHIP_GEN6},
+       {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE2G_GT2,
+           CHIP_SANDYBRIDGE|CHIP_I965|CHIP_I9XX|CHIP_HWS|CHIP_GEN6},
+       {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE2G_M_GT2,
+           CHIP_SANDYBRIDGE|CHIP_M|CHIP_I965|CHIP_I9XX|CHIP_HWS|CHIP_GEN6},
+       {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE2G_GT2_PLUS,
+           CHIP_SANDYBRIDGE|CHIP_I965|CHIP_I9XX|CHIP_HWS|CHIP_GEN6},
+       {PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE2G_M_GT2_PLUS,
+           CHIP_SANDYBRIDGE|CHIP_M|CHIP_I965|CHIP_I9XX|CHIP_HWS|CHIP_GEN6},
        {0, 0, 0}
 };
 
@@ -434,8 +447,12 @@ inteldrm_attach(struct device *parent, struct device 
*self, void *aux)
                dev_priv->num_fence_regs = 16;
        else
                dev_priv->num_fence_regs = 8;
+
        /* Initialise fences to zero, else on some macs we'll get corruption */
-       if (IS_I965G(dev_priv)) {
+       if (IS_GEN6(dev_priv)) {
+               for (i = 0; i < 16; i++)
+                       I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), 0);
+       } else if (IS_I965G(dev_priv)) {
                for (i = 0; i < 16; i++)
                        I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0);
        } else {
@@ -1628,11 +1645,14 @@ i915_add_request(struct inteldrm_softc *dev_priv)
        if (dev_priv->mm.next_gem_seqno == 0)
                dev_priv->mm.next_gem_seqno++;
 
-       BEGIN_LP_RING(4);
+       if (IS_GEN6(dev_priv))
+               BEGIN_LP_RING(10);
+       else 
+               BEGIN_LP_RING(4);
+
        OUT_RING(MI_STORE_DWORD_INDEX);
        OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
        OUT_RING(seqno);
-
        OUT_RING(MI_USER_INTERRUPT);
        ADVANCE_LP_RING();
 
@@ -2130,6 +2150,28 @@ i915_gem_get_gtt_alignment(struct drm_obj *obj)
 }
 
 void
+sandybridge_write_fence_reg(struct inteldrm_fence *reg)
+{
+       struct drm_obj          *obj = reg->obj;
+       struct drm_device       *dev = obj->dev;
+       struct inteldrm_softc   *dev_priv = dev->dev_private;
+       struct inteldrm_obj     *obj_priv = (struct inteldrm_obj *)obj;
+       int                      regnum = obj_priv->fence_reg;
+       u_int64_t                val;
+
+       val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) &
+                   0xfffff000) << 32;
+       val |= obj_priv->gtt_offset & 0xfffff000;
+       val |= (uint64_t)((obj_priv->stride / 128) - 1) <<
+                   SANDYBRIDGE_FENCE_PITCH_SHIFT;
+       if (obj_priv->tiling_mode == I915_TILING_Y)
+               val |= 1 << I965_FENCE_TILING_Y_SHIFT;
+       val |= I965_FENCE_REG_VALID;
+
+       I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val);
+}
+
+void
 i965_write_fence_reg(struct inteldrm_fence *reg)
 {
        struct drm_obj          *obj = reg->obj;
@@ -2357,7 +2399,9 @@ again:
        reg->obj = obj;
        TAILQ_INSERT_TAIL(&dev_priv->mm.fence_list, reg, list);
 
-       if (IS_I965G(dev_priv))
+       if (IS_GEN6(dev_priv))
+               sandybridge_write_fence_reg(reg);
+       else if (IS_I965G(dev_priv))
                i965_write_fence_reg(reg);
        else if (IS_I9XX(dev_priv))
                i915_write_fence_reg(reg);
@@ -2741,6 +2785,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_obj *obj, 
int write,
        /* Not valid to be called on unbound objects. */
        if (obj_priv->dmamap == NULL)
                return (EINVAL);
+
        /* Wait on any GPU rendering and flushing to occur. */
        if ((ret = i915_gem_object_flush_gpu_write_domain(obj, 0,
            interruptible, write)) != 0)
@@ -3199,8 +3244,12 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
        } else {
                BEGIN_LP_RING(4);
                if (IS_I965G(dev_priv)) {
-                       OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) |
-                           MI_BATCH_NON_SECURE_I965);
+                       if (IS_GEN6(dev_priv))
+                               OUT_RING(MI_BATCH_BUFFER_START |
+                                   MI_BATCH_NON_SECURE_I965);
+                       else
+                               OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) |
+                                   MI_BATCH_NON_SECURE_I965);
                        OUT_RING(exec_start);
                } else {
                        OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
@@ -4016,8 +4065,13 @@ i915_gem_init_hws(struct inteldrm_softc *dev_priv)
        drm_unhold_object(obj);
        dev_priv->hws_obj = obj;
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
-       I915_WRITE(HWS_PGA, obj_priv->gtt_offset);
-       I915_READ(HWS_PGA); /* posting read */
+       if (IS_GEN6(dev_priv)) {
+               I915_WRITE(HWS_PGA_GEN6, obj_priv->gtt_offset);
+               I915_READ(HWS_PGA_GEN6); /* posting read */
+       } else {
+               I915_WRITE(HWS_PGA, obj_priv->gtt_offset);
+               I915_READ(HWS_PGA); /* posting read */
+       }
        DRM_DEBUG("hws offset: 0x%08x\n", obj_priv->gtt_offset);
 
        return 0;
@@ -4042,7 +4096,11 @@ i915_gem_cleanup_hws(struct inteldrm_softc *dev_priv)
        dev_priv->hws_obj = NULL;
 
        /* Write high address into HWS_PGA when disabling. */
-       I915_WRITE(HWS_PGA, 0x1ffff000);
+       if (IS_GEN6(dev_priv)) {
+               I915_WRITE(HWS_PGA_GEN6, 0x1ffff000);
+       } else {
+               I915_WRITE(HWS_PGA, 0x1ffff000);
+       }
 }
 
 int
@@ -4139,7 +4197,10 @@ inteldrm_start_ring(struct inteldrm_softc *dev_priv)
        /* Update our cache of the ring state */
        inteldrm_update_ring(dev_priv);
 
-       if (IS_I9XX(dev_priv) && !IS_GEN3(dev_priv))
+       if (IS_GEN6(dev_priv))
+               I915_WRITE(MI_MODE | MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE,
+                   (VS_TIMER_DISPATCH) << 15 | VS_TIMER_DISPATCH);
+       else if (IS_I9XX(dev_priv) && !IS_GEN3(dev_priv))
                I915_WRITE(MI_MODE, (VS_TIMER_DISPATCH) << 15 |
                    VS_TIMER_DISPATCH);
 
@@ -4242,7 +4303,7 @@ inteldrm_error(struct inteldrm_softc *dev_priv)
        }
 
        printf("render error detected, EIR: %b\n", eir, errbitstr);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (IS_IRONLAKE(dev_priv) || IS_GEN6(dev_priv)) {
                if (eir & GT_ERROR_PTE) {
                        dev_priv->mm.wedged = 1;
                        reset = GDRST_FULL;
@@ -4328,7 +4389,7 @@ inteldrm_error(struct inteldrm_softc *dev_priv)
                if (dev_priv->mm.wedged == 0)
                        DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir);
                I915_WRITE(EMR, I915_READ(EMR) | eir);
-               if (IS_IRONLAKE(dev_priv)) {
+               if (IS_IRONLAKE(dev_priv) || IS_GEN6(dev_priv)) {
                        I915_WRITE(GTIIR, GT_MASTER_ERROR);
                } else {
                        I915_WRITE(IIR,
@@ -5075,15 +5136,11 @@ inteldrm_pipe_enabled(struct inteldrm_softc *dev_priv, 
int pipe)
 {
        bus_size_t      pipeconf;
 
-#if 0
-       if (IS_IRONLAKE(dev_priv)) {
+       if (IS_IRONLAKE(dev_priv) || IS_GEN6(dev_priv)) {
                pipeconf = (pipe ? PCH_DPLL_A : PCH_DPLL_B);
        } else {
-#endif
                pipeconf = (pipe ? PIPEBCONF : PIPEACONF);
-#if 0
        }
-#endif
        return ((I915_READ(pipeconf) & PIPEACONF_ENABLE) == PIPEACONF_ENABLE);
 }
 
@@ -5100,7 +5157,7 @@ i915_save_palette(struct inteldrm_softc *dev_priv, enum 
pipe pipe)
        if (!inteldrm_pipe_enabled(dev_priv, pipe))
                return;
 
-       if (IS_IRONLAKE(dev_priv))
+       if (HAS_PCH_SPLIT(dev_priv))
                reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
 
        if (pipe == PIPE_A)
@@ -5122,7 +5179,7 @@ i915_restore_palette(struct inteldrm_softc *dev_priv, 
enum pipe pipe)
        if (!inteldrm_pipe_enabled(dev_priv, pipe))
                return;
 
-       if (IS_IRONLAKE(dev_priv))
+       if (HAS_PCH_SPLIT(dev_priv))
                reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
 
        if (pipe == PIPE_A)
@@ -5284,7 +5341,7 @@ void
 i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
 {
 
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
                dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
        }
@@ -5292,7 +5349,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
        /* Pipe & plane A info */
        dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
        dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
                dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
                dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
@@ -5301,7 +5358,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
                dev_priv->saveFPA1 = I915_READ(FPA1);
                dev_priv->saveDPLL_A = I915_READ(DPLL_A);
        }
-       if (IS_I965G(dev_priv) && !IS_IRONLAKE(dev_priv))
+       if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
                dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
        dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
        dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
@@ -5309,7 +5366,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
        dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
        dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
        dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
                dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
                dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
@@ -5348,7 +5405,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
        /* Pipe & plane B info */
        dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
        dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->saveFPA0 = I915_READ(PCH_FPB0);
                dev_priv->saveFPA1 = I915_READ(PCH_FPB1);
                dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_B);
@@ -5357,7 +5414,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
                dev_priv->saveFPB1 = I915_READ(FPB1);
                dev_priv->saveDPLL_B = I915_READ(DPLL_B);
        }
-       if (IS_I965G(dev_priv) && !IS_IRONLAKE(dev_priv))
+       if (IS_I965G(dev_priv) && (!IS_IRONLAKE(dev_priv) && 
!IS_GEN6(dev_priv)))
                dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
        dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
        dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
@@ -5365,7 +5422,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
        dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
        dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
        dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
                dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
                dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
@@ -5394,7 +5451,7 @@ i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
        dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
        dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
        dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
-       if (IS_I965GM(dev_priv) || IS_GM45(dev_priv)) {
+       if (IS_I965GM(dev_priv) || IS_GM45(dev_priv)) { /* XXX: IS_MOBILE ? */
                dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
                dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
        }
@@ -5408,7 +5465,7 @@ i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
        bus_size_t      dpll_a_reg, fpa0_reg, fpa1_reg;
        bus_size_t      dpll_b_reg, fpb0_reg, fpb1_reg;
 
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dpll_a_reg = PCH_DPLL_A;
                dpll_b_reg = PCH_DPLL_B;
                fpa0_reg = PCH_FPA0;
@@ -5424,7 +5481,7 @@ i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
                fpb1_reg = FPB1;
        }
 
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
                I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
        }
@@ -5441,7 +5498,7 @@ i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
        /* Actually enable it */
        I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
        DRM_UDELAY(150);
-       if (IS_I965G(dev_priv) && !IS_IRONLAKE(dev_priv))
+       if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
        DRM_UDELAY(150);
 
@@ -5452,7 +5509,7 @@ i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
        I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
        I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
        I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
                I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
                I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
@@ -5505,7 +5562,7 @@ i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
        /* Actually enable it */
        I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
        DRM_UDELAY(150);
-       if (IS_I965G(dev_priv) && !IS_IRONLAKE(dev_priv))
+       if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
        DRM_UDELAY(150);
 
@@ -5516,7 +5573,7 @@ i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
        I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
        I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
        I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
                I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
                I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
@@ -5579,14 +5636,14 @@ inteldrm_save_display(struct inteldrm_softc *dev_priv)
                dev_priv->saveCURSIZE = I915_READ(CURSIZE);
 
        /* CRT state */
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->saveADPA = I915_READ(PCH_ADPA);
        } else {
                dev_priv->saveADPA = I915_READ(ADPA);
        }
 
        /* LVDS state */
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
                dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
                dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
@@ -5603,9 +5660,11 @@ inteldrm_save_display(struct inteldrm_softc *dev_priv)
                if (IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
                        dev_priv->saveLVDS = I915_READ(LVDS);
        }
-       if (!IS_I830(dev_priv) && !IS_845G(dev_priv))
+
+       if (!IS_I830(dev_priv) && !IS_845G(dev_priv) && 
!HAS_PCH_SPLIT(dev_priv))
                dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
-       if (IS_IRONLAKE(dev_priv)) {
+
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
                dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
                dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
@@ -5631,7 +5690,7 @@ inteldrm_save_display(struct inteldrm_softc *dev_priv)
        dev_priv->saveVGA0 = I915_READ(VGA0);
        dev_priv->saveVGA1 = I915_READ(VGA1);
        dev_priv->saveVGA_PD = I915_READ(VGA_PD);
-       if (IS_IRONLAKE(dev_priv))
+       if (HAS_PCH_SPLIT(dev_priv))
                dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
        else
                dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
@@ -5661,24 +5720,24 @@ inteldrm_restore_display(struct inteldrm_softc 
*dev_priv)
                I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
 
        /* CRT state */
-       if (IS_IRONLAKE(dev_priv))
+       if (HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
        else
                I915_WRITE(ADPA, dev_priv->saveADPA);
 
        /* LVDS state */
-       if (IS_I965G(dev_priv) && !IS_IRONLAKE(dev_priv))
+       if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
 
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
        } else if (IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
                I915_WRITE(LVDS, dev_priv->saveLVDS);
 
-       if (!IS_I830(dev_priv) && !IS_845G(dev_priv) && !IS_IRONLAKE(dev_priv))
+       if (!IS_I830(dev_priv) && !IS_845G(dev_priv) && 
!HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
 
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
                I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
                I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
@@ -5712,7 +5771,7 @@ inteldrm_restore_display(struct inteldrm_softc *dev_priv)
        }
 
        /* VGA state */
-       if (IS_IRONLAKE(dev_priv))
+       if (HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
        else
                I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
@@ -5734,12 +5793,16 @@ inteldrm_save_state(struct inteldrm_softc *dev_priv)
        dev_priv->saveLBB = pci_conf_read(dev_priv->pc, dev_priv->tag, LBB);
 
        /* Hardware status page */
-       dev_priv->saveHWS = I915_READ(HWS_PGA);
+       if (IS_GEN6(dev_priv)) {
+               dev_priv->saveHWS = I915_READ(HWS_PGA_GEN6);
+       } else {
+               dev_priv->saveHWS = I915_READ(HWS_PGA);
+       }
 
        inteldrm_save_display(dev_priv);
 
        /* Interrupt state */
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->saveDEIER = I915_READ(DEIER);
                dev_priv->saveDEIMR = I915_READ(DEIMR);
                dev_priv->saveGTIER = I915_READ(GTIER);
@@ -5754,7 +5817,7 @@ inteldrm_save_state(struct inteldrm_softc *dev_priv)
        }
 
        /* Clock gating state */
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->saveDSPCLK_GATE_D = I915_READ(PCH_DSPCLK_GATE_D);
                dev_priv->saveDSPCLK_GATE = I915_READ(ILK_DSPCLK_GATE);
        } else if (IS_G4X(dev_priv)) {
@@ -5794,7 +5857,11 @@ inteldrm_save_state(struct inteldrm_softc *dev_priv)
                dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
 
        /* Fences */
-       if (IS_I965G(dev_priv)) {
+       if (IS_GEN6(dev_priv)) {
+               for (i = 0; i < 16; i++)
+                       dev_priv->saveFENCE[i] = 
I915_READ64(FENCE_REG_SANDYBRIDGE_0 +
+                           (i * 8));
+       } else if (IS_I965G(dev_priv)) {
                for (i = 0; i < 16; i++)
                        dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 +
                            (i * 8));
@@ -5819,10 +5886,16 @@ inteldrm_restore_state(struct inteldrm_softc *dev_priv)
        pci_conf_write(dev_priv->pc, dev_priv->tag, LBB, dev_priv->saveLBB);
 
        /* Hardware status page */
-       I915_WRITE(HWS_PGA, dev_priv->saveHWS);
+       if (IS_GEN6(dev_priv))
+               I915_WRITE(HWS_PGA_GEN6, dev_priv->saveHWS);
+       else
+               I915_WRITE(HWS_PGA, dev_priv->saveHWS);
 
        /* Fences */
-       if (IS_I965G(dev_priv)) {
+       if (IS_GEN6(dev_priv)) {
+               for (i = 0; i < 16; i++)
+                       I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), 
dev_priv->saveFENCE[i]);
+       } else if (IS_I965G(dev_priv)) {
                for (i = 0; i < 16; i++)
                        I915_WRITE64(FENCE_REG_965_0 + (i * 8), 
dev_priv->saveFENCE[i]);
        } else {
@@ -5837,7 +5910,7 @@ inteldrm_restore_state(struct inteldrm_softc *dev_priv)
        inteldrm_restore_display(dev_priv);
 
        /* Interrupt state */
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(DEIER, dev_priv->saveDEIER);
                I915_WRITE(DEIMR, dev_priv->saveDEIMR);
                I915_WRITE(GTIER, dev_priv->saveGTIER);
@@ -5850,7 +5923,7 @@ inteldrm_restore_state(struct inteldrm_softc *dev_priv)
        }
 
        /* Clock gating state */
-       if (IS_IRONLAKE(dev_priv)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                I915_WRITE(PCH_DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
                I915_WRITE(ILK_DSPCLK_GATE, dev_priv->saveDSPCLK_GATE);
        } if (IS_G4X(dev_priv)) {
@@ -5951,13 +6024,25 @@ inteldrm_965_reset(struct inteldrm_softc *dev_priv, 
u_int8_t flags)
                        panic("can't restart ring, we're fucked");
 
                /* put the hardware status page back */
-               if (I915_NEED_GFX_HWS(dev_priv))
+               if (I915_NEED_GFX_HWS(dev_priv)) {
                        I915_WRITE(HWS_PGA, ((struct inteldrm_obj *)
                            dev_priv->hws_obj)->gtt_offset);
-               else
+                       if (IS_GEN6(dev_priv)) {
+                               I915_WRITE(HWS_PGA_GEN6,
+                                   ((struct inteldrm_obj *)
+                                   dev_priv->hws_obj)->gtt_offset);
+                       } else {
+                               I915_WRITE(HWS_PGA, ((struct inteldrm_obj *)
+                                   dev_priv->hws_obj)->gtt_offset);
+                       }
+               } else {
                        I915_WRITE(HWS_PGA,
                            dev_priv->hws_dmamem->map->dm_segs[0].ds_addr);
-               I915_READ(HWS_PGA); /* posting read */
+               }
+               if (IS_GEN6(dev_priv))
+                       I915_READ(HWS_PGA_GEN6); /* posting read */
+               else
+                       I915_READ(HWS_PGA); /* posting read */
 
                /* so we remove the handler and can put it back in */
                DRM_UNLOCK();
diff --git dev/pci/drm/i915_drv.h dev/pci/drm/i915_drv.h
index 4d8dda0..a03c387 100644
--- dev/pci/drm/i915_drv.h
+++ dev/pci/drm/i915_drv.h
@@ -439,6 +439,7 @@ struct inteldrm_file {
 #define        CHIP_IRONLAKE   0x200000
 #define CHIP_IRONLAKE_D        0x400000
 #define CHIP_IRONLAKE_M        0x800000
+#define CHIP_SANDYBRIDGE       0x1000000
 
 /* flags we use in drm_obj's do_flags */
 #define I915_ACTIVE            0x0010  /* being used by the gpu. */
@@ -767,6 +768,9 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
 #define   I965_FENCE_REG_VALID         (1<<0)
 #define   I965_FENCE_MAX_PITCH_VAL     0x0400
 
+#define FENCE_REG_SANDYBRIDGE_0                0x100000
+#define   SANDYBRIDGE_FENCE_PITCH_SHIFT        32
+
 /*
  * Instruction and interrupt control regs
  */
@@ -801,6 +805,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
 #define INSTDONE1      0x0207c /* 965+ only */
 #define ACTHD_I965     0x02074
 #define HWS_PGA                0x02080
+#define HWS_PGA_GEN6   0x04080
 #define HWS_ADDRESS_MASK       0xfffff000
 #define HWS_START_ADDRESS_SHIFT        4
 #define IPEIR          0x02088
@@ -811,6 +816,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
 
 #define MI_MODE                0x0209c
 #define VS_TIMER_DISPATCH      (1 << 6)
+#define MI_FLUSH_ENABLE                (1 << 11)
 
 #define SCPD0          0x0209c /* 915+ only */
 #define IER            0x020a0
@@ -3051,11 +3057,15 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
 #define IS_IRONLAKE_D(dev_priv) ((dev_priv)->flags & CHIP_IRONLAKE_D)
 #define IS_IRONLAKE_M(dev_priv) ((dev_priv)->flags & CHIP_IRONLAKE_M)
 
+#define IS_SANDYBRIDGE(dev_priv) ((dev_priv)->flags & CHIP_SANDYBRIDGE)
+#define IS_SANDYBRIDGE_D(dev_priv) ((dev_priv)->flags & CHIP_SANDYBRIDGE_D)
+#define IS_SANDYBRIDGE_M(dev_priv) ((dev_priv)->flags & CHIP_SANDYBRIDGE_M)
+
 #define IS_MOBILE(dev_priv) (dev_priv->flags & CHIP_M)
 
 #define I915_NEED_GFX_HWS(dev_priv) (dev_priv->flags & CHIP_HWS)
 
-#define HAS_RESET(dev_priv)    IS_I965G(dev_priv)
+#define HAS_RESET(dev_priv)    IS_I965G(dev_priv) && (!IS_GEN6(dev_priv))
 
 #define IS_GEN2(dev_priv)      (dev_priv->flags & CHIP_GEN2)
 #define IS_GEN3(dev_priv)      (dev_priv->flags & CHIP_GEN3)
diff --git dev/pci/drm/i915_irq.c dev/pci/drm/i915_irq.c
index 1e1183c..4335584 100644
--- dev/pci/drm/i915_irq.c
+++ dev/pci/drm/i915_irq.c
@@ -66,9 +66,15 @@ inline void
 ironlake_enable_graphics_irq(struct inteldrm_softc *dev_priv, u_int32_t mask)
 {
        if ((dev_priv->gt_irq_mask_reg & mask) != 0) {
+               /* XXX imr bullshit */
                dev_priv->gt_irq_mask_reg &= ~mask;
-               I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
-               (void)I915_READ(GTIMR);
+               if (IS_GEN6(dev_priv)) {
+                       I915_WRITE(0x20a8, dev_priv->gt_irq_mask_reg);
+                       (void)I915_READ(0x20a8);
+               } else {
+                       I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
+                       (void)I915_READ(GTIMR);
+               }
        }
 }
 
@@ -77,8 +83,13 @@ ironlake_disable_graphics_irq(struct inteldrm_softc 
*dev_priv, u_int32_t mask)
 {
        if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
                dev_priv->gt_irq_mask_reg |= mask;
-               I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
-               (void)I915_READ(GTIMR);
+               if (IS_GEN6(dev_priv)) {
+                       I915_WRITE(0x20a8, dev_priv->gt_irq_mask_reg);
+                       (void)I915_READ(0x20a8);
+               } else {
+                       I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
+                       (void)I915_READ(GTIMR);
+               }
        }
 }
 
@@ -145,7 +156,8 @@ i915_get_vblank_counter(struct drm_device *dev, int pipe)
        }
 
        /* GM45 just had to be different... */
-       if (IS_GM45(dev_priv) || IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv)) {
+       if (IS_GM45(dev_priv) || IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
+       IS_GEN6(dev_priv)) {
                return (I915_READ(pipe ? PIPEB_FRMCOUNT_GM45 :
                    PIPEA_FRMCOUNT_GM45));
        }
@@ -236,7 +248,7 @@ i915_driver_irq_install(struct drm_device *dev)
        struct inteldrm_softc   *dev_priv = dev->dev_private;
 
        dev->vblank->vb_max = 0xffffff; /* only 24 bits of frame count */
-       if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv))
+       if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) || IS_GEN6(dev_priv))
                dev->vblank->vb_max = 0xffffffff;
 
        I915_WRITE(HWSTAM, 0xeffe);

Reply via email to