diff options
| author | Jakob Bornecrantz <jakob@vmware.com> | 2012-02-09 10:56:45 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2012-02-13 07:01:35 -0500 |
| commit | b5ec427e8d8c66ea1bb9a3bf09663c1361ecf0b6 (patch) | |
| tree | e6b3c60a0b77cff4b1eb62c3010c83cefd17929e /drivers/gpu/drm/vmwgfx | |
| parent | bd49ae46f8a24c088dbca12064a846399e2da631 (diff) | |
vmwgfx: Add page flip support
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 64 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 34 |
3 files changed, 106 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 24efcae3e2f5..2286d47e5022 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -1681,6 +1681,70 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, | |||
| 1681 | return 0; | 1681 | return 0; |
| 1682 | } | 1682 | } |
| 1683 | 1683 | ||
| 1684 | int vmw_du_page_flip(struct drm_crtc *crtc, | ||
| 1685 | struct drm_framebuffer *fb, | ||
| 1686 | struct drm_pending_vblank_event *event) | ||
| 1687 | { | ||
| 1688 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); | ||
| 1689 | struct drm_framebuffer *old_fb = crtc->fb; | ||
| 1690 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); | ||
| 1691 | struct drm_file *file_priv = event->base.file_priv; | ||
| 1692 | struct vmw_fence_obj *fence = NULL; | ||
| 1693 | struct drm_clip_rect clips; | ||
| 1694 | int ret; | ||
| 1695 | |||
| 1696 | /* require ScreenObject support for page flipping */ | ||
| 1697 | if (!dev_priv->sou_priv) | ||
| 1698 | return -ENOSYS; | ||
| 1699 | |||
| 1700 | if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) | ||
| 1701 | return -EINVAL; | ||
| 1702 | |||
| 1703 | crtc->fb = fb; | ||
| 1704 | |||
| 1705 | /* do a full screen dirty update */ | ||
| 1706 | clips.x1 = clips.y1 = 0; | ||
| 1707 | clips.x2 = fb->width; | ||
| 1708 | clips.y2 = fb->height; | ||
| 1709 | |||
| 1710 | if (vfb->dmabuf) | ||
| 1711 | ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb, | ||
| 1712 | 0, 0, &clips, 1, 1, &fence); | ||
| 1713 | else | ||
| 1714 | ret = do_surface_dirty_sou(dev_priv, file_priv, vfb, | ||
| 1715 | 0, 0, &clips, 1, 1, &fence); | ||
| 1716 | |||
| 1717 | |||
| 1718 | if (ret != 0) | ||
| 1719 | goto out_no_fence; | ||
| 1720 | if (!fence) { | ||
| 1721 | ret = -EINVAL; | ||
| 1722 | goto out_no_fence; | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | ret = vmw_event_fence_action_queue(file_priv, fence, | ||
| 1726 | &event->base, | ||
| 1727 | &event->event.tv_sec, | ||
| 1728 | &event->event.tv_usec, | ||
| 1729 | true); | ||
| 1730 | |||
| 1731 | /* | ||
| 1732 | * No need to hold on to this now. The only cleanup | ||
| 1733 | * we need to do if we fail is unref the fence. | ||
| 1734 | */ | ||
| 1735 | vmw_fence_obj_unreference(&fence); | ||
| 1736 | |||
| 1737 | if (vmw_crtc_to_du(crtc)->is_implicit) | ||
| 1738 | vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc); | ||
| 1739 | |||
| 1740 | return ret; | ||
| 1741 | |||
| 1742 | out_no_fence: | ||
| 1743 | crtc->fb = old_fb; | ||
| 1744 | return ret; | ||
| 1745 | } | ||
| 1746 | |||
| 1747 | |||
| 1684 | void vmw_du_crtc_save(struct drm_crtc *crtc) | 1748 | void vmw_du_crtc_save(struct drm_crtc *crtc) |
| 1685 | { | 1749 | { |
| 1686 | } | 1750 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index a4f7f034996a..8184bc5b1730 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
| @@ -121,6 +121,9 @@ struct vmw_display_unit { | |||
| 121 | * Shared display unit functions - vmwgfx_kms.c | 121 | * Shared display unit functions - vmwgfx_kms.c |
| 122 | */ | 122 | */ |
| 123 | void vmw_display_unit_cleanup(struct vmw_display_unit *du); | 123 | void vmw_display_unit_cleanup(struct vmw_display_unit *du); |
| 124 | int vmw_du_page_flip(struct drm_crtc *crtc, | ||
| 125 | struct drm_framebuffer *fb, | ||
| 126 | struct drm_pending_vblank_event *event); | ||
| 124 | void vmw_du_crtc_save(struct drm_crtc *crtc); | 127 | void vmw_du_crtc_save(struct drm_crtc *crtc); |
| 125 | void vmw_du_crtc_restore(struct drm_crtc *crtc); | 128 | void vmw_du_crtc_restore(struct drm_crtc *crtc); |
| 126 | void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, | 129 | void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, |
| @@ -154,5 +157,10 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv); | |||
| 154 | int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv); | 157 | int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv); |
| 155 | int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num, | 158 | int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num, |
| 156 | struct drm_vmw_rect *rects); | 159 | struct drm_vmw_rect *rects); |
| 160 | bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv, | ||
| 161 | struct drm_crtc *crtc); | ||
| 162 | void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv, | ||
| 163 | struct drm_crtc *crtc); | ||
| 164 | |||
| 157 | 165 | ||
| 158 | #endif | 166 | #endif |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 4defdcf1c72e..97aca0bf94d0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
| @@ -394,6 +394,7 @@ static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { | |||
| 394 | .gamma_set = vmw_du_crtc_gamma_set, | 394 | .gamma_set = vmw_du_crtc_gamma_set, |
| 395 | .destroy = vmw_sou_crtc_destroy, | 395 | .destroy = vmw_sou_crtc_destroy, |
| 396 | .set_config = vmw_sou_crtc_set_config, | 396 | .set_config = vmw_sou_crtc_set_config, |
| 397 | .page_flip = vmw_du_page_flip, | ||
| 397 | }; | 398 | }; |
| 398 | 399 | ||
| 399 | /* | 400 | /* |
| @@ -535,3 +536,36 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv) | |||
| 535 | 536 | ||
| 536 | return 0; | 537 | return 0; |
| 537 | } | 538 | } |
| 539 | |||
| 540 | /** | ||
| 541 | * Returns if this unit can be page flipped. | ||
| 542 | * Must be called with the mode_config mutex held. | ||
| 543 | */ | ||
| 544 | bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv, | ||
| 545 | struct drm_crtc *crtc) | ||
| 546 | { | ||
| 547 | struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc); | ||
| 548 | |||
| 549 | if (!sou->base.is_implicit) | ||
| 550 | return true; | ||
| 551 | |||
| 552 | if (dev_priv->sou_priv->num_implicit != 1) | ||
| 553 | return false; | ||
| 554 | |||
| 555 | return true; | ||
| 556 | } | ||
| 557 | |||
| 558 | /** | ||
| 559 | * Update the implicit fb to the current fb of this crtc. | ||
| 560 | * Must be called with the mode_config mutex held. | ||
| 561 | */ | ||
| 562 | void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv, | ||
| 563 | struct drm_crtc *crtc) | ||
| 564 | { | ||
| 565 | struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc); | ||
| 566 | |||
| 567 | BUG_ON(!sou->base.is_implicit); | ||
| 568 | |||
| 569 | dev_priv->sou_priv->implicit_fb = | ||
| 570 | vmw_framebuffer_to_vfb(sou->base.crtc.fb); | ||
| 571 | } | ||
