diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fb.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 67 |
1 files changed, 18 insertions, 49 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index d23a18aae476..fb4e59ee26c7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -43,8 +43,6 @@ struct vmw_fb_par { struct mutex bo_mutex; struct vmw_dma_buffer *vmw_bo; - struct ttm_bo_kmap_obj map; - void *bo_ptr; unsigned bo_size; struct drm_framebuffer *set_fb; struct drm_display_mode *set_mode; @@ -174,11 +172,13 @@ static void vmw_fb_dirty_flush(struct work_struct *work) struct vmw_private *vmw_priv = par->vmw_priv; struct fb_info *info = vmw_priv->fb_info; unsigned long irq_flags; - s32 dst_x1, dst_x2, dst_y1, dst_y2, w, h; + s32 dst_x1, dst_x2, dst_y1, dst_y2, w = 0, h = 0; u32 cpp, max_x, max_y; struct drm_clip_rect clip; struct drm_framebuffer *cur_fb; u8 *src_ptr, *dst_ptr; + struct vmw_dma_buffer *vbo = par->vmw_bo; + void *virtual; if (vmw_priv->suspended) return; @@ -188,10 +188,16 @@ static void vmw_fb_dirty_flush(struct work_struct *work) if (!cur_fb) goto out_unlock; + (void) ttm_read_lock(&vmw_priv->reservation_sem, false); + (void) ttm_bo_reserve(&vbo->base, false, false, NULL); + virtual = vmw_dma_buffer_map_and_cache(vbo); + if (!virtual) + goto out_unreserve; + spin_lock_irqsave(&par->dirty.lock, irq_flags); if (!par->dirty.active) { spin_unlock_irqrestore(&par->dirty.lock, irq_flags); - goto out_unlock; + goto out_unreserve; } /* @@ -221,7 +227,7 @@ static void vmw_fb_dirty_flush(struct work_struct *work) spin_unlock_irqrestore(&par->dirty.lock, irq_flags); if (w && h) { - dst_ptr = (u8 *)par->bo_ptr + + dst_ptr = (u8 *)virtual + (dst_y1 * par->set_fb->pitches[0] + dst_x1 * cpp); src_ptr = (u8 *)par->vmalloc + ((dst_y1 + par->fb_y) * info->fix.line_length + @@ -237,7 +243,12 @@ static void vmw_fb_dirty_flush(struct work_struct *work) clip.x2 = dst_x2; clip.y1 = dst_y1; clip.y2 = dst_y2; + } +out_unreserve: + ttm_bo_unreserve(&vbo->base); + ttm_read_unlock(&vmw_priv->reservation_sem); + if (w && h) { WARN_ON_ONCE(par->set_fb->funcs->dirty(cur_fb, NULL, 0, 0, &clip, 1)); vmw_fifo_flush(vmw_priv, false); @@ -504,18 +515,8 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par, par->set_fb = NULL; } - if (par->vmw_bo && detach_bo) { - struct vmw_private *vmw_priv = par->vmw_priv; - - if (par->bo_ptr) { - ttm_bo_kunmap(&par->map); - par->bo_ptr = NULL; - } - if (unref_bo) - vmw_dmabuf_unreference(&par->vmw_bo); - else if (vmw_priv->active_display_unit != vmw_du_legacy) - vmw_dmabuf_unpin(par->vmw_priv, par->vmw_bo, false); - } + if (par->vmw_bo && detach_bo && unref_bo) + vmw_dmabuf_unreference(&par->vmw_bo); return 0; } @@ -636,38 +637,6 @@ static int vmw_fb_set_par(struct fb_info *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. LDU doesn't require - * additional pinning because set_config() would've pinned - * it already - */ - if (vmw_priv->active_display_unit != vmw_du_legacy) { - ret = vfb->pin(vfb); - if (ret) { - DRM_ERROR("Could not pin the fbdev " - "framebuffer.\n"); - goto out_unlock; - } - } - - ret = ttm_bo_kmap(&par->vmw_bo->base, 0, - par->vmw_bo->base.num_pages, &par->map); - if (ret) { - if (vmw_priv->active_display_unit != vmw_du_legacy) - vfb->unpin(vfb); - - DRM_ERROR("Could not map the fbdev framebuffer.\n"); - goto out_unlock; - } - - 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); |