cirrusfb: check_par fixes
1. Check if virtual resolution fits into memory. Otherwise, Linux hangs during panning. 2. When selected use all available memory to maximize yres_virtual to speed up panning (previously also xres_virtual was increased). 3. Simplify memory restriction calculations. Signed-off-by: Krzysztof Helt <krzysztof.h1@poczta.fm> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
950bbabb5a
commit
09a2910e54
|
@ -628,27 +628,18 @@ static long cirrusfb_get_mclk(long freq, int bpp, long *div)
|
||||||
static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
||||||
struct fb_info *info)
|
struct fb_info *info)
|
||||||
{
|
{
|
||||||
int nom, den; /* translyting from pixels->bytes */
|
int yres;
|
||||||
int yres, i;
|
/* memory size in pixels */
|
||||||
static struct { int xres, yres; } modes[] =
|
unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
|
||||||
{ { 1600, 1280 },
|
|
||||||
{ 1280, 1024 },
|
|
||||||
{ 1024, 768 },
|
|
||||||
{ 800, 600 },
|
|
||||||
{ 640, 480 },
|
|
||||||
{ -1, -1 } };
|
|
||||||
|
|
||||||
switch (var->bits_per_pixel) {
|
switch (var->bits_per_pixel) {
|
||||||
case 1:
|
case 1:
|
||||||
nom = 4;
|
pixels /= 4;
|
||||||
den = 8;
|
|
||||||
break; /* 8 pixel per byte, only 1/4th of mem usable */
|
break; /* 8 pixel per byte, only 1/4th of mem usable */
|
||||||
case 8:
|
case 8:
|
||||||
case 16:
|
case 16:
|
||||||
case 24:
|
case 24:
|
||||||
case 32:
|
case 32:
|
||||||
nom = var->bits_per_pixel / 8;
|
|
||||||
den = 1;
|
|
||||||
break; /* 1 pixel == 1 byte */
|
break; /* 1 pixel == 1 byte */
|
||||||
default:
|
default:
|
||||||
printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
|
printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
|
||||||
|
@ -658,43 +649,29 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var->xres * nom / den * var->yres > info->screen_size) {
|
if (var->xres_virtual < var->xres)
|
||||||
printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
|
var->xres_virtual = var->xres;
|
||||||
"resolution too high to fit into video memory!\n",
|
|
||||||
var->xres, var->yres, var->bits_per_pixel);
|
|
||||||
DPRINTK("EXIT - EINVAL error\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* use highest possible virtual resolution */
|
/* use highest possible virtual resolution */
|
||||||
if (var->xres_virtual == -1 &&
|
if (var->yres_virtual == -1) {
|
||||||
var->yres_virtual == -1) {
|
var->yres_virtual = pixels / var->xres_virtual;
|
||||||
printk(KERN_INFO
|
|
||||||
"cirrusfb: using maximum available virtual resolution\n");
|
|
||||||
for (i = 0; modes[i].xres != -1; i++) {
|
|
||||||
int size = modes[i].xres * nom / den * modes[i].yres;
|
|
||||||
if (size < info->screen_size / 2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (modes[i].xres == -1) {
|
|
||||||
printk(KERN_ERR "cirrusfb: could not find a virtual "
|
|
||||||
"resolution that fits into video memory!!\n");
|
|
||||||
DPRINTK("EXIT - EINVAL error\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
var->xres_virtual = modes[i].xres;
|
|
||||||
var->yres_virtual = modes[i].yres;
|
|
||||||
|
|
||||||
printk(KERN_INFO "cirrusfb: virtual resolution set to "
|
printk(KERN_INFO "cirrusfb: virtual resolution set to "
|
||||||
"maximum of %dx%d\n", var->xres_virtual,
|
"maximum of %dx%d\n", var->xres_virtual,
|
||||||
var->yres_virtual);
|
var->yres_virtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var->xres_virtual < var->xres)
|
|
||||||
var->xres_virtual = var->xres;
|
|
||||||
if (var->yres_virtual < var->yres)
|
if (var->yres_virtual < var->yres)
|
||||||
var->yres_virtual = var->yres;
|
var->yres_virtual = var->yres;
|
||||||
|
|
||||||
|
if (var->xres_virtual * var->yres_virtual > pixels) {
|
||||||
|
printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... "
|
||||||
|
"virtual resolution too high to fit into video memory!\n",
|
||||||
|
var->xres_virtual, var->yres_virtual,
|
||||||
|
var->bits_per_pixel);
|
||||||
|
DPRINTK("EXIT - EINVAL error\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (var->xoffset < 0)
|
if (var->xoffset < 0)
|
||||||
var->xoffset = 0;
|
var->xoffset = 0;
|
||||||
if (var->yoffset < 0)
|
if (var->yoffset < 0)
|
||||||
|
|
Loading…
Reference in New Issue