diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-03-31 18:25:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 11:59:28 -0400 |
commit | 9e848062533207130667f6eaa748549367ccbedf (patch) | |
tree | ad651331ecaf303dd94490a57cc4c5271f8095ba | |
parent | 8343c89c4f1aac4fced7bb6919b0bdd0c13edcdc (diff) |
cirrusfb: add imageblit function
Add hardware color expansion (imageblit) function. It roughly doubles
scrolling speed of my Alpine card (GD5430).
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/cirrusfb.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index e4ac2f6d4d97..a2a09b39c59a 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -381,7 +381,8 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, | |||
381 | static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, | 381 | static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, |
382 | u_short x, u_short y, | 382 | u_short x, u_short y, |
383 | u_short width, u_short height, | 383 | u_short width, u_short height, |
384 | u32 color, u_short line_length); | 384 | u32 fg_color, u32 bg_color, |
385 | u_short line_length, u_char blitmode); | ||
385 | 386 | ||
386 | static void bestclock(long freq, int *nom, int *den, int *div); | 387 | static void bestclock(long freq, int *nom, int *den, int *div); |
387 | 388 | ||
@@ -1790,8 +1791,8 @@ static void cirrusfb_fillrect(struct fb_info *info, | |||
1790 | info->var.bits_per_pixel, | 1791 | info->var.bits_per_pixel, |
1791 | (region->dx * m) / 8, region->dy, | 1792 | (region->dx * m) / 8, region->dy, |
1792 | (region->width * m) / 8, region->height, | 1793 | (region->width * m) / 8, region->height, |
1793 | color, | 1794 | color, color, |
1794 | info->fix.line_length); | 1795 | info->fix.line_length, 0x40); |
1795 | } | 1796 | } |
1796 | 1797 | ||
1797 | static void cirrusfb_copyarea(struct fb_info *info, | 1798 | static void cirrusfb_copyarea(struct fb_info *info, |
@@ -1840,9 +1841,33 @@ static void cirrusfb_imageblit(struct fb_info *info, | |||
1840 | { | 1841 | { |
1841 | struct cirrusfb_info *cinfo = info->par; | 1842 | struct cirrusfb_info *cinfo = info->par; |
1842 | 1843 | ||
1843 | if (!is_laguna(cinfo)) | 1844 | if (info->state != FBINFO_STATE_RUNNING) |
1845 | return; | ||
1846 | if (info->flags & FBINFO_HWACCEL_DISABLED) | ||
1847 | cfb_imageblit(info, image); | ||
1848 | else { | ||
1849 | unsigned size = ((image->width + 7) >> 3) * image->height; | ||
1850 | int m = info->var.bits_per_pixel; | ||
1851 | u32 fg, bg; | ||
1852 | |||
1853 | if (info->var.bits_per_pixel == 8) { | ||
1854 | fg = image->fg_color; | ||
1855 | bg = image->bg_color; | ||
1856 | } else { | ||
1857 | fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; | ||
1858 | bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; | ||
1859 | } | ||
1844 | cirrusfb_WaitBLT(cinfo->regbase); | 1860 | cirrusfb_WaitBLT(cinfo->regbase); |
1845 | cfb_imageblit(info, image); | 1861 | /* byte rounded scanlines */ |
1862 | vga_wgfx(cinfo->regbase, CL_GR33, 0x00); | ||
1863 | cirrusfb_RectFill(cinfo->regbase, | ||
1864 | info->var.bits_per_pixel, | ||
1865 | (image->dx * m) / 8, image->dy, | ||
1866 | (image->width * m) / 8, image->height, | ||
1867 | fg, bg, | ||
1868 | info->fix.line_length, 0x04); | ||
1869 | memcpy(info->screen_base, image->data, size); | ||
1870 | } | ||
1846 | } | 1871 | } |
1847 | 1872 | ||
1848 | #ifdef CONFIG_PPC_PREP | 1873 | #ifdef CONFIG_PPC_PREP |
@@ -1988,10 +2013,12 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) | |||
1988 | | FBINFO_HWACCEL_XPAN | 2013 | | FBINFO_HWACCEL_XPAN |
1989 | | FBINFO_HWACCEL_YPAN | 2014 | | FBINFO_HWACCEL_YPAN |
1990 | | FBINFO_HWACCEL_FILLRECT | 2015 | | FBINFO_HWACCEL_FILLRECT |
2016 | | FBINFO_HWACCEL_IMAGEBLIT | ||
1991 | | FBINFO_HWACCEL_COPYAREA; | 2017 | | FBINFO_HWACCEL_COPYAREA; |
1992 | if (noaccel || is_laguna(cinfo)) | 2018 | if (noaccel || is_laguna(cinfo)) |
1993 | info->flags |= FBINFO_HWACCEL_DISABLED; | 2019 | info->flags |= FBINFO_HWACCEL_DISABLED; |
1994 | info->fbops = &cirrusfb_ops; | 2020 | info->fbops = &cirrusfb_ops; |
2021 | |||
1995 | if (cinfo->btype == BT_GD5480) { | 2022 | if (cinfo->btype == BT_GD5480) { |
1996 | if (var->bits_per_pixel == 16) | 2023 | if (var->bits_per_pixel == 16) |
1997 | info->screen_base += 1 * MB_; | 2024 | info->screen_base += 1 * MB_; |
@@ -2711,7 +2738,8 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, | |||
2711 | 2738 | ||
2712 | static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, | 2739 | static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, |
2713 | u_short x, u_short y, u_short width, u_short height, | 2740 | u_short x, u_short y, u_short width, u_short height, |
2714 | u32 color, u_short line_length) | 2741 | u32 fg_color, u32 bg_color, u_short line_length, |
2742 | u_char blitmode) | ||
2715 | { | 2743 | { |
2716 | u_long ndest = (y * line_length) + x; | 2744 | u_long ndest = (y * line_length) + x; |
2717 | u_char op; | 2745 | u_char op; |
@@ -2720,24 +2748,24 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, | |||
2720 | 2748 | ||
2721 | /* This is a ColorExpand Blt, using the */ | 2749 | /* This is a ColorExpand Blt, using the */ |
2722 | /* same color for foreground and background */ | 2750 | /* same color for foreground and background */ |
2723 | vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */ | 2751 | vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color); |
2724 | vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */ | 2752 | vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color); |
2725 | 2753 | ||
2726 | op = 0xc0; | 2754 | op = 0x80; |
2727 | if (bits_per_pixel >= 16) { | 2755 | if (bits_per_pixel >= 16) { |
2728 | vga_wgfx(regbase, CL_GR10, color >> 8); /* foreground color */ | 2756 | vga_wgfx(regbase, CL_GR10, bg_color >> 8); |
2729 | vga_wgfx(regbase, CL_GR11, color >> 8); /* background color */ | 2757 | vga_wgfx(regbase, CL_GR11, fg_color >> 8); |
2730 | op = 0xd0; | 2758 | op = 0x90; |
2731 | } | 2759 | } |
2732 | if (bits_per_pixel == 32) { | 2760 | if (bits_per_pixel == 32) { |
2733 | vga_wgfx(regbase, CL_GR12, color >> 16);/* foreground color */ | 2761 | vga_wgfx(regbase, CL_GR12, bg_color >> 16); |
2734 | vga_wgfx(regbase, CL_GR13, color >> 16);/* background color */ | 2762 | vga_wgfx(regbase, CL_GR13, fg_color >> 16); |
2735 | vga_wgfx(regbase, CL_GR14, color >> 24);/* foreground color */ | 2763 | vga_wgfx(regbase, CL_GR14, bg_color >> 24); |
2736 | vga_wgfx(regbase, CL_GR15, color >> 24);/* background color */ | 2764 | vga_wgfx(regbase, CL_GR15, fg_color >> 24); |
2737 | op = 0xf0; | 2765 | op = 0xb0; |
2738 | } | 2766 | } |
2739 | cirrusfb_set_blitter(regbase, width - 1, height - 1, | 2767 | cirrusfb_set_blitter(regbase, width - 1, height - 1, |
2740 | 0, ndest, op, line_length); | 2768 | 0, ndest, op | blitmode, line_length); |
2741 | } | 2769 | } |
2742 | 2770 | ||
2743 | /************************************************************************** | 2771 | /************************************************************************** |