aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@infradead.org>2007-05-08 03:37:50 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:27 -0400
commit28b230ed71df88a3b2df58e3f177c3c7be1753b9 (patch)
tree05d5538d0d6155c07d2fc3b399becda70b94e362 /drivers
parent86c6f7d08b2868ba7cc1ef509c76ee9e9266af40 (diff)
tgafb accelerated code
Add accelerated panning and accelerated color and mono image drawing. Please apply. Signed-off-by: James Simmons <jsimmons@infradead.org> Acked-by: Maciej W. Rozycki <macro@linux-mips.org> (tested, too!) Cc: "Antonino A. Daplas" <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tgafb.c157
1 files changed, 113 insertions, 44 deletions
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 5345fe03cdfe..f0fde6ea7c36 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -59,6 +59,7 @@ static void tgafb_init_fix(struct fb_info *);
59static void tgafb_imageblit(struct fb_info *, const struct fb_image *); 59static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
60static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *); 60static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
61static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *); 61static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
62static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
62 63
63static int __devinit tgafb_register(struct device *dev); 64static int __devinit tgafb_register(struct device *dev);
64static void __devexit tgafb_unregister(struct device *dev); 65static void __devexit tgafb_unregister(struct device *dev);
@@ -81,6 +82,7 @@ static struct fb_ops tgafb_ops = {
81 .fb_set_par = tgafb_set_par, 82 .fb_set_par = tgafb_set_par,
82 .fb_setcolreg = tgafb_setcolreg, 83 .fb_setcolreg = tgafb_setcolreg,
83 .fb_blank = tgafb_blank, 84 .fb_blank = tgafb_blank,
85 .fb_pan_display = tgafb_pan_display,
84 .fb_fillrect = tgafb_fillrect, 86 .fb_fillrect = tgafb_fillrect,
85 .fb_copyarea = tgafb_copyarea, 87 .fb_copyarea = tgafb_copyarea,
86 .fb_imageblit = tgafb_imageblit, 88 .fb_imageblit = tgafb_imageblit,
@@ -319,21 +321,7 @@ tgafb_set_par(struct fb_info *info)
319 BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE); 321 BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
320 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); 322 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
321 323
322#ifdef CONFIG_HW_CONSOLE
323 for (i = 0; i < 16; i++) {
324 int j = color_table[i];
325
326 TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
327 TGA_RAMDAC_REG);
328 TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
329 TGA_RAMDAC_REG);
330 TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
331 TGA_RAMDAC_REG);
332 }
333 for (i = 0; i < 240 * 3; i += 4) {
334#else
335 for (i = 0; i < 256 * 3; i += 4) { 324 for (i = 0; i < 256 * 3; i += 4) {
336#endif
337 TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8), 325 TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
338 TGA_RAMDAC_REG); 326 TGA_RAMDAC_REG);
339 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8), 327 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
@@ -358,18 +346,7 @@ tgafb_set_par(struct fb_info *info)
358 BT459_LOAD_ADDR(par, 0x0000); 346 BT459_LOAD_ADDR(par, 0x0000);
359 TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG); 347 TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
360 348
361#ifdef CONFIG_HW_CONSOLE
362 for (i = 0; i < 16; i++) {
363 int j = color_table[i];
364
365 TGA_WRITE_REG(par, default_red[j], TGA_RAMDAC_REG);
366 TGA_WRITE_REG(par, default_grn[j], TGA_RAMDAC_REG);
367 TGA_WRITE_REG(par, default_blu[j], TGA_RAMDAC_REG);
368 }
369 for (i = 0; i < 240 * 3; i += 4) {
370#else
371 for (i = 0; i < 256 * 3; i += 4) { 349 for (i = 0; i < 256 * 3; i += 4) {
372#endif
373 TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG); 350 TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
374 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG); 351 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
375 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG); 352 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
@@ -646,16 +623,8 @@ tgafb_blank(int blank, struct fb_info *info)
646 * Acceleration. 623 * Acceleration.
647 */ 624 */
648 625
649/**
650 * tgafb_imageblit - REQUIRED function. Can use generic routines if
651 * non acclerated hardware and packed pixel based.
652 * Copies a image from system memory to the screen.
653 *
654 * @info: frame buffer structure that represents a single frame buffer
655 * @image: structure defining the image.
656 */
657static void 626static void
658tgafb_imageblit(struct fb_info *info, const struct fb_image *image) 627tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
659{ 628{
660 struct tga_par *par = (struct tga_par *) info->par; 629 struct tga_par *par = (struct tga_par *) info->par;
661 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask; 630 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
@@ -665,6 +634,17 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
665 void __iomem *regs_base; 634 void __iomem *regs_base;
666 void __iomem *fb_base; 635 void __iomem *fb_base;
667 636
637 is8bpp = info->var.bits_per_pixel == 8;
638
639 /* For copies that aren't pixel expansion, there's little we
640 can do better than the generic code. */
641 /* ??? There is a DMA write mode; I wonder if that could be
642 made to pull the data from the image buffer... */
643 if (image->depth > 1) {
644 cfb_imageblit(info, image);
645 return;
646 }
647
668 dx = image->dx; 648 dx = image->dx;
669 dy = image->dy; 649 dy = image->dy;
670 width = image->width; 650 width = image->width;
@@ -682,18 +662,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
682 if (dy + height > vyres) 662 if (dy + height > vyres)
683 height = vyres - dy; 663 height = vyres - dy;
684 664
685 /* For copies that aren't pixel expansion, there's little we
686 can do better than the generic code. */
687 /* ??? There is a DMA write mode; I wonder if that could be
688 made to pull the data from the image buffer... */
689 if (image->depth > 1) {
690 cfb_imageblit(info, image);
691 return;
692 }
693
694 regs_base = par->tga_regs_base; 665 regs_base = par->tga_regs_base;
695 fb_base = par->tga_fb_base; 666 fb_base = par->tga_fb_base;
696 is8bpp = info->var.bits_per_pixel == 8;
697 667
698 /* Expand the color values to fill 32-bits. */ 668 /* Expand the color values to fill 32-bits. */
699 /* ??? Would be nice to notice colour changes elsewhere, so 669 /* ??? Would be nice to notice colour changes elsewhere, so
@@ -871,6 +841,85 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
871 regs_base + TGA_MODE_REG); 841 regs_base + TGA_MODE_REG);
872} 842}
873 843
844static void
845tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
846{
847 struct tga_par *par = (struct tga_par *) info->par;
848 u32 color, dx, dy, width, height, vxres, vyres;
849 u32 *palette = ((u32 *)info->pseudo_palette);
850 unsigned long pos, line_length, i, j;
851 const unsigned char *data;
852 void *regs_base, *fb_base;
853
854 dx = image->dx;
855 dy = image->dy;
856 width = image->width;
857 height = image->height;
858 vxres = info->var.xres_virtual;
859 vyres = info->var.yres_virtual;
860 line_length = info->fix.line_length;
861
862 /* Crop the image to the screen. */
863 if (dx > vxres || dy > vyres)
864 return;
865 if (dx + width > vxres)
866 width = vxres - dx;
867 if (dy + height > vyres)
868 height = vyres - dy;
869
870 regs_base = par->tga_regs_base;
871 fb_base = par->tga_fb_base;
872
873 pos = dy * line_length + (dx * 4);
874 data = image->data;
875
876 /* Now copy the image, color_expanding via the palette. */
877 for (i = 0; i < height; i++) {
878 for (j = 0; j < width; j++) {
879 color = palette[*data++];
880 __raw_writel(color, fb_base + pos + j*4);
881 }
882 pos += line_length;
883 }
884}
885
886/**
887 * tgafb_imageblit - REQUIRED function. Can use generic routines if
888 * non acclerated hardware and packed pixel based.
889 * Copies a image from system memory to the screen.
890 *
891 * @info: frame buffer structure that represents a single frame buffer
892 * @image: structure defining the image.
893 */
894static void
895tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
896{
897 unsigned int is8bpp = info->var.bits_per_pixel == 8;
898
899 /* If a mono image, regardless of FB depth, go do it. */
900 if (image->depth == 1) {
901 tgafb_mono_imageblit(info, image);
902 return;
903 }
904
905 /* For copies that aren't pixel expansion, there's little we
906 can do better than the generic code. */
907 /* ??? There is a DMA write mode; I wonder if that could be
908 made to pull the data from the image buffer... */
909 if (image->depth == info->var.bits_per_pixel) {
910 cfb_imageblit(info, image);
911 return;
912 }
913
914 /* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */
915 if (!is8bpp && image->depth == 8) {
916 tgafb_clut_imageblit(info, image);
917 return;
918 }
919
920 /* Silently return... */
921}
922
874/** 923/**
875 * tgafb_fillrect - REQUIRED function. Can use generic routines if 924 * tgafb_fillrect - REQUIRED function. Can use generic routines if
876 * non acclerated hardware and packed pixel based. 925 * non acclerated hardware and packed pixel based.
@@ -1480,6 +1529,26 @@ tgafb_init_fix(struct fb_info *info)
1480 info->fix.ywrapstep = 0; 1529 info->fix.ywrapstep = 0;
1481 1530
1482 info->fix.accel = FB_ACCEL_DEC_TGA; 1531 info->fix.accel = FB_ACCEL_DEC_TGA;
1532
1533 /*
1534 * These are needed by fb_set_logo_truepalette(), so we
1535 * set them here for 24-plane cards.
1536 */
1537 if (tga_type != TGA_TYPE_8PLANE) {
1538 info->var.red.length = 8;
1539 info->var.green.length = 8;
1540 info->var.blue.length = 8;
1541 info->var.red.offset = 16;
1542 info->var.green.offset = 8;
1543 info->var.blue.offset = 0;
1544 }
1545}
1546
1547static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1548{
1549 /* We just use this to catch switches out of graphics mode. */
1550 tgafb_set_par(info); /* A bit of overkill for BASE_ADDR reset. */
1551 return 0;
1483} 1552}
1484 1553
1485static int __devinit 1554static int __devinit