diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-10-16 04:28:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:14 -0400 |
commit | 91b3a6f4cdbfc73019df36a4b10238063c00f3c3 (patch) | |
tree | 410dc764d196034f466a6df88d12f63f265a28a9 /drivers | |
parent | d5383fcc4c221227b954e028821a697ca7859e0e (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.c | 123 |
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 | ||
1171 | static 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 | ||