summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/qxl
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-09-28 13:23:07 +1000
committerDave Airlie <airlied@redhat.com>2016-09-28 13:23:07 +1000
commitc0d5fb4d0d9224ccaad0475c9b58740873970e7e (patch)
tree202ee565e7d873f6580b85251aba75a00bac1fc2 /drivers/gpu/drm/qxl
parentca09fb9f60b5f3ab2d57e761aaeea89a5147d784 (diff)
parent30b9c96cf7b44d53b9165649c8be34ac234be324 (diff)
downloadlinux-c0d5fb4d0d9224ccaad0475c9b58740873970e7e.tar.bz2
Merge tag 'drm-qemu-20160921' of git://git.kraxel.org/linux into drm-next
bugfixes for qemu (bochs, qxl and virtio-gpu) drm drivers * tag 'drm-qemu-20160921' of git://git.kraxel.org/linux: drm/virtio: add real fence context and seqno drm/virtio: drop virtio_gpu_execbuffer_ioctl() wrapping virtio-gpu: avoid possible NULL pointer dereference drm/qxl: reapply cursor after SetCrtc calls bochs: ignore device if there isn't enougth memory
Diffstat (limited to 'drivers/gpu/drm/qxl')
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c56
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h1
2 files changed, 56 insertions, 1 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 3aef12742a53..a61c0d460ec2 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -211,6 +211,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc)
struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
drm_crtc_cleanup(crtc);
+ qxl_bo_unref(&qxl_crtc->cursor_bo);
kfree(qxl_crtc);
}
@@ -296,6 +297,52 @@ qxl_hide_cursor(struct qxl_device *qdev)
return 0;
}
+static int qxl_crtc_apply_cursor(struct drm_crtc *crtc)
+{
+ struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct qxl_device *qdev = dev->dev_private;
+ struct qxl_cursor_cmd *cmd;
+ struct qxl_release *release;
+ int ret = 0;
+
+ if (!qcrtc->cursor_bo)
+ return 0;
+
+ ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
+ QXL_RELEASE_CURSOR_CMD,
+ &release, NULL);
+ if (ret)
+ return ret;
+
+ ret = qxl_release_list_add(release, qcrtc->cursor_bo);
+ if (ret)
+ goto out_free_release;
+
+ ret = qxl_release_reserve_list(release, false);
+ if (ret)
+ goto out_free_release;
+
+ cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
+ cmd->type = QXL_CURSOR_SET;
+ cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
+ cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
+
+ cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0);
+
+ cmd->u.set.visible = 1;
+ qxl_release_unmap(qdev, release, &cmd->release_info);
+
+ qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+ qxl_release_fence_buffer_objects(release);
+
+ return ret;
+
+out_free_release:
+ qxl_release_free(qdev, release);
+ return ret;
+}
+
static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
struct drm_file *file_priv,
uint32_t handle,
@@ -400,7 +447,8 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
}
drm_gem_object_unreference_unlocked(obj);
- qxl_bo_unref(&cursor_bo);
+ qxl_bo_unref (&qcrtc->cursor_bo);
+ qcrtc->cursor_bo = cursor_bo;
return ret;
@@ -655,6 +703,12 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
bo->surf.stride, bo->surf.format);
qxl_io_create_primary(qdev, 0, bo);
bo->is_primary = true;
+
+ ret = qxl_crtc_apply_cursor(crtc);
+ if (ret) {
+ DRM_ERROR("could not set cursor after modeset");
+ ret = 0;
+ }
}
if (bo->is_primary) {
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 8e633caa4078..5f3e5ad99de7 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -137,6 +137,7 @@ struct qxl_crtc {
int cur_y;
int hot_spot_x;
int hot_spot_y;
+ struct qxl_bo *cursor_bo;
};
struct qxl_output {