Merge branch 'agp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / drivers / char / agp / intel-agp.c
index 148d7e3..1540e69 100644 (file)
@@ -59,6 +59,7 @@
 #define PCI_DEVICE_ID_INTEL_IGDNG_D_HB     0x0040
 #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG     0x0042
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB     0x0044
+#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB            0x0062
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG     0x0046
 
 /* cover 915 and 945 variants */
@@ -91,7 +92,8 @@
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB)
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
 
 extern int agp_memory_reserved;
 
@@ -196,41 +198,39 @@ static void intel_agp_unmap_page(struct page *page, dma_addr_t dma)
                       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 }
 
+static void intel_agp_free_sglist(struct agp_memory *mem)
+{
+       struct sg_table st;
+
+       st.sgl = mem->sg_list;
+       st.orig_nents = st.nents = mem->page_count;
+
+       sg_free_table(&st);
+
+       mem->sg_list = NULL;
+       mem->num_sg = 0;
+}
+
 static int intel_agp_map_memory(struct agp_memory *mem)
 {
+       struct sg_table st;
        struct scatterlist *sg;
        int i;
 
        DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
 
-       if ((mem->page_count * sizeof(*mem->sg_list)) < 2*PAGE_SIZE)
-               mem->sg_list = kcalloc(mem->page_count, sizeof(*mem->sg_list),
-                                      GFP_KERNEL);
-
-       if (mem->sg_list == NULL) {
-               mem->sg_list = vmalloc(mem->page_count * sizeof(*mem->sg_list));
-               mem->sg_vmalloc_flag = 1;
-       }
-
-       if (!mem->sg_list) {
-               mem->sg_vmalloc_flag = 0;
+       if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
                return -ENOMEM;
-       }
-       sg_init_table(mem->sg_list, mem->page_count);
 
-       sg = mem->sg_list;
+       mem->sg_list = sg = st.sgl;
+
        for (i = 0 ; i < mem->page_count; i++, sg = sg_next(sg))
                sg_set_page(sg, mem->pages[i], PAGE_SIZE, 0);
 
        mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list,
                                 mem->page_count, PCI_DMA_BIDIRECTIONAL);
-       if (!mem->num_sg) {
-               if (mem->sg_vmalloc_flag)
-                       vfree(mem->sg_list);
-               else
-                       kfree(mem->sg_list);
-               mem->sg_list = NULL;
-               mem->sg_vmalloc_flag = 0;
+       if (unlikely(!mem->num_sg)) {
+               intel_agp_free_sglist(mem);
                return -ENOMEM;
        }
        return 0;
@@ -242,13 +242,7 @@ static void intel_agp_unmap_memory(struct agp_memory *mem)
 
        pci_unmap_sg(intel_private.pcidev, mem->sg_list,
                     mem->page_count, PCI_DMA_BIDIRECTIONAL);
-       if (mem->sg_vmalloc_flag)
-               vfree(mem->sg_list);
-       else
-               kfree(mem->sg_list);
-       mem->sg_vmalloc_flag = 0;
-       mem->sg_list = NULL;
-       mem->num_sg = 0;
+       intel_agp_free_sglist(mem);
 }
 
 static void intel_agp_insert_sg_entries(struct agp_memory *mem,
@@ -296,7 +290,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(agp_bridge->driver->mask_memory(agp_bridge,
-                              phys_to_gart(page_to_phys(mem->pages[i])), mask_type),
+                               page_to_phys(mem->pages[i]), mask_type),
                       intel_private.gtt+j);
        }
 
@@ -478,8 +472,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
                        global_cache_flush();
                for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                        writel(agp_bridge->driver->mask_memory(agp_bridge,
-                                                              phys_to_gart(page_to_phys(mem->pages[i])),
-                                                              mask_type),
+                                       page_to_phys(mem->pages[i]), mask_type),
                               intel_private.registers+I810_PTE_BASE+(j*4));
                }
                readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
@@ -985,7 +978,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start,
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(agp_bridge->driver->mask_memory(agp_bridge,
-                              phys_to_gart(page_to_phys(mem->pages[i])), mask_type),
+                               page_to_phys(mem->pages[i]), mask_type),
                       intel_private.registers+I810_PTE_BASE+(j*4));
        }
        readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
@@ -1149,6 +1142,12 @@ static int intel_i915_configure(void)
 
        intel_i9xx_setup_flush();
 
+#ifdef USE_PCI_DMA_API 
+       if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+               dev_err(&intel_private.pcidev->dev,
+                       "set gfx device dma mask 36bit failed!\n");
+#endif
+
        return 0;
 }
 
@@ -1344,6 +1343,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
        case PCI_DEVICE_ID_INTEL_G41_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
+       case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
                *gtt_offset = *gtt_size = MB(2);
                break;
        default:
@@ -2341,6 +2341,8 @@ static const struct intel_driver_description {
            "IGDNG/D", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
            "IGDNG/M", NULL, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
+           "IGDNG/MA", NULL, &intel_i965_driver },
        { 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2454,15 +2456,6 @@ static int agp_intel_resume(struct pci_dev *pdev)
        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
        int ret_val;
 
-       pci_restore_state(pdev);
-
-       /* We should restore our graphics device's config space,
-        * as host bridge (00:00) resumes before graphics device (02:00),
-        * then our access to its pci space can work right.
-        */
-       if (intel_private.pcidev)
-               pci_restore_state(intel_private.pcidev);
-
        if (bridge->driver == &intel_generic_driver)
                intel_configure();
        else if (bridge->driver == &intel_850_driver)
@@ -2544,6 +2537,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_G41_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
+       ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
        { }
 };