Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alex Ivanov and committed by
Helge Deller
cb908ed3 c4b5fd3f

+38 -2
+38 -2
drivers/video/fbdev/stifb.c
··· 121 121 #define REG_3 0x0004a0 122 122 #define REG_4 0x000600 123 123 #define REG_6 0x000800 124 + #define REG_7 0x000804 124 125 #define REG_8 0x000820 125 126 #define REG_9 0x000a04 126 127 #define REG_10 0x018000 ··· 136 135 #define REG_21 0x200218 137 136 #define REG_22 0x0005a0 138 137 #define REG_23 0x0005c0 138 + #define REG_24 0x000808 139 + #define REG_25 0x000b00 139 140 #define REG_26 0x200118 140 141 #define REG_27 0x200308 141 142 #define REG_32 0x21003c ··· 431 428 432 429 #define SET_LENXY_START_RECFILL(fb, lenxy) \ 433 430 WRITE_WORD(lenxy, fb, REG_9) 431 + 432 + #define SETUP_COPYAREA(fb) \ 433 + WRITE_BYTE(0, fb, REG_16b1) 434 434 435 435 static void 436 436 HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) ··· 1010 1004 return 0; 1011 1005 } 1012 1006 1007 + static void 1008 + stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 1009 + { 1010 + struct stifb_info *fb = container_of(info, struct stifb_info, info); 1011 + 1012 + SETUP_COPYAREA(fb); 1013 + 1014 + SETUP_HW(fb); 1015 + if (fb->info.var.bits_per_pixel == 32) { 1016 + WRITE_WORD(0xBBA0A000, fb, REG_10); 1017 + 1018 + NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); 1019 + } else { 1020 + WRITE_WORD(fb->id == S9000_ID_HCRX ? 0x13a02000 : 0x13a01000, fb, REG_10); 1021 + 1022 + NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xff); 1023 + } 1024 + 1025 + NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, 1026 + IBOvals(RopSrc, MaskAddrOffset(0), 1027 + BitmapExtent08, StaticReg(1), 1028 + DataDynamic, MaskOtc, BGx(0), FGx(0))); 1029 + 1030 + WRITE_WORD(((area->sx << 16) | area->sy), fb, REG_24); 1031 + WRITE_WORD(((area->width << 16) | area->height), fb, REG_7); 1032 + WRITE_WORD(((area->dx << 16) | area->dy), fb, REG_25); 1033 + 1034 + SETUP_FB(fb); 1035 + } 1036 + 1013 1037 static void __init 1014 1038 stifb_init_display(struct stifb_info *fb) 1015 1039 { ··· 1105 1069 .fb_setcolreg = stifb_setcolreg, 1106 1070 .fb_blank = stifb_blank, 1107 1071 .fb_fillrect = cfb_fillrect, 1108 - .fb_copyarea = cfb_copyarea, 1072 + .fb_copyarea = stifb_copyarea, 1109 1073 .fb_imageblit = cfb_imageblit, 1110 1074 }; 1111 1075 ··· 1294 1258 info->fbops = &stifb_ops; 1295 1259 info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len); 1296 1260 info->screen_size = fix->smem_len; 1297 - info->flags = FBINFO_DEFAULT; 1261 + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA; 1298 1262 info->pseudo_palette = &fb->pseudo_palette; 1299 1263 1300 1264 /* This has to be done !!! */