Skip to contentSkip to conversation

radeonfb: Fix mode setting on CRT monitors

PATCH In review Benjamin Herrenschmidt 2 participants 3 messages Mar 28, 2005 Framebuffer layer

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 radeonfb: Fix mode setting on CRT monitors

Hi !

Current radeonfb is a bit "anal" about accepting CRT modes, it basically only accepts modes that have the exact resolution, which tends to break with fbcon on console switches as it provides "approximate" modes. This patch fixes it by having the driver chose the closest possible mode instead of looking for an exact match.

drivers/video/aty/radeon_monitor.c +10 -12
@@ -903,7 +903,7 @@
  */
 
 /*
- * This is used when looking for modes. We assign a "goodness" value
+ * This is used when looking for modes. We assign a "distance" value
  * to a mode in the modedb depending how "close" it is from what we
  * are looking for.
  * Currently, we don't compare that much, we could do better but
@@ -912,13 +912,11 @@
 static int radeon_compare_modes(const struct fb_var_screeninfo *var,
 				const struct fb_videomode *mode)
 {
-	int goodness = 0;
+	int distance = 0;
 
-	if (var->yres == mode->yres)
-		goodness += 10;
-	if (var->xres == mode->xres)
-		goodness += 9;
-	return goodness;
+	distance = mode->yres - var->yres;
+	distance += (mode->xres - var->xres)/2;
+	return distance;
 }
 
 /*
@@ -940,7 +938,7 @@
 	const struct fb_videomode	*db = vesa_modes;
 	int				i, dbsize = 34;
 	int				has_rmx, native_db = 0;
-	int				goodness = 0;
+	int				distance = INT_MAX;
 	const struct fb_videomode	*candidate = NULL;
 
 	/* Start with a copy of the requested mode */
@@ -976,19 +974,19 @@
 	/* Now look for a mode in the database */
 	while (db) {
 		for (i = 0; i < dbsize; i++) {
-			int g;
+			int d;
 
 			if (db[i].yres < src->yres)
 				continue;	
 			if (db[i].xres < src->xres)
 				continue;
-			g = radeon_compare_modes(src, &db[i]);
+			d = radeon_compare_modes(src, &db[i]);
 			/* If the new mode is at least as good as the previous one,
 			 * then it's our new candidate
 			 */
-			if (g >= goodness) {
+			if (d < distance) {
 				candidate = &db[i];
-				goodness = g;
+				distance = d;
 			}
 		}
 		db = NULL;
Signature · 1 line
Benjamin Herrenschmidt <[email protected]>
#1 lore raw
Quoted 7 lines · Benjamin Herrenschmidt

Hi !

Current radeonfb is a bit "anal" about accepting CRT modes, it basically only accepts modes that have the exact resolution, which tends to break with fbcon on console switches as it provides "approximate" modes. This patch fixes it by having the driver chose the closest possible mode instead of looking for an exact match.

Hi Benjamin,

I tried your patch because on recent -mm kernels I see dirty colored columns during a few seconds when switching from X to radeon fbcon (looks like remaining colors of X).
I don't know what visible effect your patch is supposed to have.
I didn't see any difference, but I doesn't seem to break anything.

Regards,
Brice

#2 lore raw
Quoted 9 lines · Brice Goglin
Quoted 7 lines · Benjamin Herrenschmidt

Hi !

Current radeonfb is a bit "anal" about accepting CRT modes, it basically only accepts modes that have the exact resolution, which tends to break with fbcon on console switches as it provides "approximate" modes. This patch fixes it by having the driver chose the closest possible mode instead of looking for an exact match.

Quoted 7 lines

Hi Benjamin,

I tried your patch because on recent -mm kernels I see dirty colored columns during a few seconds when switching from X to radeon fbcon (looks like remaining colors of X).
I don't know what visible effect your patch is supposed to have. I didn't see any difference, but I doesn't seem to break anything.

The effect is that if your console resolution isn't an exact multiple of the character width or height, radeonfb would fail to set the mode on console switches. It doesn't happen with 1024x768 and default font but it does happen with some weird modes, and some monitors (/me lurks toward IBM) tend to have quite broken default EDID timings.

Ben.