diff options
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c748207e9e1c..250282fee9c8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -30,6 +30,8 @@ | |||
30 | /* Might need a hrtimer here? */ | 30 | /* Might need a hrtimer here? */ |
31 | #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) | 31 | #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) |
32 | 32 | ||
33 | static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb); | ||
34 | static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb); | ||
33 | 35 | ||
34 | void vmw_display_unit_cleanup(struct vmw_display_unit *du) | 36 | void vmw_display_unit_cleanup(struct vmw_display_unit *du) |
35 | { | 37 | { |
@@ -326,6 +328,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, | |||
326 | struct vmw_framebuffer_surface { | 328 | struct vmw_framebuffer_surface { |
327 | struct vmw_framebuffer base; | 329 | struct vmw_framebuffer base; |
328 | struct vmw_surface *surface; | 330 | struct vmw_surface *surface; |
331 | struct vmw_dma_buffer *buffer; | ||
329 | struct delayed_work d_work; | 332 | struct delayed_work d_work; |
330 | struct mutex work_lock; | 333 | struct mutex work_lock; |
331 | bool present_fs; | 334 | bool present_fs; |
@@ -500,8 +503,8 @@ int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, | |||
500 | vfbs->base.base.depth = 24; | 503 | vfbs->base.base.depth = 24; |
501 | vfbs->base.base.width = width; | 504 | vfbs->base.base.width = width; |
502 | vfbs->base.base.height = height; | 505 | vfbs->base.base.height = height; |
503 | vfbs->base.pin = NULL; | 506 | vfbs->base.pin = &vmw_surface_dmabuf_pin; |
504 | vfbs->base.unpin = NULL; | 507 | vfbs->base.unpin = &vmw_surface_dmabuf_unpin; |
505 | vfbs->surface = surface; | 508 | vfbs->surface = surface; |
506 | mutex_init(&vfbs->work_lock); | 509 | mutex_init(&vfbs->work_lock); |
507 | INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback); | 510 | INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback); |
@@ -589,6 +592,40 @@ static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = { | |||
589 | .create_handle = vmw_framebuffer_create_handle, | 592 | .create_handle = vmw_framebuffer_create_handle, |
590 | }; | 593 | }; |
591 | 594 | ||
595 | static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb) | ||
596 | { | ||
597 | struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); | ||
598 | struct vmw_framebuffer_surface *vfbs = | ||
599 | vmw_framebuffer_to_vfbs(&vfb->base); | ||
600 | unsigned long size = vfbs->base.base.pitch * vfbs->base.base.height; | ||
601 | int ret; | ||
602 | |||
603 | vfbs->buffer = kzalloc(sizeof(*vfbs->buffer), GFP_KERNEL); | ||
604 | if (unlikely(vfbs->buffer == NULL)) | ||
605 | return -ENOMEM; | ||
606 | |||
607 | vmw_overlay_pause_all(dev_priv); | ||
608 | ret = vmw_dmabuf_init(dev_priv, vfbs->buffer, size, | ||
609 | &vmw_vram_ne_placement, | ||
610 | false, &vmw_dmabuf_bo_free); | ||
611 | vmw_overlay_resume_all(dev_priv); | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb) | ||
617 | { | ||
618 | struct ttm_buffer_object *bo; | ||
619 | struct vmw_framebuffer_surface *vfbs = | ||
620 | vmw_framebuffer_to_vfbs(&vfb->base); | ||
621 | |||
622 | bo = &vfbs->buffer->base; | ||
623 | ttm_bo_unref(&bo); | ||
624 | vfbs->buffer = NULL; | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
592 | static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) | 629 | static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) |
593 | { | 630 | { |
594 | struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); | 631 | struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); |