Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / char / agp / intel-agp.c
index 06e791f..bddcae5 100644 (file)
@@ -150,7 +150,7 @@ static void intel_i810_tlbflush(struct agp_memory *mem)
        return;
 }
 
-static void intel_i810_agp_enable(u32 mode)
+static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode)
 {
        return;
 }
@@ -201,9 +201,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
        temp = agp_bridge->current_size;
        num_entries = A_SIZE_FIX(temp)->num_entries;
 
-       if ((pg_start + mem->page_count) > num_entries) {
+       if ((pg_start + mem->page_count) > num_entries)
                return -EINVAL;
-       }
+
        for (j = pg_start; j < (pg_start + mem->page_count); j++) {
                if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j)))
                        return -EBUSY;
@@ -221,7 +221,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
                        agp_bridge->driver->tlb_flush(mem);
                        return 0;
                }
-               if((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
+               if ((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
                        goto insert;
                return -EINVAL;
        }
@@ -229,8 +229,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
 insert:
        global_cache_flush();
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-               writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
-                               intel_i810_private.registers+I810_PTE_BASE+(j*4));
+               writel(agp_bridge->driver->mask_memory(agp_bridge,
+                       mem->memory[i], mem->type),
+                       intel_i810_private.registers+I810_PTE_BASE+(j*4));
                readl(intel_i810_private.registers+I810_PTE_BASE+(j*4));        /* PCI Posting. */
        }
        global_cache_flush();
@@ -268,7 +269,8 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
                return NULL;
 
        switch (pg_count) {
-       case 1: addr = agp_bridge->driver->agp_alloc_page();
+       case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
+               global_flush_tlb();
                break;
        case 4:
                /* kludge to get 4 physical pages for ARGB cursor */
@@ -285,7 +287,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
        if (new == NULL)
                return NULL;
 
-       new->memory[0] = virt_to_phys(addr);
+       new->memory[0] = virt_to_gart(addr);
        if (pg_count == 4) {
                /* kludge to get 4 physical pages for ARGB cursor */
                new->memory[1] = new->memory[0] + PAGE_SIZE;
@@ -326,21 +328,24 @@ static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
 static void intel_i810_free_by_type(struct agp_memory *curr)
 {
        agp_free_key(curr->key);
-       if(curr->type == AGP_PHYS_MEMORY) {
+       if (curr->type == AGP_PHYS_MEMORY) {
                if (curr->page_count == 4)
-                       i8xx_destroy_pages(phys_to_virt(curr->memory[0]));
-               else
+                       i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
+               else {
                        agp_bridge->driver->agp_destroy_page(
-                                phys_to_virt(curr->memory[0]));
+                                gart_to_virt(curr->memory[0]));
+                       global_flush_tlb();
+               }
                vfree(curr->memory);
        }
        kfree(curr);
 }
 
-static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
+static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge,
+       unsigned long addr, int type)
 {
        /* Type checking must be done elsewhere */
-       return addr | agp_bridge->driver->masks[type].mask;
+       return addr | bridge->driver->masks[type].mask;
 }
 
 static struct aper_size_info_fixed intel_i830_sizes[] =
@@ -416,7 +421,9 @@ static void intel_i830_init_gtt_entries(void)
                case I915_GMCH_GMS_STOLEN_48M:
                        /* Check it's really I915G */
                        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB)
                                gtt_entries = MB(48) - KB(size);
                        else
                                gtt_entries = 0;
@@ -424,7 +431,9 @@ static void intel_i830_init_gtt_entries(void)
                case I915_GMCH_GMS_STOLEN_64M:
                        /* Check it's really I915G */
                        if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
+                           agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB)
                                gtt_entries = MB(64) - KB(size);
                        else
                                gtt_entries = 0;
@@ -447,7 +456,7 @@ static void intel_i830_init_gtt_entries(void)
 /* The intel i830 automatically initializes the agp aperture during POST.
  * Use the memory already set aside for in the GTT.
  */
-static int intel_i830_create_gatt_table(void)
+static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
 {
        int page_order;
        struct aper_size_info_fixed *size;
@@ -482,7 +491,7 @@ static int intel_i830_create_gatt_table(void)
 /* Return the gatt table to a sane state. Use the top of stolen
  * memory for the GTT.
  */
-static int intel_i830_free_gatt_table(void)
+static int intel_i830_free_gatt_table(struct agp_bridge_data *bridge)
 {
        return 0;
 }
@@ -582,8 +591,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
        global_cache_flush();   /* FIXME: Necessary ?*/
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-               writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
-                               intel_i830_private.registers+I810_PTE_BASE+(j*4));
+               writel(agp_bridge->driver->mask_memory(agp_bridge,
+                       mem->memory[i], mem->type),
+                       intel_i830_private.registers+I810_PTE_BASE+(j*4));
                readl(intel_i830_private.registers+I810_PTE_BASE+(j*4));        /* PCI Posting. */
        }
 
@@ -691,7 +701,8 @@ static int intel_i915_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(mem->memory[i], mem->type), intel_i830_private.gtt+j);
+               writel(agp_bridge->driver->mask_memory(agp_bridge,
+                       mem->memory[i], mem->type), intel_i830_private.gtt+j);
                readl(intel_i830_private.gtt+j);        /* PCI Posting. */
        }
 
@@ -743,7 +754,7 @@ static int intel_i915_fetch_size(void)
 /* The intel i915 automatically initializes the agp aperture during POST.
  * Use the memory already set aside for in the GTT.
  */
-static int intel_i915_create_gatt_table(void)
+static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
 {
        int page_order;
        struct aper_size_info_fixed *size;
@@ -1041,9 +1052,15 @@ static int intel_845_configure(void)
        /* aperture size */
        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 
-       /* address to map to */
-       pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
-       agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       if (agp_bridge->apbase_config != 0) {
+               pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
+                                      agp_bridge->apbase_config);
+       } else {
+               /* address to map to */
+               pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
+               agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+               agp_bridge->apbase_config = temp;
+       }
 
        /* attbase - aperture base */
        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
@@ -1586,11 +1603,10 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                name = "i820";
                break;
        case PCI_DEVICE_ID_INTEL_82830_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC)) {
+               if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
                        bridge->driver = &intel_830_driver;
-               } else {
+               else
                        bridge->driver = &intel_830mp_driver;
-               }
                name = "830M";
                break;
        case PCI_DEVICE_ID_INTEL_82840_HB:
@@ -1602,11 +1618,10 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                name = "i845";
                break;
        case PCI_DEVICE_ID_INTEL_82845G_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG)) {
+               if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
                        bridge->driver = &intel_830_driver;
-               } else {
+               else
                        bridge->driver = &intel_845_driver;
-               }
                name = "845G";
                break;
        case PCI_DEVICE_ID_INTEL_82850_HB:
@@ -1631,11 +1646,10 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                name = "i860";
                break;
        case PCI_DEVICE_ID_INTEL_82865_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG)) {
+               if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
                        bridge->driver = &intel_830_driver;
-               } else {
+               else
                        bridge->driver = &intel_845_driver;
-               }
                name = "865";
                break;
        case PCI_DEVICE_ID_INTEL_82875_HB:
@@ -1643,21 +1657,33 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                name = "i875";
                break;
        case PCI_DEVICE_ID_INTEL_82915G_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG)) {
+               if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
                        bridge->driver = &intel_915_driver;
-               } else {
+               else
                        bridge->driver = &intel_845_driver;
-               }
                name = "915G";
                break;
        case PCI_DEVICE_ID_INTEL_82915GM_HB:
-               if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG)) {
+               if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
                        bridge->driver = &intel_915_driver;
-               } else {
+               else
                        bridge->driver = &intel_845_driver;
-               }
                name = "915GM";
                break;
+       case PCI_DEVICE_ID_INTEL_82945G_HB:
+               if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
+                       bridge->driver = &intel_915_driver;
+               else
+                       bridge->driver = &intel_845_driver;
+               name = "945G";
+               break;
+       case PCI_DEVICE_ID_INTEL_82945GM_HB:
+               if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
+                       bridge->driver = &intel_915_driver;
+               else
+                       bridge->driver = &intel_845_driver;
+               name = "945GM";
+               break;
        case PCI_DEVICE_ID_INTEL_7505_0:
                bridge->driver = &intel_7505_driver;
                name = "E7505";
@@ -1691,7 +1717,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
        */
        r = &pdev->resource[0];
        if (!r->start && r->end) {
-               if(pci_assign_resource(pdev, 0)) {
+               if (pci_assign_resource(pdev, 0)) {
                        printk(KERN_ERR PFX "could not assign resource 0\n");
                        agp_put_bridge(bridge);
                        return -ENODEV;
@@ -1758,6 +1784,8 @@ static int agp_intel_resume(struct pci_dev *pdev)
                intel_i915_configure();
        else if (bridge->driver == &intel_830_driver)
                intel_i830_configure();
+       else if (bridge->driver == &intel_810_driver)
+               intel_i810_configure();
 
        return 0;
 }
@@ -1795,6 +1823,8 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_7205_0),
        ID(PCI_DEVICE_ID_INTEL_82915G_HB),
        ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
+       ID(PCI_DEVICE_ID_INTEL_82945G_HB),
+       ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
        { }
 };
 
@@ -1810,7 +1840,9 @@ static struct pci_driver agp_intel_pci_driver = {
 
 static int __init agp_intel_init(void)
 {
-       return pci_module_init(&agp_intel_pci_driver);
+       if (agp_off)
+               return -EINVAL;
+       return pci_register_driver(&agp_intel_pci_driver);
 }
 
 static void __exit agp_intel_cleanup(void)