diff options
author | James Simmons <jsimmons@infradead.org> | 2007-05-08 03:37:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:27 -0400 |
commit | 28b230ed71df88a3b2df58e3f177c3c7be1753b9 (patch) | |
tree | 05d5538d0d6155c07d2fc3b399becda70b94e362 /drivers/video/tgafb.c | |
parent | 86c6f7d08b2868ba7cc1ef509c76ee9e9266af40 (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/video/tgafb.c')
-rw-r--r-- | drivers/video/tgafb.c | 157 |
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 *); | |||
59 | static void tgafb_imageblit(struct fb_info *, const struct fb_image *); | 59 | static void tgafb_imageblit(struct fb_info *, const struct fb_image *); |
60 | static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *); | 60 | static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *); |
61 | static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *); | 61 | static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *); |
62 | static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); | ||
62 | 63 | ||
63 | static int __devinit tgafb_register(struct device *dev); | 64 | static int __devinit tgafb_register(struct device *dev); |
64 | static void __devexit tgafb_unregister(struct device *dev); | 65 | static 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 | */ | ||
657 | static void | 626 | static void |
658 | tgafb_imageblit(struct fb_info *info, const struct fb_image *image) | 627 | tgafb_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 | ||
844 | static void | ||
845 | tgafb_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 | */ | ||
894 | static void | ||
895 | tgafb_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 | |||
1547 | static 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 | ||
1485 | static int __devinit | 1554 | static int __devinit |