aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0598-drm-amdgpu-dce11-Re-show-the-cursor-after-a-modeset-.patch
blob: f994d40e8a66396e93d63e23e51fd938bdb8924a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
From 679121985753fce630871366ddcdc66e1f247720 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher@amd.com>
Date: Wed, 7 Oct 2015 17:22:23 -0400
Subject: [PATCH 0598/1050] drm/amdgpu/dce11: Re-show the cursor after a
 modeset (v2)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Setting a mode seems to clear the cursor registers, so we need to
re-program them to make sure the cursor is visible.

Port of radeon commit:
6d3759fac636028849f3bbec80c4b77e9bfdb1d2

v2: change radeon reference in error output

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 81 ++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index eccdecb..d01399b 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2532,11 +2532,23 @@ static int dce_v11_0_cursor_move_locked(struct drm_crtc *crtc,
 	return 0;
 }
 
-static void dce_v11_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
-				 uint64_t gpu_addr, int hot_x, int hot_y)
+static int dce_v11_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
+				int hot_x, int hot_y)
 {
 	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 	struct amdgpu_device *adev = crtc->dev->dev_private;
+	struct amdgpu_bo *aobj = gem_to_amdgpu_bo(obj);
+	uint64_t gpu_addr;
+	int ret;
+
+	ret = amdgpu_bo_reserve(aobj, false);
+	if (unlikely(ret != 0))
+		goto fail;
+
+	ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr);
+	amdgpu_bo_unreserve(aobj);
+	if (ret)
+		goto fail;
 
 	WREG32(mmCUR_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
 	       upper_32_bits(gpu_addr));
@@ -2555,6 +2567,13 @@ static void dce_v11_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *o
 		amdgpu_crtc->cursor_hot_x = hot_x;
 		amdgpu_crtc->cursor_hot_y = hot_y;
 	}
+
+	return 0;
+
+fail:
+	drm_gem_object_unreference_unlocked(obj);
+
+	return ret;
 }
 
 static int dce_v11_0_crtc_cursor_move(struct drm_crtc *crtc,
@@ -2579,8 +2598,6 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
 {
 	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 	struct drm_gem_object *obj;
-	struct amdgpu_bo *robj;
-	uint64_t gpu_addr;
 	int ret;
 
 	if (!handle) {
@@ -2602,41 +2619,56 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
 		return -ENOENT;
 	}
 
-	robj = gem_to_amdgpu_bo(obj);
-	ret = amdgpu_bo_reserve(robj, false);
-	if (unlikely(ret != 0))
-		goto fail;
-	ret = amdgpu_bo_pin_restricted(robj, AMDGPU_GEM_DOMAIN_VRAM,
-				       0, 0, &gpu_addr);
-	amdgpu_bo_unreserve(robj);
-	if (ret)
-		goto fail;
-
 	amdgpu_crtc->cursor_width = width;
 	amdgpu_crtc->cursor_height = height;
 
 	dce_v11_0_lock_cursor(crtc, true);
-	dce_v11_0_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y);
-	dce_v11_0_show_cursor(crtc);
+	ret = dce_v11_0_set_cursor(crtc, obj, hot_x, hot_y);
+	if (ret)
+		DRM_ERROR("dce_v11_0_set_cursor returned %d, not changing cursor\n",
+			  ret);
+	else
+		dce_v11_0_show_cursor(crtc);
 	dce_v11_0_lock_cursor(crtc, false);
 
 unpin:
 	if (amdgpu_crtc->cursor_bo) {
-		robj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
-		ret = amdgpu_bo_reserve(robj, false);
+		struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
+		ret = amdgpu_bo_reserve(aobj, false);
 		if (likely(ret == 0)) {
-			amdgpu_bo_unpin(robj);
-			amdgpu_bo_unreserve(robj);
+			amdgpu_bo_unpin(aobj);
+			amdgpu_bo_unreserve(aobj);
 		}
-		drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+		if (amdgpu_crtc->cursor_bo != obj)
+			drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
 	}
 
 	amdgpu_crtc->cursor_bo = obj;
 	return 0;
-fail:
-	drm_gem_object_unreference_unlocked(obj);
+}
 
-	return ret;
+static void dce_v11_0_cursor_reset(struct drm_crtc *crtc)
+{
+	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+	int ret;
+
+	if (amdgpu_crtc->cursor_bo) {
+		dce_v11_0_lock_cursor(crtc, true);
+
+		dce_v11_0_cursor_move_locked(crtc, amdgpu_crtc->cursor_x,
+					     amdgpu_crtc->cursor_y);
+
+		ret = dce_v11_0_set_cursor(crtc, amdgpu_crtc->cursor_bo,
+					   amdgpu_crtc->cursor_hot_x,
+					   amdgpu_crtc->cursor_hot_y);
+		if (ret)
+			DRM_ERROR("dce_v11_0_set_cursor returned %d, not showing "
+				  "cursor\n", ret);
+		else
+			dce_v11_0_show_cursor(crtc);
+
+		dce_v11_0_lock_cursor(crtc, false);
+	}
 }
 
 static void dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
@@ -2798,6 +2830,7 @@ static int dce_v11_0_crtc_mode_set(struct drm_crtc *crtc,
 	dce_v11_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
 	amdgpu_atombios_crtc_overscan_setup(crtc, mode, adjusted_mode);
 	amdgpu_atombios_crtc_scaler_setup(crtc);
+	dce_v11_0_cursor_reset(crtc);
 	/* update the hw version fpr dpm */
 	amdgpu_crtc->hw_mode = *adjusted_mode;
 
-- 
1.9.1