|
@@ -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);
|
|
|
|