[AGPGART] Rework AGPv3 modesetting fallback.
authorDave Jones <davej@redhat.com>
Mon, 11 Sep 2006 01:12:20 +0000 (21:12 -0400)
committerDave Jones <davej@redhat.com>
Mon, 11 Sep 2006 01:12:20 +0000 (21:12 -0400)
Sometimes the logic to handle AGPx8->AGPx4 fallback failed, as can
be seen in https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=197346

The failures occured if the bridge was in AGPx8 mode, but the
user hadn't specified a mode in their X config.  We weren't
setting the mode to the highest mode capable by the video card+bridge
(as we do in the AGPv2 case), which was leading to all kinds of
mayhem including us believing that after falling back from AGPx8, that
we couldn't do x4 mode (which is disastrous in AGPv3, as those are
the only two modes possible).

Signed-off-by: Dave Jones <davej@redhat.com>
drivers/char/agp/generic.c

index cc5ea347a8a7899a9e3228289697a2cd88378839..0dcdb363923fed70e4fa9f964c563a53bcf4f67c 100644 (file)
@@ -568,25 +568,34 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
                *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("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("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;
+                       }
                }
        }