aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-10-16 04:28:34 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:14 -0400
commit91b3a6f4cdbfc73019df36a4b10238063c00f3c3 (patch)
tree410dc764d196034f466a6df88d12f63f265a28a9 /drivers
parentd5383fcc4c221227b954e028821a697ca7859e0e (diff)
pm2fb: accelerated imageblit
This patch adds accelerated imageblit function. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Antonino Daplas <adaplas@gmail.com> 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/pm2fb.c123
1 files changed, 120 insertions, 3 deletions
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index af615d99d438..c3abb951db59 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -60,6 +60,8 @@
60#define DPRINTK(a,b...) 60#define DPRINTK(a,b...)
61#endif 61#endif
62 62
63#define PM2_PIXMAP_SIZE (1600 * 4)
64
63/* 65/*
64 * Driver data 66 * Driver data
65 */ 67 */
@@ -1166,6 +1168,104 @@ static void pm2fb_copyarea(struct fb_info *info,
1166 modded.width, modded.height, 0); 1168 modded.width, modded.height, 0);
1167} 1169}
1168 1170
1171static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
1172{
1173 struct pm2fb_par *par = info->par;
1174 u32 height = image->height;
1175 u32 fgx, bgx;
1176 const u32 *src = (const u32*)image->data;
1177 u32 xres = (info->var.xres + 31) & ~31;
1178
1179 if (info->state != FBINFO_STATE_RUNNING)
1180 return;
1181 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) {
1182 cfb_imageblit(info, image);
1183 return;
1184 }
1185 switch (info->fix.visual) {
1186 case FB_VISUAL_PSEUDOCOLOR:
1187 fgx = image->fg_color;
1188 bgx = image->bg_color;
1189 break;
1190 case FB_VISUAL_TRUECOLOR:
1191 default:
1192 fgx = par->palette[image->fg_color];
1193 bgx = par->palette[image->bg_color];
1194 break;
1195 }
1196 if (info->var.bits_per_pixel == 8) {
1197 fgx |= fgx << 8;
1198 bgx |= bgx << 8;
1199 }
1200 if (info->var.bits_per_pixel <= 16) {
1201 fgx |= fgx << 16;
1202 bgx |= bgx << 16;
1203 }
1204
1205 WAIT_FIFO(par, 13);
1206 pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
1207 pm2_WR(par, PM2R_SCISSOR_MIN_XY,
1208 ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
1209 pm2_WR(par, PM2R_SCISSOR_MAX_XY,
1210 (((image->dy + image->height) & 0x0fff) << 16) |
1211 ((image->dx + image->width) & 0x0fff));
1212 pm2_WR(par, PM2R_SCISSOR_MODE, 1);
1213 /* GXcopy & UNIT_ENABLE */
1214 pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1 );
1215 pm2_WR(par, PM2R_RECTANGLE_ORIGIN,
1216 ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
1217 pm2_WR(par, PM2R_RECTANGLE_SIZE,
1218 ((image->height & 0x0fff) << 16) |
1219 ((image->width) & 0x0fff));
1220 if (info->var.bits_per_pixel == 24) {
1221 pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
1222 /* clear area */
1223 pm2_WR(par, PM2R_CONSTANT_COLOR, bgx);
1224 pm2_WR(par, PM2R_RENDER,
1225 PM2F_RENDER_RECTANGLE |
1226 PM2F_INCREASE_X | PM2F_INCREASE_Y );
1227 /* BitMapPackEachScanline & invert bits and byte order*/
1228 /* force background */
1229 pm2_WR(par, PM2R_RASTERIZER_MODE, (1<<9) | 1 | (3<<7));
1230 pm2_WR(par, PM2R_CONSTANT_COLOR, fgx);
1231 pm2_WR(par, PM2R_RENDER,
1232 PM2F_RENDER_RECTANGLE |
1233 PM2F_INCREASE_X | PM2F_INCREASE_Y |
1234 PM2F_RENDER_SYNC_ON_BIT_MASK);
1235 } else {
1236 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1237 /* clear area */
1238 pm2_WR(par, PM2R_FB_BLOCK_COLOR, bgx);
1239 pm2_WR(par, PM2R_RENDER,
1240 PM2F_RENDER_RECTANGLE |
1241 PM2F_RENDER_FASTFILL |
1242 PM2F_INCREASE_X | PM2F_INCREASE_Y );
1243 /* invert bits and byte order*/
1244 pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3<<7) );
1245 pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx);
1246 pm2_WR(par, PM2R_RENDER,
1247 PM2F_RENDER_RECTANGLE |
1248 PM2F_INCREASE_X | PM2F_INCREASE_Y |
1249 PM2F_RENDER_FASTFILL |
1250 PM2F_RENDER_SYNC_ON_BIT_MASK);
1251 }
1252
1253 while (height--) {
1254 int width = ((image->width + 7) >> 3)
1255 + info->pixmap.scan_align - 1;
1256 width >>= 2;
1257 WAIT_FIFO(par, width);
1258 while (width--) {
1259 pm2_WR(par, PM2R_BIT_MASK_PATTERN, *src);
1260 src++;
1261 }
1262 }
1263 WAIT_FIFO(par, 3);
1264 pm2_WR(par, PM2R_RASTERIZER_MODE, 0);
1265 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1266 pm2_WR(par, PM2R_SCISSOR_MODE, 0);
1267}
1268
1169/* ------------ Hardware Independent Functions ------------ */ 1269/* ------------ Hardware Independent Functions ------------ */
1170 1270
1171/* 1271/*
@@ -1181,7 +1281,7 @@ static struct fb_ops pm2fb_ops = {
1181 .fb_pan_display = pm2fb_pan_display, 1281 .fb_pan_display = pm2fb_pan_display,
1182 .fb_fillrect = pm2fb_fillrect, 1282 .fb_fillrect = pm2fb_fillrect,
1183 .fb_copyarea = pm2fb_copyarea, 1283 .fb_copyarea = pm2fb_copyarea,
1184 .fb_imageblit = cfb_imageblit, 1284 .fb_imageblit = pm2fb_imageblit,
1185 .fb_sync = pm2fb_sync, 1285 .fb_sync = pm2fb_sync,
1186}; 1286};
1187 1287
@@ -1340,11 +1440,24 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1340 info->flags = FBINFO_DEFAULT | 1440 info->flags = FBINFO_DEFAULT |
1341 FBINFO_HWACCEL_YPAN | 1441 FBINFO_HWACCEL_YPAN |
1342 FBINFO_HWACCEL_COPYAREA | 1442 FBINFO_HWACCEL_COPYAREA |
1443 FBINFO_HWACCEL_IMAGEBLIT |
1343 FBINFO_HWACCEL_FILLRECT; 1444 FBINFO_HWACCEL_FILLRECT;
1344 1445
1446 info->pixmap.addr = kmalloc(PM2_PIXMAP_SIZE, GFP_KERNEL);
1447 if (!info->pixmap.addr) {
1448 err_retval = -ENOMEM;
1449 goto err_exit_pixmap;
1450 }
1451 info->pixmap.size = PM2_PIXMAP_SIZE;
1452 info->pixmap.buf_align = 4;
1453 info->pixmap.scan_align = 4;
1454 info->pixmap.access_align = 32;
1455 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1456
1345 if (noaccel) { 1457 if (noaccel) {
1346 printk(KERN_DEBUG "disabling acceleration\n"); 1458 printk(KERN_DEBUG "disabling acceleration\n");
1347 info->flags |= FBINFO_HWACCEL_DISABLED; 1459 info->flags |= FBINFO_HWACCEL_DISABLED;
1460 info->pixmap.scan_align = 1;
1348 } 1461 }
1349 1462
1350 if (!mode) 1463 if (!mode)
@@ -1373,6 +1486,8 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1373 err_exit_all: 1486 err_exit_all:
1374 fb_dealloc_cmap(&info->cmap); 1487 fb_dealloc_cmap(&info->cmap);
1375 err_exit_both: 1488 err_exit_both:
1489 kfree(info->pixmap.addr);
1490 err_exit_pixmap:
1376 iounmap(info->screen_base); 1491 iounmap(info->screen_base);
1377 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1492 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1378 err_exit_mmio: 1493 err_exit_mmio:
@@ -1409,6 +1524,8 @@ static void __devexit pm2fb_remove(struct pci_dev *pdev)
1409 release_mem_region(fix->mmio_start, fix->mmio_len); 1524 release_mem_region(fix->mmio_start, fix->mmio_len);
1410 1525
1411 pci_set_drvdata(pdev, NULL); 1526 pci_set_drvdata(pdev, NULL);
1527 if (info->pixmap.addr)
1528 kfree(info->pixmap.addr);
1412 kfree(info); 1529 kfree(info);
1413} 1530}
1414 1531