aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2008-07-24 00:31:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:36 -0400
commit0292be4a382957016e8b574dc292779cfb49e029 (patch)
treedc583df0ad19e5fc2f7cfa294cbd6ade9ad4a87b
parent6280fd4f9c2683a4d2f096320dd74ded4e5106ad (diff)
tridentfb: add imageblit acceleration for Blade3D family
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>
-rw-r--r--drivers/video/tridentfb.c79
-rw-r--r--include/video/trident.h1
2 files changed, 77 insertions, 3 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 854e2e5af582..b21f84239022 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -35,11 +35,12 @@ struct tridentfb_par {
35 (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32); 35 (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32);
36 void (*copy_rect) 36 void (*copy_rect)
37 (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32); 37 (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32);
38 void (*image_blit)
39 (struct tridentfb_par *par, const char*,
40 u32, u32, u32, u32, u32, u32);
38 unsigned char eng_oper; /* engine operation... */ 41 unsigned char eng_oper; /* engine operation... */
39}; 42};
40 43
41static struct fb_ops tridentfb_ops;
42
43static struct fb_fix_screeninfo tridentfb_fix = { 44static struct fb_fix_screeninfo tridentfb_fix = {
44 .id = "Trident", 45 .id = "Trident",
45 .type = FB_TYPE_PACKED_PIXELS, 46 .type = FB_TYPE_PACKED_PIXELS,
@@ -212,6 +213,21 @@ static void blade_fill_rect(struct tridentfb_par *par,
212 writemmr(par, DST2, point(x + w - 1, y + h - 1)); 213 writemmr(par, DST2, point(x + w - 1, y + h - 1));
213} 214}
214 215
216static void blade_image_blit(struct tridentfb_par *par, const char *data,
217 u32 x, u32 y, u32 w, u32 h, u32 c, u32 b)
218{
219 unsigned size = ((w + 31) >> 5) * h;
220
221 writemmr(par, COLOR, c);
222 writemmr(par, BGCOLOR, b);
223 writemmr(par, CMD, 0xa0000000 | 3 << 19);
224
225 writemmr(par, DST1, point(x, y));
226 writemmr(par, DST2, point(x + w - 1, y + h - 1));
227
228 memcpy(par->io_virt + 0x10000, data, 4 * size);
229}
230
215static void blade_copy_rect(struct tridentfb_par *par, 231static void blade_copy_rect(struct tridentfb_par *par,
216 u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) 232 u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
217{ 233{
@@ -497,6 +513,36 @@ static void tridentfb_fillrect(struct fb_info *info,
497 fr->height, col, fr->rop); 513 fr->height, col, fr->rop);
498} 514}
499 515
516static void tridentfb_imageblit(struct fb_info *info,
517 const struct fb_image *img)
518{
519 struct tridentfb_par *par = info->par;
520 int col, bgcol;
521
522 if ((info->flags & FBINFO_HWACCEL_DISABLED) || img->depth != 1) {
523 cfb_imageblit(info, img);
524 return;
525 }
526 if (info->var.bits_per_pixel == 8) {
527 col = img->fg_color;
528 col |= col << 8;
529 col |= col << 16;
530 bgcol = img->bg_color;
531 bgcol |= bgcol << 8;
532 bgcol |= bgcol << 16;
533 } else {
534 col = ((u32 *)(info->pseudo_palette))[img->fg_color];
535 bgcol = ((u32 *)(info->pseudo_palette))[img->bg_color];
536 }
537
538 par->wait_engine(par);
539 if (par->image_blit)
540 par->image_blit(par, img->data, img->dx, img->dy,
541 img->width, img->height, col, bgcol);
542 else
543 cfb_imageblit(info, img);
544}
545
500static void tridentfb_copyarea(struct fb_info *info, 546static void tridentfb_copyarea(struct fb_info *info,
501 const struct fb_copyarea *ca) 547 const struct fb_copyarea *ca)
502{ 548{
@@ -522,6 +568,7 @@ static int tridentfb_sync(struct fb_info *info)
522#else 568#else
523#define tridentfb_fillrect cfb_fillrect 569#define tridentfb_fillrect cfb_fillrect
524#define tridentfb_copyarea cfb_copyarea 570#define tridentfb_copyarea cfb_copyarea
571#define tridentfb_imageblit cfb_imageblit
525#endif /* CONFIG_FB_TRIDENT_ACCEL */ 572#endif /* CONFIG_FB_TRIDENT_ACCEL */
526 573
527/* 574/*
@@ -1285,7 +1332,7 @@ static struct fb_ops tridentfb_ops = {
1285 .fb_set_par = tridentfb_set_par, 1332 .fb_set_par = tridentfb_set_par,
1286 .fb_fillrect = tridentfb_fillrect, 1333 .fb_fillrect = tridentfb_fillrect,
1287 .fb_copyarea = tridentfb_copyarea, 1334 .fb_copyarea = tridentfb_copyarea,
1288 .fb_imageblit = cfb_imageblit, 1335 .fb_imageblit = tridentfb_imageblit,
1289#ifdef CONFIG_FB_TRIDENT_ACCEL 1336#ifdef CONFIG_FB_TRIDENT_ACCEL
1290 .fb_sync = tridentfb_sync, 1337 .fb_sync = tridentfb_sync,
1291#endif 1338#endif
@@ -1369,6 +1416,7 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
1369 default_par->wait_engine = blade_wait_engine; 1416 default_par->wait_engine = blade_wait_engine;
1370 default_par->fill_rect = blade_fill_rect; 1417 default_par->fill_rect = blade_fill_rect;
1371 default_par->copy_rect = blade_copy_rect; 1418 default_par->copy_rect = blade_copy_rect;
1419 default_par->image_blit = blade_image_blit;
1372 tridentfb_fix.accel = FB_ACCEL_TRIDENT_BLADE3D; 1420 tridentfb_fix.accel = FB_ACCEL_TRIDENT_BLADE3D;
1373 } else if (chip3D) { /* 3DImage family left */ 1421 } else if (chip3D) { /* 3DImage family left */
1374 default_par->init_accel = image_init_accel; 1422 default_par->init_accel = image_init_accel;
@@ -1446,6 +1494,29 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
1446 } else 1494 } else
1447 info->flags |= FBINFO_HWACCEL_DISABLED; 1495 info->flags |= FBINFO_HWACCEL_DISABLED;
1448 1496
1497 info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
1498 if (!info->pixmap.addr) {
1499 err = -ENOMEM;
1500 goto out_unmap2;
1501 }
1502
1503 info->pixmap.size = 4096;
1504 info->pixmap.buf_align = 4;
1505 info->pixmap.scan_align = 1;
1506 info->pixmap.access_align = 32;
1507 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1508
1509 if (default_par->image_blit) {
1510 info->flags |= FBINFO_HWACCEL_IMAGEBLIT;
1511 info->pixmap.scan_align = 4;
1512 }
1513
1514 if (noaccel) {
1515 printk(KERN_DEBUG "disabling acceleration\n");
1516 info->flags |= FBINFO_HWACCEL_DISABLED;
1517 info->pixmap.scan_align = 1;
1518 }
1519
1449 if (!fb_find_mode(&info->var, info, 1520 if (!fb_find_mode(&info->var, info,
1450 mode_option, NULL, 0, NULL, bpp)) { 1521 mode_option, NULL, 0, NULL, bpp)) {
1451 err = -EINVAL; 1522 err = -EINVAL;
@@ -1471,6 +1542,7 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
1471 return 0; 1542 return 0;
1472 1543
1473out_unmap2: 1544out_unmap2:
1545 kfree(info->pixmap.addr);
1474 if (info->screen_base) 1546 if (info->screen_base)
1475 iounmap(info->screen_base); 1547 iounmap(info->screen_base);
1476 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1548 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
@@ -1494,6 +1566,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev)
1494 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1566 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
1495 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); 1567 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
1496 pci_set_drvdata(dev, NULL); 1568 pci_set_drvdata(dev, NULL);
1569 kfree(info->pixmap.addr);
1497 framebuffer_release(info); 1570 framebuffer_release(info);
1498} 1571}
1499 1572
diff --git a/include/video/trident.h b/include/video/trident.h
index 85ced9d91312..b6ce19d1b61b 100644
--- a/include/video/trident.h
+++ b/include/video/trident.h
@@ -135,6 +135,7 @@
135#define CMD 0x2144 135#define CMD 0x2144
136#define ROP 0x2148 136#define ROP 0x2148
137#define COLOR 0x2160 137#define COLOR 0x2160
138#define BGCOLOR 0x2164
138#define SRC1 0x2100 139#define SRC1 0x2100
139#define SRC2 0x2104 140#define SRC2 0x2104
140#define DST1 0x2108 141#define DST1 0x2108