| From d5f1a291e32309324a8c481ed84b5c118d1360ea Mon Sep 17 00:00:00 2001 |
| From: Sinclair Yeh <syeh@vmware.com> |
| Date: Wed, 29 Jun 2016 13:23:18 -0700 |
| Subject: drm/vmwgfx: Delay pinning fbdev framebuffer until after mode set |
| |
| From: Sinclair Yeh <syeh@vmware.com> |
| |
| commit d5f1a291e32309324a8c481ed84b5c118d1360ea upstream. |
| |
| For the Screen Object display unit, we need to reserve a |
| guest-invisible region equal to the size of the framebuffer for |
| the host. This region can only be reserved in VRAM, whereas |
| the guest-visible framebuffer can be reserved in either VRAM or |
| GMR. |
| |
| As such priority should be given to the guest-invisible |
| region otherwise in a limited VRAM situation, we can fail to |
| allocate this region. |
| |
| This patch makes it so that vmw_sou_backing_alloc() is called |
| before the framebuffer is pinned. |
| |
| Signed-off-by: Sinclair Yeh <syeh@vmware.com> |
| Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 47 +++++++++++++++++++------------------ |
| 1 file changed, 25 insertions(+), 22 deletions(-) |
| |
| --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c |
| +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c |
| @@ -517,28 +517,6 @@ static int vmw_fb_kms_framebuffer(struct |
| |
| par->set_fb = &vfb->base; |
| |
| - if (!par->bo_ptr) { |
| - /* |
| - * Pin before mapping. Since we don't know in what placement |
| - * to pin, call into KMS to do it for us. |
| - */ |
| - ret = vfb->pin(vfb); |
| - if (ret) { |
| - DRM_ERROR("Could not pin the fbdev framebuffer.\n"); |
| - return ret; |
| - } |
| - |
| - ret = ttm_bo_kmap(&par->vmw_bo->base, 0, |
| - par->vmw_bo->base.num_pages, &par->map); |
| - if (ret) { |
| - vfb->unpin(vfb); |
| - DRM_ERROR("Could not map the fbdev framebuffer.\n"); |
| - return ret; |
| - } |
| - |
| - par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite); |
| - } |
| - |
| return 0; |
| } |
| |
| @@ -601,6 +579,31 @@ static int vmw_fb_set_par(struct fb_info |
| if (ret) |
| goto out_unlock; |
| |
| + if (!par->bo_ptr) { |
| + struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb); |
| + |
| + /* |
| + * Pin before mapping. Since we don't know in what placement |
| + * to pin, call into KMS to do it for us. |
| + */ |
| + ret = vfb->pin(vfb); |
| + if (ret) { |
| + DRM_ERROR("Could not pin the fbdev framebuffer.\n"); |
| + return ret; |
| + } |
| + |
| + ret = ttm_bo_kmap(&par->vmw_bo->base, 0, |
| + par->vmw_bo->base.num_pages, &par->map); |
| + if (ret) { |
| + vfb->unpin(vfb); |
| + DRM_ERROR("Could not map the fbdev framebuffer.\n"); |
| + return ret; |
| + } |
| + |
| + par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite); |
| + } |
| + |
| + |
| vmw_fb_dirty_mark(par, par->fb_x, par->fb_y, |
| par->set_fb->width, par->set_fb->height); |
| |