diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 8e5ca88dc45c..a28bf0d68ab5 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -142,11 +142,14 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, static void virtio_gpu_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct virtio_gpu_output *output = NULL; struct virtio_gpu_device *vgdev = crtc->dev->dev_private; struct drm_device *drm = crtc->dev; const unsigned pipe = drm_crtc_index(crtc); struct drm_pending_vblank_event *old_e, *e = crtc->state->event; + output = drm_crtc_to_virtio_gpu_output(crtc); + output->primary_update = false; if (!vgdev->has_vblank || !crtc->state->event) return; @@ -217,9 +220,20 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_device *drm = crtc->dev; struct virtio_gpu_device *vgdev = drm->dev_private; const unsigned pipe = drm_crtc_index(crtc); + unsigned long irqflags; + struct drm_pending_vblank_event *e; - if(vgdev->has_multi_plane) + if(vgdev->has_multi_plane) { virtio_gpu_resource_flush_sync(crtc); + } else { + if (vgdev->has_flip_sequence && !output->primary_update) { + virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0); + virtio_gpu_cmd_resource_flush(vgdev, 0, 0, 0, + 0, 0, 0, 0); + virtio_gpu_notify(vgdev); + } + } + output->primary_update = false; if(vgdev->has_scaling) output->scaler_users = 0; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 9d7e6d19fa53..97b565c297a2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -219,6 +219,7 @@ struct virtio_gpu_output { uint64_t rotation[VIRTIO_GPU_MAX_PLANES]; unsigned scaler_users; struct virtio_gpu_hdcp hdcp; + bool primary_update; }; #define drm_crtc_to_virtio_gpu_output(x) \ container_of(x, struct virtio_gpu_output, crtc) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index efdaab341377..b8563d41cd72 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -621,6 +621,7 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1); + output->primary_update = true; } static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index f99d7198fe36..c7b484b38e44 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -833,7 +833,10 @@ void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, cmd_p->r.x = cpu_to_le32(x); cmd_p->r.y = cpu_to_le32(y); - virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + if (fence) + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + else + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,