diff options
author | Alex Ivanov <lausgans@gmail.com> | 2015-06-15 01:50:45 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2015-07-10 15:44:19 -0400 |
commit | cb908ed3495496b9973a2b9ed1a60f43933fdf01 (patch) | |
tree | 6e7e6f68b2288d7d38c12d486d9f17a303808ba8 /drivers/video | |
parent | c4b5fd3fb2058b650447372472ad24e2a989f9f6 (diff) |
stifb: Implement hardware accelerated copyarea
This patch adds hardware assisted scrolling. The code is based upon the
following investigation: https://parisc.wiki.kernel.org/index.php/NGLE#Blitter
A simple 'time ls -la /usr/bin' test shows 1.6x speed increase over soft
copy and 2.3x increase over FBINFO_READS_FAST (prefer soft copy over
screen redraw) on Artist framebuffer.
Signed-off-by: Alex Ivanov <lausgans@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/stifb.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index 86621fabbb8b..735355b0e023 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c | |||
@@ -121,6 +121,7 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS]; | |||
121 | #define REG_3 0x0004a0 | 121 | #define REG_3 0x0004a0 |
122 | #define REG_4 0x000600 | 122 | #define REG_4 0x000600 |
123 | #define REG_6 0x000800 | 123 | #define REG_6 0x000800 |
124 | #define REG_7 0x000804 | ||
124 | #define REG_8 0x000820 | 125 | #define REG_8 0x000820 |
125 | #define REG_9 0x000a04 | 126 | #define REG_9 0x000a04 |
126 | #define REG_10 0x018000 | 127 | #define REG_10 0x018000 |
@@ -135,6 +136,8 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS]; | |||
135 | #define REG_21 0x200218 | 136 | #define REG_21 0x200218 |
136 | #define REG_22 0x0005a0 | 137 | #define REG_22 0x0005a0 |
137 | #define REG_23 0x0005c0 | 138 | #define REG_23 0x0005c0 |
139 | #define REG_24 0x000808 | ||
140 | #define REG_25 0x000b00 | ||
138 | #define REG_26 0x200118 | 141 | #define REG_26 0x200118 |
139 | #define REG_27 0x200308 | 142 | #define REG_27 0x200308 |
140 | #define REG_32 0x21003c | 143 | #define REG_32 0x21003c |
@@ -429,6 +432,9 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) | |||
429 | #define SET_LENXY_START_RECFILL(fb, lenxy) \ | 432 | #define SET_LENXY_START_RECFILL(fb, lenxy) \ |
430 | WRITE_WORD(lenxy, fb, REG_9) | 433 | WRITE_WORD(lenxy, fb, REG_9) |
431 | 434 | ||
435 | #define SETUP_COPYAREA(fb) \ | ||
436 | WRITE_BYTE(0, fb, REG_16b1) | ||
437 | |||
432 | static void | 438 | static void |
433 | HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) | 439 | HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) |
434 | { | 440 | { |
@@ -1004,6 +1010,36 @@ stifb_blank(int blank_mode, struct fb_info *info) | |||
1004 | return 0; | 1010 | return 0; |
1005 | } | 1011 | } |
1006 | 1012 | ||
1013 | static void | ||
1014 | stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
1015 | { | ||
1016 | struct stifb_info *fb = container_of(info, struct stifb_info, info); | ||
1017 | |||
1018 | SETUP_COPYAREA(fb); | ||
1019 | |||
1020 | SETUP_HW(fb); | ||
1021 | if (fb->info.var.bits_per_pixel == 32) { | ||
1022 | WRITE_WORD(0xBBA0A000, fb, REG_10); | ||
1023 | |||
1024 | NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); | ||
1025 | } else { | ||
1026 | WRITE_WORD(fb->id == S9000_ID_HCRX ? 0x13a02000 : 0x13a01000, fb, REG_10); | ||
1027 | |||
1028 | NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xff); | ||
1029 | } | ||
1030 | |||
1031 | NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, | ||
1032 | IBOvals(RopSrc, MaskAddrOffset(0), | ||
1033 | BitmapExtent08, StaticReg(1), | ||
1034 | DataDynamic, MaskOtc, BGx(0), FGx(0))); | ||
1035 | |||
1036 | WRITE_WORD(((area->sx << 16) | area->sy), fb, REG_24); | ||
1037 | WRITE_WORD(((area->width << 16) | area->height), fb, REG_7); | ||
1038 | WRITE_WORD(((area->dx << 16) | area->dy), fb, REG_25); | ||
1039 | |||
1040 | SETUP_FB(fb); | ||
1041 | } | ||
1042 | |||
1007 | static void __init | 1043 | static void __init |
1008 | stifb_init_display(struct stifb_info *fb) | 1044 | stifb_init_display(struct stifb_info *fb) |
1009 | { | 1045 | { |
@@ -1069,7 +1105,7 @@ static struct fb_ops stifb_ops = { | |||
1069 | .fb_setcolreg = stifb_setcolreg, | 1105 | .fb_setcolreg = stifb_setcolreg, |
1070 | .fb_blank = stifb_blank, | 1106 | .fb_blank = stifb_blank, |
1071 | .fb_fillrect = cfb_fillrect, | 1107 | .fb_fillrect = cfb_fillrect, |
1072 | .fb_copyarea = cfb_copyarea, | 1108 | .fb_copyarea = stifb_copyarea, |
1073 | .fb_imageblit = cfb_imageblit, | 1109 | .fb_imageblit = cfb_imageblit, |
1074 | }; | 1110 | }; |
1075 | 1111 | ||
@@ -1258,7 +1294,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) | |||
1258 | info->fbops = &stifb_ops; | 1294 | info->fbops = &stifb_ops; |
1259 | info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len); | 1295 | info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len); |
1260 | info->screen_size = fix->smem_len; | 1296 | info->screen_size = fix->smem_len; |
1261 | info->flags = FBINFO_DEFAULT; | 1297 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA; |
1262 | info->pseudo_palette = &fb->pseudo_palette; | 1298 | info->pseudo_palette = &fb->pseudo_palette; |
1263 | 1299 | ||
1264 | /* This has to be done !!! */ | 1300 | /* This has to be done !!! */ |