Skip to content

Commit

Permalink
tridentfb: add imageblit acceleration for Blade3D family
Browse files Browse the repository at this point in the history
Add imageblit acceleration for the Blade3D family of cores.  The code is
based on code from the cyblafb driver.

It is a step toward assimilating back the cyblafb driver into the
tridentfb driver.  The cyblafb driver handles a subfamily of the Trident
Blade3d cores.

Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Krzysztof Helt authored and Linus Torvalds committed Jul 24, 2008
1 parent 6280fd4 commit 0292be4
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 3 deletions.
79 changes: 76 additions & 3 deletions drivers/video/tridentfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ struct tridentfb_par {
(struct tridentfb_par *par, u32, u32, u32, u32, u32, u32);
void (*copy_rect)
(struct tridentfb_par *par, u32, u32, u32, u32, u32, u32);
void (*image_blit)
(struct tridentfb_par *par, const char*,
u32, u32, u32, u32, u32, u32);
unsigned char eng_oper; /* engine operation... */
};

static struct fb_ops tridentfb_ops;

static struct fb_fix_screeninfo tridentfb_fix = {
.id = "Trident",
.type = FB_TYPE_PACKED_PIXELS,
Expand Down Expand Up @@ -212,6 +213,21 @@ static void blade_fill_rect(struct tridentfb_par *par,
writemmr(par, DST2, point(x + w - 1, y + h - 1));
}

static void blade_image_blit(struct tridentfb_par *par, const char *data,
u32 x, u32 y, u32 w, u32 h, u32 c, u32 b)
{
unsigned size = ((w + 31) >> 5) * h;

writemmr(par, COLOR, c);
writemmr(par, BGCOLOR, b);
writemmr(par, CMD, 0xa0000000 | 3 << 19);

writemmr(par, DST1, point(x, y));
writemmr(par, DST2, point(x + w - 1, y + h - 1));

memcpy(par->io_virt + 0x10000, data, 4 * size);
}

static void blade_copy_rect(struct tridentfb_par *par,
u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
{
Expand Down Expand Up @@ -497,6 +513,36 @@ static void tridentfb_fillrect(struct fb_info *info,
fr->height, col, fr->rop);
}

static void tridentfb_imageblit(struct fb_info *info,
const struct fb_image *img)
{
struct tridentfb_par *par = info->par;
int col, bgcol;

if ((info->flags & FBINFO_HWACCEL_DISABLED) || img->depth != 1) {
cfb_imageblit(info, img);
return;
}
if (info->var.bits_per_pixel == 8) {
col = img->fg_color;
col |= col << 8;
col |= col << 16;
bgcol = img->bg_color;
bgcol |= bgcol << 8;
bgcol |= bgcol << 16;
} else {
col = ((u32 *)(info->pseudo_palette))[img->fg_color];
bgcol = ((u32 *)(info->pseudo_palette))[img->bg_color];
}

par->wait_engine(par);
if (par->image_blit)
par->image_blit(par, img->data, img->dx, img->dy,
img->width, img->height, col, bgcol);
else
cfb_imageblit(info, img);
}

static void tridentfb_copyarea(struct fb_info *info,
const struct fb_copyarea *ca)
{
Expand All @@ -522,6 +568,7 @@ static int tridentfb_sync(struct fb_info *info)
#else
#define tridentfb_fillrect cfb_fillrect
#define tridentfb_copyarea cfb_copyarea
#define tridentfb_imageblit cfb_imageblit
#endif /* CONFIG_FB_TRIDENT_ACCEL */

/*
Expand Down Expand Up @@ -1285,7 +1332,7 @@ static struct fb_ops tridentfb_ops = {
.fb_set_par = tridentfb_set_par,
.fb_fillrect = tridentfb_fillrect,
.fb_copyarea = tridentfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_imageblit = tridentfb_imageblit,
#ifdef CONFIG_FB_TRIDENT_ACCEL
.fb_sync = tridentfb_sync,
#endif
Expand Down Expand Up @@ -1369,6 +1416,7 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
default_par->wait_engine = blade_wait_engine;
default_par->fill_rect = blade_fill_rect;
default_par->copy_rect = blade_copy_rect;
default_par->image_blit = blade_image_blit;
tridentfb_fix.accel = FB_ACCEL_TRIDENT_BLADE3D;
} else if (chip3D) { /* 3DImage family left */
default_par->init_accel = image_init_accel;
Expand Down Expand Up @@ -1446,6 +1494,29 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
} else
info->flags |= FBINFO_HWACCEL_DISABLED;

info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
if (!info->pixmap.addr) {
err = -ENOMEM;
goto out_unmap2;
}

info->pixmap.size = 4096;
info->pixmap.buf_align = 4;
info->pixmap.scan_align = 1;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;

if (default_par->image_blit) {
info->flags |= FBINFO_HWACCEL_IMAGEBLIT;
info->pixmap.scan_align = 4;
}

if (noaccel) {
printk(KERN_DEBUG "disabling acceleration\n");
info->flags |= FBINFO_HWACCEL_DISABLED;
info->pixmap.scan_align = 1;
}

if (!fb_find_mode(&info->var, info,
mode_option, NULL, 0, NULL, bpp)) {
err = -EINVAL;
Expand All @@ -1471,6 +1542,7 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
return 0;

out_unmap2:
kfree(info->pixmap.addr);
if (info->screen_base)
iounmap(info->screen_base);
release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
Expand All @@ -1494,6 +1566,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev)
release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
pci_set_drvdata(dev, NULL);
kfree(info->pixmap.addr);
framebuffer_release(info);
}

Expand Down
1 change: 1 addition & 0 deletions include/video/trident.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
#define CMD 0x2144
#define ROP 0x2148
#define COLOR 0x2160
#define BGCOLOR 0x2164
#define SRC1 0x2100
#define SRC2 0x2104
#define DST1 0x2108
Expand Down

0 comments on commit 0292be4

Please sign in to comment.