summary refs log tree commit diff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2007-05-08 00:39:24 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 11:15:32 -0700
commit249bdbbf0dbab5554a4bfe55639e324d4758da96 (patch)
tree9c29295b115f83908814b35447ac5965b22a2fe4
parent4941cb7a18fd84d4d8cd097d2beada3c79c8f781 (diff)
downloadlinux-249bdbbf0dbab5554a4bfe55639e324d4758da96.tar.gz
s3fb: driver fixes
This fixes broken fbcon on Virge VX in 24 bpp mode, and contains several
other small updates.

Signed-off-by: Ondrej Zajicek <santiago@crfreenet.org>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/fb/s3fb.txt12
-rw-r--r--drivers/video/s3fb.c21
2 files changed, 18 insertions, 15 deletions
diff --git a/Documentation/fb/s3fb.txt b/Documentation/fb/s3fb.txt
index 8a04c0da0c91..2c97770bdbaa 100644
--- a/Documentation/fb/s3fb.txt
+++ b/Documentation/fb/s3fb.txt
@@ -35,10 +35,12 @@ Supported Features
 	* suspend/resume support
 	* DPMS support
 
-Text mode is supported even in higher resolutions, but there is limitation
-to lower pixclocks (maximum between 50-60 MHz, depending on specific hardware).
-This limitation is not enforced by driver. Text mode supports 8bit wide fonts
-only (hardware limitation) and 16bit tall fonts (driver limitation).
+Text mode is supported even in higher resolutions, but there is limitation to
+lower pixclocks (maximum usually between 50-60 MHz, depending on specific
+hardware, i get best results from plain S3 Trio32 card - about 75 MHz). This
+limitation is not enforced by driver. Text mode supports 8bit wide fonts only
+(hardware limitation) and 16bit tall fonts (driver limitation). Text mode
+support is broken on S3 Trio64 V2/DX.
 
 There are two 4 bpp modes. First mode (selected if nonstd == 0) is mode with
 packed pixels, high nibble first. Second mode (selected if nonstd == 1) is mode
@@ -73,6 +75,8 @@ Known bugs
 ==========
 
 	* cursor disable in text mode doesn't work
+	* text mode broken on S3 Trio64 V2/DX
+
 
 --
 Ondrej Zajicek <santiago@crfreenet.org>
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 2a8d7d3338d5..dfa717b5b63a 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -65,7 +65,7 @@ static const struct svga_fb_format s3fb_formats[] = {
 
 
 static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
-	60000, 240000, 14318};
+	35000, 240000, 14318};
 
 static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
 
@@ -331,8 +331,13 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
 {
 	u16 m, n, r;
 	u8 regval;
+	int rv;
 
-	svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+	rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+	if (rv < 0) {
+		printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
+		return;
+	}
 
 	/* Set VGA misc register  */
 	regval = vga_r(NULL, VGA_MIS_R);
@@ -710,7 +715,7 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 		break;
 	case 16:
 		if (regno >= 16)
-			return -EINVAL;
+			return 0;
 
 		if (fb->var.green.length == 5)
 			((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) |
@@ -723,9 +728,9 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 	case 24:
 	case 32:
 		if (regno >= 16)
-			return -EINVAL;
+			return 0;
 
-		((u32*)fb->pseudo_palette)[regno] = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) |
+		((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) |
 			(green & 0xFF00) | ((blue & 0xFF00) >> 8);
 		break;
 	default:
@@ -778,12 +783,6 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 
 	unsigned int offset;
 
-	/* Validate the offsets */
-	if ((var->xoffset + var->xres) > var->xres_virtual)
-		return -EINVAL;
-	if ((var->yoffset + var->yres) > var->yres_virtual)
-		return -EINVAL;
-
 	/* Calculate the offset */
 	if (var->bits_per_pixel == 0) {
 		offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);