]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.21/drm-qxl-reapply-cursor-after-resetting-primary.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.14.21 / drm-qxl-reapply-cursor-after-resetting-primary.patch
1 From 9428088c90b6f7d5edd2a1b0d742c75339b36f6e Mon Sep 17 00:00:00 2001
2 From: Ray Strode <rstrode@redhat.com>
3 Date: Mon, 27 Nov 2017 16:50:10 -0500
4 Subject: drm/qxl: reapply cursor after resetting primary
5
6 From: Ray Strode <rstrode@redhat.com>
7
8 commit 9428088c90b6f7d5edd2a1b0d742c75339b36f6e upstream.
9
10 QXL associates mouse state with its primary plane.
11
12 Destroying a primary plane and putting a new one in place has the side
13 effect of destroying the cursor as well.
14
15 This commit changes the driver to reapply the cursor any time a new
16 primary is created. It achieves this by keeping a reference to the
17 cursor bo on the qxl_crtc struct.
18
19 This fix is very similar to
20
21 commit 4532b241a4b7 ("drm/qxl: reapply cursor after SetCrtc calls")
22
23 which got implicitly reverted as part of implementing the atomic
24 modeset feature.
25
26 Cc: Gerd Hoffmann <kraxel@redhat.com>
27 Cc: Dave Airlie <airlied@redhat.com>
28 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1512097
29 Fixes: 1277eed5fecb ("drm: qxl: Atomic phase 1: convert cursor to universal plane")
30 Cc: stable@vger.kernel.org
31 Signed-off-by: Ray Strode <rstrode@redhat.com>
32 Signed-off-by: Dave Airlie <airlied@redhat.com>
33 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
34
35 ---
36 drivers/gpu/drm/qxl/qxl_display.c | 59 ++++++++++++++++++++++++++++++++++++++
37 drivers/gpu/drm/qxl/qxl_drv.h | 2 +
38 2 files changed, 61 insertions(+)
39
40 --- a/drivers/gpu/drm/qxl/qxl_display.c
41 +++ b/drivers/gpu/drm/qxl/qxl_display.c
42 @@ -289,6 +289,7 @@ static void qxl_crtc_destroy(struct drm_
43 {
44 struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
45
46 + qxl_bo_unref(&qxl_crtc->cursor_bo);
47 drm_crtc_cleanup(crtc);
48 kfree(qxl_crtc);
49 }
50 @@ -495,6 +496,53 @@ static int qxl_primary_atomic_check(stru
51 return 0;
52 }
53
54 +static int qxl_primary_apply_cursor(struct drm_plane *plane)
55 +{
56 + struct drm_device *dev = plane->dev;
57 + struct qxl_device *qdev = dev->dev_private;
58 + struct drm_framebuffer *fb = plane->state->fb;
59 + struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc);
60 + struct qxl_cursor_cmd *cmd;
61 + struct qxl_release *release;
62 + int ret = 0;
63 +
64 + if (!qcrtc->cursor_bo)
65 + return 0;
66 +
67 + ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
68 + QXL_RELEASE_CURSOR_CMD,
69 + &release, NULL);
70 + if (ret)
71 + return ret;
72 +
73 + ret = qxl_release_list_add(release, qcrtc->cursor_bo);
74 + if (ret)
75 + goto out_free_release;
76 +
77 + ret = qxl_release_reserve_list(release, false);
78 + if (ret)
79 + goto out_free_release;
80 +
81 + cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
82 + cmd->type = QXL_CURSOR_SET;
83 + cmd->u.set.position.x = plane->state->crtc_x + fb->hot_x;
84 + cmd->u.set.position.y = plane->state->crtc_y + fb->hot_y;
85 +
86 + cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0);
87 +
88 + cmd->u.set.visible = 1;
89 + qxl_release_unmap(qdev, release, &cmd->release_info);
90 +
91 + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
92 + qxl_release_fence_buffer_objects(release);
93 +
94 + return ret;
95 +
96 +out_free_release:
97 + qxl_release_free(qdev, release);
98 + return ret;
99 +}
100 +
101 static void qxl_primary_atomic_update(struct drm_plane *plane,
102 struct drm_plane_state *old_state)
103 {
104 @@ -510,6 +558,7 @@ static void qxl_primary_atomic_update(st
105 .x2 = qfb->base.width,
106 .y2 = qfb->base.height
107 };
108 + int ret;
109 bool same_shadow = false;
110
111 if (old_state->fb) {
112 @@ -531,6 +580,11 @@ static void qxl_primary_atomic_update(st
113 if (!same_shadow)
114 qxl_io_destroy_primary(qdev);
115 bo_old->is_primary = false;
116 +
117 + ret = qxl_primary_apply_cursor(plane);
118 + if (ret)
119 + DRM_ERROR(
120 + "could not set cursor after creating primary");
121 }
122
123 if (!bo->is_primary) {
124 @@ -571,6 +625,7 @@ static void qxl_cursor_atomic_update(str
125 struct drm_device *dev = plane->dev;
126 struct qxl_device *qdev = dev->dev_private;
127 struct drm_framebuffer *fb = plane->state->fb;
128 + struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc);
129 struct qxl_release *release;
130 struct qxl_cursor_cmd *cmd;
131 struct qxl_cursor *cursor;
132 @@ -628,6 +683,10 @@ static void qxl_cursor_atomic_update(str
133 cmd->u.set.shape = qxl_bo_physical_address(qdev,
134 cursor_bo, 0);
135 cmd->type = QXL_CURSOR_SET;
136 +
137 + qxl_bo_unref(&qcrtc->cursor_bo);
138 + qcrtc->cursor_bo = cursor_bo;
139 + cursor_bo = NULL;
140 } else {
141
142 ret = qxl_release_reserve_list(release, true);
143 --- a/drivers/gpu/drm/qxl/qxl_drv.h
144 +++ b/drivers/gpu/drm/qxl/qxl_drv.h
145 @@ -135,6 +135,8 @@ struct qxl_bo_list {
146 struct qxl_crtc {
147 struct drm_crtc base;
148 int index;
149 +
150 + struct qxl_bo *cursor_bo;
151 };
152
153 struct qxl_output {