1
0
Fork 0

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>
hifive-unleashed-5.1
Ondrej Zajicek 2007-05-08 00:39:24 -07:00 committed by Linus Torvalds
parent 4941cb7a18
commit 249bdbbf0d
2 changed files with 18 additions and 15 deletions

View File

@ -35,10 +35,12 @@ Supported Features
* suspend/resume support * suspend/resume support
* DPMS support * DPMS support
Text mode is supported even in higher resolutions, but there is limitation Text mode is supported even in higher resolutions, but there is limitation to
to lower pixclocks (maximum between 50-60 MHz, depending on specific hardware). lower pixclocks (maximum usually between 50-60 MHz, depending on specific
This limitation is not enforced by driver. Text mode supports 8bit wide fonts hardware, i get best results from plain S3 Trio32 card - about 75 MHz). This
only (hardware limitation) and 16bit tall fonts (driver limitation). 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 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 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 * cursor disable in text mode doesn't work
* text mode broken on S3 Trio64 V2/DX
-- --
Ondrej Zajicek <santiago@crfreenet.org> Ondrej Zajicek <santiago@crfreenet.org>

View File

@ -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, 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}; 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; u16 m, n, r;
u8 regval; 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 */ /* Set VGA misc register */
regval = vga_r(NULL, VGA_MIS_R); 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; break;
case 16: case 16:
if (regno >= 16) if (regno >= 16)
return -EINVAL; return 0;
if (fb->var.green.length == 5) if (fb->var.green.length == 5)
((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | ((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 24:
case 32: case 32:
if (regno >= 16) 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); (green & 0xFF00) | ((blue & 0xFF00) >> 8);
break; break;
default: default:
@ -778,12 +783,6 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
unsigned int offset; 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 */ /* Calculate the offset */
if (var->bits_per_pixel == 0) { if (var->bits_per_pixel == 0) {
offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2); offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);