fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / char / agp / generic.c
index f0079e9..3491d6f 100644 (file)
@@ -27,7 +27,6 @@
  * TODO:
  * - Allocate more than order 0 pages to avoid too much linear map splitting.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -57,7 +56,8 @@ int map_page_into_agp(struct page *page)
 {
        int i;
        i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
-       global_flush_tlb();
+       /* Caller's responsibility to call global_flush_tlb() for
+        * performance reasons */
        return i;
 }
 EXPORT_SYMBOL_GPL(map_page_into_agp);
@@ -66,7 +66,8 @@ int unmap_page_from_agp(struct page *page)
 {
        int i;
        i = change_page_attr(page, 1, PAGE_KERNEL);
-       global_flush_tlb();
+       /* Caller's responsibility to call global_flush_tlb() for
+        * performance reasons */
        return i;
 }
 EXPORT_SYMBOL_GPL(unmap_page_from_agp);
@@ -105,12 +106,10 @@ struct agp_memory *agp_create_memory(int scratch_pages)
 {
        struct agp_memory *new;
 
-       new = kmalloc(sizeof(struct agp_memory), GFP_KERNEL);
-
+       new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL);
        if (new == NULL)
                return NULL;
 
-       memset(new, 0, sizeof(struct agp_memory));
        new->key = agp_get_key();
 
        if (new->key < 0) {
@@ -155,6 +154,7 @@ void agp_free_memory(struct agp_memory *curr)
                for (i = 0; i < curr->page_count; i++) {
                        curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
                }
+               flush_agp_mappings();
        }
        agp_free_key(curr->key);
        vfree(curr->memory);
@@ -212,7 +212,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
                new->memory[i] = virt_to_gart(addr);
                new->page_count++;
        }
-       new->bridge = bridge;
+       new->bridge = bridge;
 
        flush_agp_mappings();
 
@@ -298,7 +298,7 @@ EXPORT_SYMBOL_GPL(agp_num_entries);
 /**
  *     agp_copy_info  -  copy bridge state information
  *
- *     @info:          agp_kern_info pointer.  The caller should insure that this pointer is valid. 
+ *     @info:          agp_kern_info pointer.  The caller should insure that this pointer is valid.
  *
  *     This function copies information about the agp bridge device and the state of
  *     the agp backend into an agp_kern_info pointer.
@@ -319,7 +319,6 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)
                info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
        else
                info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
-       info->mode = bridge->mode;
        info->aper_base = bridge->gart_bus_addr;
        info->aper_size = agp_return_size();
        info->max_memory = bridge->max_memory_agp;
@@ -356,7 +355,7 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
                return -EINVAL;
 
        if (curr->is_bound == TRUE) {
-               printk (KERN_INFO PFX "memory %p is already bound!\n", curr);
+               printk(KERN_INFO PFX "memory %p is already bound!\n", curr);
                return -EINVAL;
        }
        if (curr->is_flushed == FALSE) {
@@ -391,7 +390,7 @@ int agp_unbind_memory(struct agp_memory *curr)
                return -EINVAL;
 
        if (curr->is_bound != TRUE) {
-               printk (KERN_INFO PFX "memory %p was not bound!\n", curr);
+               printk(KERN_INFO PFX "memory %p was not bound!\n", curr);
                return -EINVAL;
        }
 
@@ -415,15 +414,41 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
        u32 tmp;
 
        if (*requested_mode & AGP2_RESERVED_MASK) {
-               printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+               printk(KERN_INFO PFX "reserved bits set (%x) in mode 0x%x. Fixed.\n",
+                       *requested_mode & AGP2_RESERVED_MASK, *requested_mode);
                *requested_mode &= ~AGP2_RESERVED_MASK;
        }
 
+       /*
+        * Some dumb bridges are programmed to disobey the AGP2 spec.
+        * This is likely a BIOS misprogramming rather than poweron default, or
+        * it would be a lot more common.
+        * https://bugs.freedesktop.org/show_bug.cgi?id=8816
+        * AGPv2 spec 6.1.9 states:
+        *   The RATE field indicates the data transfer rates supported by this
+        *   device. A.G.P. devices must report all that apply.
+        * Fix them up as best we can.
+        */
+       switch (*bridge_agpstat & 7) {
+       case 4:
+               *bridge_agpstat |= (AGPSTAT2_2X | AGPSTAT2_1X);
+               printk(KERN_INFO PFX "BIOS bug. AGP bridge claims to only support x4 rate"
+                       "Fixing up support for x2 & x1\n");
+               break;
+       case 2:
+               *bridge_agpstat |= AGPSTAT2_1X;
+               printk(KERN_INFO PFX "BIOS bug. AGP bridge claims to only support x2 rate"
+                       "Fixing up support for x1\n");
+               break;
+       default:
+               break;
+       }
+
        /* Check the speed bits make sense. Only one should be set. */
        tmp = *requested_mode & 7;
        switch (tmp) {
                case 0:
-                       printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
+                       printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
                        *requested_mode |= AGPSTAT2_1X;
                        break;
                case 1:
@@ -493,18 +518,19 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
        u32 tmp;
 
        if (*requested_mode & AGP3_RESERVED_MASK) {
-               printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+               printk(KERN_INFO PFX "reserved bits set (%x) in mode 0x%x. Fixed.\n",
+                       *requested_mode & AGP3_RESERVED_MASK, *requested_mode);
                *requested_mode &= ~AGP3_RESERVED_MASK;
        }
 
        /* Check the speed bits make sense. */
        tmp = *requested_mode & 7;
        if (tmp == 0) {
-               printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
+               printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
                *requested_mode |= AGPSTAT3_4X;
        }
        if (tmp >= 3) {
-               printk (KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
+               printk(KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
                *requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X;
        }
 
@@ -533,7 +559,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                 * AGP2.x 4x -> AGP3.0 4x.
                 */
                if (*requested_mode & AGPSTAT2_4X) {
-                       printk (KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
+                       printk(KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
                                                current->comm, *requested_mode);
                        *requested_mode &= ~AGPSTAT2_4X;
                        *requested_mode |= AGPSTAT3_4X;
@@ -544,7 +570,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                 * but have been passed an AGP 2.x mode.
                 * Convert AGP 1x,2x,4x -> AGP 3.0 4x.
                 */
-               printk (KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
+               printk(KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
                                        current->comm, *requested_mode);
                *requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X);
                *requested_mode |= AGPSTAT3_4X;
@@ -554,38 +580,50 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                if (!(*bridge_agpstat & AGPSTAT3_8X)) {
                        *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
                        *bridge_agpstat |= AGPSTAT3_4X;
-                       printk ("%s requested AGPx8 but bridge not capable.\n", current->comm);
+                       printk(KERN_INFO PFX "%s requested AGPx8 but bridge not capable.\n", current->comm);
                        return;
                }
                if (!(*vga_agpstat & AGPSTAT3_8X)) {
                        *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
                        *bridge_agpstat |= AGPSTAT3_4X;
-                       printk ("%s requested AGPx8 but graphic card not capable.\n", current->comm);
+                       printk(KERN_INFO PFX "%s requested AGPx8 but graphic card not capable.\n", current->comm);
                        return;
                }
                /* All set, bridge & device can do AGP x8*/
                *bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
                goto done;
 
+       } else if (*requested_mode & AGPSTAT3_4X) {
+               *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+               *bridge_agpstat |= AGPSTAT3_4X;
+               goto done;
+
        } else {
 
                /*
-                * If we didn't specify AGPx8, we can only do x4.
-                * If the hardware can't do x4, we're up shit creek, and never
-                *  should have got this far.
+                * If we didn't specify an AGP mode, we see if both
+                * the graphics card, and the bridge can do x8, and use if so.
+                * If not, we fall back to x4 mode.
                 */
-               *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
-               if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X))
-                       *bridge_agpstat |= AGPSTAT3_4X;
-               else {
-                       printk (KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
-                                                       "[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n",
-                                                       origbridge, origvga, *bridge_agpstat, *vga_agpstat);
-                       if (!(*bridge_agpstat & AGPSTAT3_4X))
-                               printk (KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
-                       if (!(*vga_agpstat & AGPSTAT3_4X))
-                               printk (KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
-                       return;
+               if ((*bridge_agpstat & AGPSTAT3_8X) && (*vga_agpstat & AGPSTAT3_8X)) {
+                       printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode "
+                               "supported by bridge & card (x8).\n");
+                       *bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
+                       *vga_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
+               } else {
+                       printk(KERN_INFO PFX "Fell back to AGPx4 mode because");
+                       if (!(*bridge_agpstat & AGPSTAT3_8X)) {
+                               printk(KERN_INFO PFX "bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n",
+                                       *bridge_agpstat, origbridge);
+                               *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+                               *bridge_agpstat |= AGPSTAT3_4X;
+                       }
+                       if (!(*vga_agpstat & AGPSTAT3_8X)) {
+                               printk(KERN_INFO PFX "graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n",
+                                       *vga_agpstat, origvga);
+                               *vga_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+                               *vga_agpstat |= AGPSTAT3_4X;
+                       }
                }
        }
 
@@ -622,7 +660,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
        for (;;) {
                device = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, device);
                if (!device) {
-                       printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
+                       printk(KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
                        return 0;
                }
                cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
@@ -734,7 +772,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
                    pci_write_config_dword(bridge->dev,
                                        bridge->capndx+AGPCTRL, temp);
 
-                   printk (KERN_INFO PFX "Device is in legacy mode,"
+                   printk(KERN_INFO PFX "Device is in legacy mode,"
                                " falling back to 2.x\n");
                }
        }
@@ -807,12 +845,10 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
                                case U32_APER_SIZE:
                                        bridge->current_size = A_IDX32(bridge);
                                        break;
-                                       /* This case will never really happen. */
+                               /* These cases will never really happen. */
                                case FIXED_APER_SIZE:
                                case LVL2_APER_SIZE:
                                default:
-                                       bridge->current_size =
-                                           bridge->current_size;
                                        break;
                                }
                                temp = bridge->current_size;
@@ -929,6 +965,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
        if (!bridge)
                return -EINVAL;
 
+       if (mem->page_count == 0)
+               return 0;
+
        temp = bridge->current_size;
 
        switch (bridge->driver->size_type) {
@@ -980,8 +1019,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
 
        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
                writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j);
-               readl(bridge->gatt_table+j);    /* PCI Posting. */
        }
+       readl(bridge->gatt_table+j-1);  /* PCI Posting. */
 
        bridge->driver->tlb_flush(mem);
        return 0;
@@ -998,6 +1037,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
        if (!bridge)
                return -EINVAL;
 
+       if (mem->page_count == 0)
+               return 0;
+
        if (type != 0 || mem->type != 0) {
                /* The generic routines know nothing of memory types */
                return -EINVAL;
@@ -1006,10 +1048,9 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
        /* AK: bogus, should encode addresses > 4GB */
        for (i = pg_start; i < (mem->page_count + pg_start); i++) {
                writel(bridge->scratch_page, bridge->gatt_table+i);
-               readl(bridge->gatt_table+i);    /* PCI Posting. */
        }
+       readl(bridge->gatt_table+i-1);  /* PCI Posting. */
 
-       global_cache_flush();
        bridge->driver->tlb_flush(mem);
        return 0;
 }
@@ -1043,7 +1084,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
 {
        struct page * page;
 
-       page = alloc_page(GFP_KERNEL);
+       page = alloc_page(GFP_KERNEL | GFP_DMA32);
        if (page == NULL)
                return NULL;