.type = INTEL_AGP_CACHED_MEMORY}
 };
 
+#define INTEL_AGP_UNCACHED_MEMORY              0
+#define INTEL_AGP_CACHED_MEMORY_LLC            1
+#define INTEL_AGP_CACHED_MEMORY_LLC_GFDT       2
+#define INTEL_AGP_CACHED_MEMORY_LLC_MLC        3
+#define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT   4
+
+static struct gatt_mask intel_gen6_masks[] =
+{
+       {.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED,
+        .type = INTEL_AGP_UNCACHED_MEMORY },
+       {.mask = I810_PTE_VALID | GEN6_PTE_LLC,
+         .type = INTEL_AGP_CACHED_MEMORY_LLC },
+       {.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT,
+         .type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT },
+       {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC,
+         .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC },
+       {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT,
+         .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT },
+};
+
 static struct _intel_private {
        struct pci_dev *pcidev; /* device one */
        u8 __iomem *registers;
                                        off_t pg_start, int mask_type)
 {
        int i, j;
-       u32 cache_bits = 0;
-
-       if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
-           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
-       {
-               cache_bits = GEN6_PTE_LLC_MLC;
-       }
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(agp_bridge->driver->mask_memory(agp_bridge,
                return 0;
 }
 
+static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge,
+                                       int type)
+{
+       unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT;
+       unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT;
+
+       if (type_mask == AGP_USER_UNCACHED_MEMORY)
+               return INTEL_AGP_UNCACHED_MEMORY;
+       else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
+               return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT :
+                             INTEL_AGP_CACHED_MEMORY_LLC_MLC;
+       else /* set 'normal'/'cached' to LLC by default */
+               return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT :
+                             INTEL_AGP_CACHED_MEMORY_LLC;
+}
+
+
 static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
                                int type)
 {
 
        mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
 
-       if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
+       if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
            mask_type != INTEL_AGP_CACHED_MEMORY)
                goto out_err;
 
        .fetch_size             = intel_i9xx_fetch_size,
        .cleanup                = intel_i915_cleanup,
        .mask_memory            = intel_gen6_mask_memory,
-       .masks                  = intel_i810_masks,
+       .masks                  = intel_gen6_masks,
        .agp_enable             = intel_i810_agp_enable,
        .cache_flush            = global_cache_flush,
        .create_gatt_table      = intel_i965_create_gatt_table,
        .agp_alloc_pages        = agp_generic_alloc_pages,
        .agp_destroy_page       = agp_generic_destroy_page,
        .agp_destroy_pages      = agp_generic_destroy_pages,
-       .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
+       .agp_type_to_mask_type  = intel_gen6_type_to_mask_type,
        .chipset_flush          = intel_i915_chipset_flush,
 #ifdef USE_PCI_DMA_API
        .agp_map_page           = intel_agp_map_page,