diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-10-16 04:28:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:14 -0400 |
commit | e7f76df9648ccd69a99fe6bc7d774dc05922f2f0 (patch) | |
tree | 6ec2d9ad3aeef81b0a89f2eb8f8c63414582d8db | |
parent | 0a0b53f66043b4f4da728b391232de5e5d22f145 (diff) |
pm3fb: copyarea and partial imageblit suppor
This patch adds accelerated copyarea and partially accelerated imageblit
functions. There is also fixed one register address in the pm3fb.h file.
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>
-rw-r--r-- | drivers/video/pm3fb.c | 180 | ||||
-rw-r--r-- | include/video/pm3fb.h | 5 |
2 files changed, 173 insertions, 12 deletions
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 5b3f54c0918e..438872a5f43f 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c | |||
@@ -276,15 +276,22 @@ static void pm3fb_init_engine(struct fb_info *info) | |||
276 | 276 | ||
277 | PM3_WAIT(par, 2); | 277 | PM3_WAIT(par, 2); |
278 | { | 278 | { |
279 | unsigned long rm = 1; | 279 | /* invert bits in bitmask */ |
280 | unsigned long rm = 1 | (3 << 7); | ||
280 | switch (info->var.bits_per_pixel) { | 281 | switch (info->var.bits_per_pixel) { |
281 | case 8: | 282 | case 8: |
282 | PM3_WRITE_REG(par, PM3PixelSize, | 283 | PM3_WRITE_REG(par, PM3PixelSize, |
283 | PM3PixelSize_GLOBAL_8BIT); | 284 | PM3PixelSize_GLOBAL_8BIT); |
285 | #ifdef __BIG_ENDIAN | ||
286 | rm |= 3 << 15; | ||
287 | #endif | ||
284 | break; | 288 | break; |
285 | case 16: | 289 | case 16: |
286 | PM3_WRITE_REG(par, PM3PixelSize, | 290 | PM3_WRITE_REG(par, PM3PixelSize, |
287 | PM3PixelSize_GLOBAL_16BIT); | 291 | PM3PixelSize_GLOBAL_16BIT); |
292 | #ifdef __BIG_ENDIAN | ||
293 | rm |= 2 << 15; | ||
294 | #endif | ||
288 | break; | 295 | break; |
289 | case 32: | 296 | case 32: |
290 | PM3_WRITE_REG(par, PM3PixelSize, | 297 | PM3_WRITE_REG(par, PM3PixelSize, |
@@ -394,18 +401,18 @@ static void pm3fb_fillrect (struct fb_info *info, | |||
394 | color |= color << 16; | 401 | color |= color << 16; |
395 | 402 | ||
396 | PM3_WAIT(par, 4); | 403 | PM3_WAIT(par, 4); |
397 | 404 | /* ROP Ox3 is GXcopy */ | |
398 | PM3_WRITE_REG(par, PM3Config2D, | 405 | PM3_WRITE_REG(par, PM3Config2D, |
399 | PM3Config2D_UseConstantSource | | 406 | PM3Config2D_UseConstantSource | |
400 | PM3Config2D_ForegroundROPEnable | | 407 | PM3Config2D_ForegroundROPEnable | |
401 | (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */ | 408 | (PM3Config2D_ForegroundROP(0x3)) | |
402 | PM3Config2D_FBWriteEnable); | 409 | PM3Config2D_FBWriteEnable); |
403 | 410 | ||
404 | PM3_WRITE_REG(par, PM3ForegroundColor, color); | 411 | PM3_WRITE_REG(par, PM3ForegroundColor, color); |
405 | 412 | ||
406 | PM3_WRITE_REG(par, PM3RectanglePosition, | 413 | PM3_WRITE_REG(par, PM3RectanglePosition, |
407 | (PM3RectanglePosition_XOffset(modded.dx)) | | 414 | (PM3RectanglePosition_XOffset(modded.dx)) | |
408 | (PM3RectanglePosition_YOffset(modded.dy))); | 415 | (PM3RectanglePosition_YOffset(modded.dy))); |
409 | 416 | ||
410 | PM3_WRITE_REG(par, PM3Render2D, | 417 | PM3_WRITE_REG(par, PM3Render2D, |
411 | PM3Render2D_XPositive | | 418 | PM3Render2D_XPositive | |
@@ -415,6 +422,154 @@ static void pm3fb_fillrect (struct fb_info *info, | |||
415 | (PM3Render2D_Width(modded.width)) | | 422 | (PM3Render2D_Width(modded.width)) | |
416 | (PM3Render2D_Height(modded.height))); | 423 | (PM3Render2D_Height(modded.height))); |
417 | } | 424 | } |
425 | |||
426 | static void pm3fb_copyarea(struct fb_info *info, | ||
427 | const struct fb_copyarea *area) | ||
428 | { | ||
429 | struct pm3_par *par = info->par; | ||
430 | struct fb_copyarea modded; | ||
431 | u32 vxres, vyres; | ||
432 | int x_align, o_x, o_y; | ||
433 | |||
434 | if (info->state != FBINFO_STATE_RUNNING) | ||
435 | return; | ||
436 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
437 | cfb_copyarea(info, area); | ||
438 | return; | ||
439 | } | ||
440 | |||
441 | memcpy(&modded, area, sizeof(struct fb_copyarea)); | ||
442 | |||
443 | vxres = info->var.xres_virtual; | ||
444 | vyres = info->var.yres_virtual; | ||
445 | |||
446 | if(!modded.width || !modded.height || | ||
447 | modded.sx >= vxres || modded.sy >= vyres || | ||
448 | modded.dx >= vxres || modded.dy >= vyres) | ||
449 | return; | ||
450 | |||
451 | if(modded.sx + modded.width > vxres) | ||
452 | modded.width = vxres - modded.sx; | ||
453 | if(modded.dx + modded.width > vxres) | ||
454 | modded.width = vxres - modded.dx; | ||
455 | if(modded.sy + modded.height > vyres) | ||
456 | modded.height = vyres - modded.sy; | ||
457 | if(modded.dy + modded.height > vyres) | ||
458 | modded.height = vyres - modded.dy; | ||
459 | |||
460 | o_x = modded.sx - modded.dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */ | ||
461 | o_y = modded.sy - modded.dy; /*(sy > dy ) ? (sy - dy) : (dy - sy); */ | ||
462 | |||
463 | x_align = (modded.sx & 0x1f); | ||
464 | |||
465 | PM3_WAIT(par, 6); | ||
466 | |||
467 | PM3_WRITE_REG(par, PM3Config2D, | ||
468 | PM3Config2D_UserScissorEnable | | ||
469 | PM3Config2D_ForegroundROPEnable | | ||
470 | PM3Config2D_Blocking | | ||
471 | (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */ | ||
472 | PM3Config2D_FBWriteEnable); | ||
473 | |||
474 | PM3_WRITE_REG(par, PM3ScissorMinXY, | ||
475 | ((modded.dy & 0x0fff) << 16) | (modded.dx & 0x0fff)); | ||
476 | PM3_WRITE_REG(par, PM3ScissorMaxXY, | ||
477 | (((modded.dy + modded.height) & 0x0fff) << 16) | | ||
478 | ((modded.dx + modded.width) & 0x0fff)); | ||
479 | |||
480 | PM3_WRITE_REG(par, PM3FBSourceReadBufferOffset, | ||
481 | PM3FBSourceReadBufferOffset_XOffset(o_x) | | ||
482 | PM3FBSourceReadBufferOffset_YOffset(o_y)); | ||
483 | |||
484 | PM3_WRITE_REG(par, PM3RectanglePosition, | ||
485 | (PM3RectanglePosition_XOffset(modded.dx - x_align)) | | ||
486 | (PM3RectanglePosition_YOffset(modded.dy))); | ||
487 | |||
488 | PM3_WRITE_REG(par, PM3Render2D, | ||
489 | ((modded.sx > modded.dx) ? PM3Render2D_XPositive : 0) | | ||
490 | ((modded.sy > modded.dy) ? PM3Render2D_YPositive : 0) | | ||
491 | PM3Render2D_Operation_Normal | | ||
492 | PM3Render2D_SpanOperation | | ||
493 | PM3Render2D_FBSourceReadEnable | | ||
494 | (PM3Render2D_Width(modded.width + x_align)) | | ||
495 | (PM3Render2D_Height(modded.height))); | ||
496 | } | ||
497 | |||
498 | static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image) | ||
499 | { | ||
500 | struct pm3_par *par = info->par; | ||
501 | u32 height = image->height; | ||
502 | u32 fgx, bgx; | ||
503 | const u32 *src = (const u32*)image->data; | ||
504 | |||
505 | switch (info->fix.visual) { | ||
506 | case FB_VISUAL_PSEUDOCOLOR: | ||
507 | fgx = image->fg_color; | ||
508 | bgx = image->bg_color; | ||
509 | break; | ||
510 | case FB_VISUAL_TRUECOLOR: | ||
511 | default: | ||
512 | fgx = par->palette[image->fg_color]; | ||
513 | bgx = par->palette[image->bg_color]; | ||
514 | break; | ||
515 | } | ||
516 | if (image->depth != 1 || (image->width & 0x1f)) { | ||
517 | return cfb_imageblit(info, image); | ||
518 | } | ||
519 | if (info->var.bits_per_pixel == 8) { | ||
520 | fgx |= fgx << 8; | ||
521 | bgx |= bgx << 8; | ||
522 | } | ||
523 | if (info->var.bits_per_pixel <= 16) { | ||
524 | fgx |= fgx << 16; | ||
525 | bgx |= bgx << 16; | ||
526 | } | ||
527 | |||
528 | PM3_WAIT(par, 5); | ||
529 | |||
530 | PM3_WRITE_REG(par, PM3ForegroundColor, fgx); | ||
531 | PM3_WRITE_REG(par, PM3BackgroundColor, bgx); | ||
532 | |||
533 | /* ROP Ox3 is GXcopy */ | ||
534 | PM3_WRITE_REG(par, PM3Config2D, | ||
535 | PM3Config2D_UseConstantSource | | ||
536 | PM3Config2D_ForegroundROPEnable | | ||
537 | (PM3Config2D_ForegroundROP(0x3)) | | ||
538 | PM3Config2D_OpaqueSpan | | ||
539 | PM3Config2D_FBWriteEnable); | ||
540 | PM3_WRITE_REG(par, PM3RectanglePosition, | ||
541 | (PM3RectanglePosition_XOffset(image->dx)) | | ||
542 | (PM3RectanglePosition_YOffset(image->dy))); | ||
543 | PM3_WRITE_REG(par, PM3Render2D, | ||
544 | PM3Render2D_XPositive | | ||
545 | PM3Render2D_YPositive | | ||
546 | PM3Render2D_Operation_SyncOnBitMask | | ||
547 | PM3Render2D_SpanOperation | | ||
548 | (PM3Render2D_Width(image->width)) | | ||
549 | (PM3Render2D_Height(image->height))); | ||
550 | |||
551 | |||
552 | while (height--) { | ||
553 | u32 width = (image->width + 31) >> 5; | ||
554 | |||
555 | while (width >= PM3_FIFO_SIZE) { | ||
556 | int i = PM3_FIFO_SIZE - 1; | ||
557 | |||
558 | PM3_WAIT(par, PM3_FIFO_SIZE); | ||
559 | while (i--) { | ||
560 | PM3_WRITE_REG(par, PM3BitMaskPattern, *src); | ||
561 | src++; | ||
562 | } | ||
563 | width -= PM3_FIFO_SIZE - 1; | ||
564 | } | ||
565 | |||
566 | PM3_WAIT(par, width + 1); | ||
567 | while (width--) { | ||
568 | PM3_WRITE_REG(par, PM3BitMaskPattern, *src); | ||
569 | src++; | ||
570 | } | ||
571 | } | ||
572 | } | ||
418 | /* end of acceleration functions */ | 573 | /* end of acceleration functions */ |
419 | 574 | ||
420 | /* write the mode to registers */ | 575 | /* write the mode to registers */ |
@@ -907,8 +1062,8 @@ static struct fb_ops pm3fb_ops = { | |||
907 | .fb_setcolreg = pm3fb_setcolreg, | 1062 | .fb_setcolreg = pm3fb_setcolreg, |
908 | .fb_pan_display = pm3fb_pan_display, | 1063 | .fb_pan_display = pm3fb_pan_display, |
909 | .fb_fillrect = pm3fb_fillrect, | 1064 | .fb_fillrect = pm3fb_fillrect, |
910 | .fb_copyarea = cfb_copyarea, | 1065 | .fb_copyarea = pm3fb_copyarea, |
911 | .fb_imageblit = cfb_imageblit, | 1066 | .fb_imageblit = pm3fb_imageblit, |
912 | .fb_blank = pm3fb_blank, | 1067 | .fb_blank = pm3fb_blank, |
913 | .fb_sync = pm3fb_sync, | 1068 | .fb_sync = pm3fb_sync, |
914 | }; | 1069 | }; |
@@ -1080,7 +1235,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev, | |||
1080 | info->fix = pm3fb_fix; | 1235 | info->fix = pm3fb_fix; |
1081 | info->pseudo_palette = par->palette; | 1236 | info->pseudo_palette = par->palette; |
1082 | info->flags = FBINFO_DEFAULT | | 1237 | info->flags = FBINFO_DEFAULT | |
1083 | FBINFO_HWACCEL_FILLRECT;/* | FBINFO_HWACCEL_YPAN;*/ | 1238 | /* FBINFO_HWACCEL_YPAN |*/ |
1239 | FBINFO_HWACCEL_COPYAREA | | ||
1240 | FBINFO_HWACCEL_IMAGEBLIT | | ||
1241 | FBINFO_HWACCEL_FILLRECT; | ||
1084 | 1242 | ||
1085 | /* | 1243 | /* |
1086 | * This should give a reasonable default video mode. The following is | 1244 | * This should give a reasonable default video mode. The following is |
diff --git a/include/video/pm3fb.h b/include/video/pm3fb.h index d52e45a1e9b8..871f707c7250 100644 --- a/include/video/pm3fb.h +++ b/include/video/pm3fb.h | |||
@@ -849,7 +849,7 @@ | |||
849 | #define PM3Render_FBSourceRead_Enable (1<<27) | 849 | #define PM3Render_FBSourceRead_Enable (1<<27) |
850 | #define PM3RasterizerMode 0x80a0 | 850 | #define PM3RasterizerMode 0x80a0 |
851 | #define PM3RasterizerModeAnd 0xaba0 | 851 | #define PM3RasterizerModeAnd 0xaba0 |
852 | #define PM3RasterizerModeOr 0xabb8 | 852 | #define PM3RasterizerModeOr 0xaba8 |
853 | #define PM3RectangleHeight 0x94e0 | 853 | #define PM3RectangleHeight 0x94e0 |
854 | #define PM3Render 0x8038 | 854 | #define PM3Render 0x8038 |
855 | #define PM3RepeatLine 0x9328 | 855 | #define PM3RepeatLine 0x9328 |
@@ -1116,6 +1116,9 @@ | |||
1116 | /* ***** pm3fb useful define and macro ***** */ | 1116 | /* ***** pm3fb useful define and macro ***** */ |
1117 | /* ***************************************** */ | 1117 | /* ***************************************** */ |
1118 | 1118 | ||
1119 | /* fifo size in chip */ | ||
1120 | #define PM3_FIFO_SIZE 120 | ||
1121 | |||
1119 | /* max size of options */ | 1122 | /* max size of options */ |
1120 | #define PM3_OPTIONS_SIZE 256 | 1123 | #define PM3_OPTIONS_SIZE 256 |
1121 | 1124 | ||