Commit 82f912ea authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] i810fb fixes

1. Fixed cursor corruption if acceleration is enabled
2. Round up fields in var instead of rounding down
3. Set capabilities flags
4. Added myself to the MAINTAINERS file for i810fb
5. Make i810fb depend on X86 but not X86_64
6. Fixed typo in i810_init_monspecs(). Reported by Manuel Lauss
   <slauss@resi.at>.
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 27f8601a
...@@ -1060,6 +1060,12 @@ M: lethal@chaoticdreams.org ...@@ -1060,6 +1060,12 @@ M: lethal@chaoticdreams.org
L: linux-fbdev-devel@lists.sourceforge.net L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained S: Maintained
INTEL 810/815 FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@pol.net
L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained
INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT
P: Ingo Molnar P: Ingo Molnar
M: mingo@redhat.com M: mingo@redhat.com
......
...@@ -470,7 +470,9 @@ config FB_RIVA_DEBUG ...@@ -470,7 +470,9 @@ config FB_RIVA_DEBUG
config FB_I810 config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)" tristate "Intel 810/815 support (EXPERIMENTAL)"
depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
select AGP
select AGP_INTEL
help help
This driver supports the on-board graphics built in to the Intel 810 This driver supports the on-board graphics built in to the Intel 810
and 815 chipsets. Say Y if you have and plan to use such a board. and 815 chipsets. Say Y if you have and plan to use such a board.
......
...@@ -193,19 +193,19 @@ struct mode_registers std_modes[] = { ...@@ -193,19 +193,19 @@ struct mode_registers std_modes[] = {
void round_off_xres(u32 *xres) void round_off_xres(u32 *xres)
{ {
if (*xres < 800) if (*xres <= 640)
*xres = 640; *xres = 640;
if (*xres < 1024 && *xres >= 800) else if (*xres <= 800)
*xres = 800; *xres = 800;
if (*xres < 1152 && *xres >= 1024) else if (*xres <= 1024)
*xres = 1024; *xres = 1024;
if (*xres < 1280 && *xres >= 1152) else if (*xres <= 1152)
*xres = 1152; *xres = 1152;
if (*xres < 1600 && *xres >= 1280) else if (*xres <= 1280)
*xres = 1280; *xres = 1280;
if (*xres >= 1600) else
*xres = 1600; *xres = 1600;
} }
inline void round_off_yres(u32 *xres, u32 *yres) inline void round_off_yres(u32 *xres, u32 *yres)
{ {
......
...@@ -1353,11 +1353,15 @@ static int i810fb_set_par(struct fb_info *info) ...@@ -1353,11 +1353,15 @@ static int i810fb_set_par(struct fb_info *info)
encode_fix(&info->fix, info); encode_fix(&info->fix, info);
if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) {
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_IMAGEBLIT;
info->pixmap.scan_align = 2; info->pixmap.scan_align = 2;
else } else {
info->pixmap.scan_align = 1; info->pixmap.scan_align = 1;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
}
return 0; return 0;
} }
...@@ -1388,16 +1392,17 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -1388,16 +1392,17 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{ {
struct i810fb_par *par = (struct i810fb_par *)info->par; struct i810fb_par *par = (struct i810fb_par *)info->par;
u8 *mmio = par->mmio_start_virtual; u8 *mmio = par->mmio_start_virtual;
u8 data[64 * 8];
if (!info->var.accel_flags || par->dev_flags & LOCKUP) if (!info->var.accel_flags || par->dev_flags & LOCKUP)
return soft_cursor(info, cursor); return soft_cursor(info, cursor);
if (cursor->image.width > 64 || cursor->image.height > 64) if (cursor->image.width > 64 || cursor->image.height > 64)
return -ENXIO; return -ENXIO;
if ((i810_readl(CURBASE, mmio) & 0xf) != par->cursor_heap.physical) if ((i810_readl(CURBASE, mmio) & 0xf) != par->cursor_heap.physical) {
i810_init_cursor(par); i810_init_cursor(par);
cursor->set |= FB_CUR_SETALL;
}
i810_enable_cursor(mmio, OFF); i810_enable_cursor(mmio, OFF);
...@@ -1409,50 +1414,56 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -1409,50 +1414,56 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
info->cursor.image.dx = cursor->image.dx; info->cursor.image.dx = cursor->image.dx;
info->cursor.image.dy = cursor->image.dy; info->cursor.image.dy = cursor->image.dy;
tmp = (info->cursor.image.dx - info->var.xoffset) & 0xffff;
tmp = cursor->image.dx - info->var.xoffset; tmp |= (info->cursor.image.dy - info->var.yoffset) << 16;
tmp |= (cursor->image.dy - info->var.yoffset) << 16;
i810_writel(CURPOS, mmio, tmp); i810_writel(CURPOS, mmio, tmp);
} }
if (cursor->set & FB_CUR_SETSIZE) { if (cursor->set & FB_CUR_SETSIZE) {
i810_reset_cursor_image(par);
info->cursor.image.height = cursor->image.height; info->cursor.image.height = cursor->image.height;
info->cursor.image.width = cursor->image.width; info->cursor.image.width = cursor->image.width;
i810_reset_cursor_image(par);
} }
if (cursor->set & FB_CUR_SETCMAP) { if (cursor->set & FB_CUR_SETCMAP) {
info->cursor.image.fg_color = cursor->image.fg_color;
info->cursor.image.bg_color = cursor->image.bg_color;
i810_load_cursor_colors(cursor->image.fg_color, i810_load_cursor_colors(cursor->image.fg_color,
cursor->image.bg_color, cursor->image.bg_color,
info); info);
info->cursor.image.fg_color = cursor->image.fg_color;
info->cursor.image.bg_color = cursor->image.bg_color;
} }
if (cursor->set & FB_CUR_SETSHAPE) { if (cursor->set & (FB_CUR_SETSHAPE)) {
int size = ((info->cursor.image.width + 7) >> 3) * int size = ((info->cursor.image.width + 7) >> 3) *
info->cursor.image.height; info->cursor.image.height;
int i; int i;
u8 *data = kmalloc(64 * 8, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
info->cursor.image.data = cursor->image.data;
switch (info->cursor.rop) { switch (info->cursor.rop) {
case ROP_XOR: case ROP_XOR:
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
data[i] = cursor->image.data[i] ^ info->cursor.mask[i]; data[i] = info->cursor.image.data[i] ^ info->cursor.mask[i];
break; break;
case ROP_COPY: case ROP_COPY:
default: default:
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
data[i] = cursor->image.data[i] & info->cursor.mask[i]; data[i] = info->cursor.image.data[i] & info->cursor.mask[i];
break; break;
} }
i810_load_cursor_image(info->cursor.image.width, i810_load_cursor_image(info->cursor.image.width,
info->cursor.image.height, data, info->cursor.image.height, data,
par); par);
kfree(data);
} }
if (info->cursor.enable) if (info->cursor.enable)
i810_enable_cursor(mmio, ON); i810_enable_cursor(mmio, ON);
return 0; return 0;
} }
...@@ -1641,9 +1652,11 @@ static void __devinit i810_init_monspecs(struct fb_info *info) ...@@ -1641,9 +1652,11 @@ static void __devinit i810_init_monspecs(struct fb_info *info)
hsync1 = HFMIN; hsync1 = HFMIN;
if (!hsync2) if (!hsync2)
hsync2 = HFMAX; hsync2 = HFMAX;
info->monspecs.hfmax = hsync2; if (!info->monspecs.hfmax)
info->monspecs.hfmin = hsync1; info->monspecs.hfmax = hsync2;
if (hsync2 < hsync1) if (!info->monspecs.hfmin)
info->monspecs.hfmin = hsync1;
if (hsync2 < hsync1)
info->monspecs.hfmin = hsync2; info->monspecs.hfmin = hsync2;
if (!vsync1) if (!vsync1)
...@@ -1652,8 +1665,10 @@ static void __devinit i810_init_monspecs(struct fb_info *info) ...@@ -1652,8 +1665,10 @@ static void __devinit i810_init_monspecs(struct fb_info *info)
vsync2 = VFMAX; vsync2 = VFMAX;
if (IS_DVT && vsync1 < 60) if (IS_DVT && vsync1 < 60)
vsync1 = 60; vsync1 = 60;
info->monspecs.vfmax = vsync2; if (!info->monspecs.vfmax)
info->monspecs.vfmin = vsync1; info->monspecs.vfmax = vsync2;
if (!info->monspecs.vfmin)
info->monspecs.vfmin = vsync1;
if (vsync2 < vsync1) if (vsync2 < vsync1)
info->monspecs.vfmin = vsync2; info->monspecs.vfmin = vsync2;
} }
...@@ -1724,6 +1739,7 @@ static void __devinit i810_init_device(struct i810fb_par *par) ...@@ -1724,6 +1739,7 @@ static void __devinit i810_init_device(struct i810fb_par *par)
pci_read_config_byte(par->dev, 0x50, &reg); pci_read_config_byte(par->dev, 0x50, &reg);
reg &= FREQ_MASK; reg &= FREQ_MASK;
par->mem_freq = (reg) ? 133 : 100; par->mem_freq = (reg) ? 133 : 100;
} }
static int __devinit static int __devinit
...@@ -1836,8 +1852,9 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev, ...@@ -1836,8 +1852,9 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
{ {
struct fb_info *info; struct fb_info *info;
struct i810fb_par *par = NULL; struct i810fb_par *par = NULL;
int err, vfreq, hfreq, pixclock; int i, err = -1, vfreq, hfreq, pixclock;
i = 0;
if (!(info = kmalloc(sizeof(struct fb_info), GFP_KERNEL))) { if (!(info = kmalloc(sizeof(struct fb_info), GFP_KERNEL))) {
i810fb_release_resource(info, par); i810fb_release_resource(info, par);
return -ENOMEM; return -ENOMEM;
...@@ -1879,8 +1896,6 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev, ...@@ -1879,8 +1896,6 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
info->screen_base = par->fb.virtual; info->screen_base = par->fb.virtual;
info->fbops = &par->i810fb_ops; info->fbops = &par->i810fb_ops;
info->pseudo_palette = par->pseudo_palette; info->pseudo_palette = par->pseudo_palette;
info->flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&info->cmap, 256, 0); fb_alloc_cmap(&info->cmap, 256, 0);
if ((err = info->fbops->fb_check_var(&info->var, info))) { if ((err = info->fbops->fb_check_var(&info->var, info))) {
...@@ -1957,8 +1972,7 @@ static void i810fb_release_resource(struct fb_info *info, ...@@ -1957,8 +1972,7 @@ static void i810fb_release_resource(struct fb_info *info,
kfree(par); kfree(par);
} }
if (info) kfree(info);
kfree(info);
} }
static void __exit i810fb_remove_pci(struct pci_dev *dev) static void __exit i810fb_remove_pci(struct pci_dev *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment