aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2014-11-18 04:00:08 -0500
committerAlex Deucher <alexander.deucher@amd.com>2014-11-20 11:11:41 -0500
commit78b1a6010b46a69bcd47b723a80f92693f26d17b (patch)
treebe63de0ed5b1fe8447f683a5d02741d377b07b35
parentcc5ac1ca79b4976ed3a779d7ea157f078207b56b (diff)
drm/radeon: Use cursor_set2 hook for enabling / disabling the HW cursor
The cursor_set2 hook provides the cursor hotspot position within the cursor image. When the hotspot position changes, we can adjust the cursor position such that the hotspot doesn't move on the screen. This prevents the cursor from appearing to intermittently jump around on the screen when the position of the hotspot within the cursor image changes. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon_cursor.c51
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h16
3 files changed, 52 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
index 9630e8d95fb4..fd4bddfd67d6 100644
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
@@ -117,8 +117,10 @@ static void radeon_show_cursor(struct drm_crtc *crtc)
117 } 117 }
118} 118}
119 119
120static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y);
121
120static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, 122static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
121 uint64_t gpu_addr) 123 uint64_t gpu_addr, int hot_x, int hot_y)
122{ 124{
123 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 125 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
124 struct radeon_device *rdev = crtc->dev->dev_private; 126 struct radeon_device *rdev = crtc->dev->dev_private;
@@ -142,13 +144,28 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
142 /* offset is from DISP(2)_BASE_ADDRESS */ 144 /* offset is from DISP(2)_BASE_ADDRESS */
143 WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); 145 WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
144 } 146 }
147
148 if (hot_x != radeon_crtc->cursor_hot_x ||
149 hot_y != radeon_crtc->cursor_hot_y) {
150 int x, y;
151
152 x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x;
153 y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y;
154
155 radeon_cursor_move_locked(crtc, x, y);
156
157 radeon_crtc->cursor_hot_x = hot_x;
158 radeon_crtc->cursor_hot_y = hot_y;
159 }
145} 160}
146 161
147int radeon_crtc_cursor_set(struct drm_crtc *crtc, 162int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
148 struct drm_file *file_priv, 163 struct drm_file *file_priv,
149 uint32_t handle, 164 uint32_t handle,
150 uint32_t width, 165 uint32_t width,
151 uint32_t height) 166 uint32_t height,
167 int32_t hot_x,
168 int32_t hot_y)
152{ 169{
153 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 170 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
154 struct radeon_device *rdev = crtc->dev->dev_private; 171 struct radeon_device *rdev = crtc->dev->dev_private;
@@ -192,7 +209,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
192 radeon_crtc->cursor_height = height; 209 radeon_crtc->cursor_height = height;
193 210
194 radeon_lock_cursor(crtc, true); 211 radeon_lock_cursor(crtc, true);
195 radeon_set_cursor(crtc, obj, gpu_addr); 212 radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y);
196 radeon_show_cursor(crtc); 213 radeon_show_cursor(crtc);
197 radeon_lock_cursor(crtc, false); 214 radeon_lock_cursor(crtc, false);
198 215
@@ -215,8 +232,7 @@ fail:
215 return ret; 232 return ret;
216} 233}
217 234
218int radeon_crtc_cursor_move(struct drm_crtc *crtc, 235static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
219 int x, int y)
220{ 236{
221 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 237 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
222 struct radeon_device *rdev = crtc->dev->dev_private; 238 struct radeon_device *rdev = crtc->dev->dev_private;
@@ -281,7 +297,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
281 } 297 }
282 } 298 }
283 299
284 radeon_lock_cursor(crtc, true);
285 if (ASIC_IS_DCE4(rdev)) { 300 if (ASIC_IS_DCE4(rdev)) {
286 WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); 301 WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y);
287 WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); 302 WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
@@ -308,7 +323,21 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
308 WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + 323 WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset +
309 (yorigin * 256))); 324 (yorigin * 256)));
310 } 325 }
311 radeon_lock_cursor(crtc, false); 326
327 radeon_crtc->cursor_x = x;
328 radeon_crtc->cursor_y = y;
312 329
313 return 0; 330 return 0;
314} 331}
332
333int radeon_crtc_cursor_move(struct drm_crtc *crtc,
334 int x, int y)
335{
336 int ret;
337
338 radeon_lock_cursor(crtc, true);
339 ret = radeon_cursor_move_locked(crtc, x, y);
340 radeon_lock_cursor(crtc, false);
341
342 return ret;
343}
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index f1b0fa1285bb..102116902a07 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -635,7 +635,7 @@ radeon_crtc_set_config(struct drm_mode_set *set)
635 return ret; 635 return ret;
636} 636}
637static const struct drm_crtc_funcs radeon_crtc_funcs = { 637static const struct drm_crtc_funcs radeon_crtc_funcs = {
638 .cursor_set = radeon_crtc_cursor_set, 638 .cursor_set2 = radeon_crtc_cursor_set2,
639 .cursor_move = radeon_crtc_cursor_move, 639 .cursor_move = radeon_crtc_cursor_move,
640 .gamma_set = radeon_crtc_gamma_set, 640 .gamma_set = radeon_crtc_gamma_set,
641 .set_config = radeon_crtc_set_config, 641 .set_config = radeon_crtc_set_config,
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 64eba7ebb354..f3d87cdd5c9d 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -321,6 +321,10 @@ struct radeon_crtc {
321 uint32_t crtc_offset; 321 uint32_t crtc_offset;
322 struct drm_gem_object *cursor_bo; 322 struct drm_gem_object *cursor_bo;
323 uint64_t cursor_addr; 323 uint64_t cursor_addr;
324 int cursor_x;
325 int cursor_y;
326 int cursor_hot_x;
327 int cursor_hot_y;
324 int cursor_width; 328 int cursor_width;
325 int cursor_height; 329 int cursor_height;
326 int max_cursor_width; 330 int max_cursor_width;
@@ -805,11 +809,13 @@ extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
805extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, 809extern int radeon_crtc_do_set_base(struct drm_crtc *crtc,
806 struct drm_framebuffer *fb, 810 struct drm_framebuffer *fb,
807 int x, int y, int atomic); 811 int x, int y, int atomic);
808extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, 812extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
809 struct drm_file *file_priv, 813 struct drm_file *file_priv,
810 uint32_t handle, 814 uint32_t handle,
811 uint32_t width, 815 uint32_t width,
812 uint32_t height); 816 uint32_t height,
817 int32_t hot_x,
818 int32_t hot_y);
813extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, 819extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
814 int x, int y); 820 int x, int y);
815 821