Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: Re-show the cursor after a modeset

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

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Michel Dänzer and committed by
Alex Deucher
6d3759fa d5b75dc0

+68 -24
+1
drivers/gpu/drm/radeon/atombios_crtc.c
··· 2039 2039 atombios_crtc_set_base(crtc, x, y, old_fb); 2040 2040 atombios_overscan_setup(crtc, mode, adjusted_mode); 2041 2041 atombios_scaler_setup(crtc); 2042 + radeon_cursor_reset(crtc); 2042 2043 /* update the hw version fpr dpm */ 2043 2044 radeon_crtc->hw_mode = *adjusted_mode; 2044 2045
+65 -24
drivers/gpu/drm/radeon/radeon_cursor.c
··· 227 227 return ret; 228 228 } 229 229 230 - static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, 231 - uint64_t gpu_addr, int hot_x, int hot_y) 230 + static int radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, 231 + int hot_x, int hot_y) 232 232 { 233 233 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 234 234 struct radeon_device *rdev = crtc->dev->dev_private; 235 + struct radeon_bo *robj = gem_to_radeon_bo(obj); 236 + uint64_t gpu_addr; 237 + int ret; 238 + 239 + ret = radeon_bo_reserve(robj, false); 240 + if (unlikely(ret != 0)) 241 + goto fail; 242 + /* Only 27 bit offset for legacy cursor */ 243 + ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, 244 + ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, 245 + &gpu_addr); 246 + radeon_bo_unreserve(robj); 247 + if (ret) 248 + goto fail; 235 249 236 250 if (ASIC_IS_DCE4(rdev)) { 237 251 WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, ··· 279 265 radeon_crtc->cursor_hot_x = hot_x; 280 266 radeon_crtc->cursor_hot_y = hot_y; 281 267 } 268 + 269 + return 0; 270 + 271 + fail: 272 + drm_gem_object_unreference_unlocked(obj); 273 + 274 + return ret; 282 275 } 283 276 284 277 int radeon_crtc_cursor_set2(struct drm_crtc *crtc, ··· 297 276 int32_t hot_y) 298 277 { 299 278 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 300 - struct radeon_device *rdev = crtc->dev->dev_private; 301 279 struct drm_gem_object *obj; 302 - struct radeon_bo *robj; 303 - uint64_t gpu_addr; 304 280 int ret; 305 281 306 282 if (!handle) { ··· 319 301 return -ENOENT; 320 302 } 321 303 322 - robj = gem_to_radeon_bo(obj); 323 - ret = radeon_bo_reserve(robj, false); 324 - if (unlikely(ret != 0)) 325 - goto fail; 326 - /* Only 27 bit offset for legacy cursor */ 327 - ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, 328 - ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, 329 - &gpu_addr); 330 - radeon_bo_unreserve(robj); 331 - if (ret) 332 - goto fail; 333 - 334 304 radeon_crtc->cursor_width = width; 335 305 radeon_crtc->cursor_height = height; 336 306 337 307 radeon_lock_cursor(crtc, true); 338 - radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); 339 - radeon_show_cursor(crtc); 308 + ret = radeon_set_cursor(crtc, obj, hot_x, hot_y); 309 + 310 + if (ret) 311 + DRM_ERROR("radeon_set_cursor returned %d, not changing cursor\n", 312 + ret); 313 + else 314 + radeon_show_cursor(crtc); 315 + 340 316 radeon_lock_cursor(crtc, false); 341 317 342 318 unpin: 343 319 if (radeon_crtc->cursor_bo) { 344 - robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); 320 + struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); 345 321 ret = radeon_bo_reserve(robj, false); 346 322 if (likely(ret == 0)) { 347 323 radeon_bo_unpin(robj); 348 324 radeon_bo_unreserve(robj); 349 325 } 350 - drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); 326 + if (radeon_crtc->cursor_bo != obj) 327 + drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); 351 328 } 352 329 353 330 radeon_crtc->cursor_bo = obj; 354 331 return 0; 355 - fail: 356 - drm_gem_object_unreference_unlocked(obj); 332 + } 357 333 358 - return ret; 334 + /** 335 + * radeon_cursor_reset - Re-set the current cursor, if any. 336 + * 337 + * @crtc: drm crtc 338 + * 339 + * If the CRTC passed in currently has a cursor assigned, this function 340 + * makes sure it's visible. 341 + */ 342 + void radeon_cursor_reset(struct drm_crtc *crtc) 343 + { 344 + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 345 + int ret; 346 + 347 + if (radeon_crtc->cursor_bo) { 348 + radeon_lock_cursor(crtc, true); 349 + 350 + radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, 351 + radeon_crtc->cursor_y); 352 + 353 + ret = radeon_set_cursor(crtc, radeon_crtc->cursor_bo, 354 + radeon_crtc->cursor_hot_x, 355 + radeon_crtc->cursor_hot_y); 356 + if (ret) 357 + DRM_ERROR("radeon_set_cursor returned %d, not showing " 358 + "cursor\n", ret); 359 + else 360 + radeon_show_cursor(crtc); 361 + 362 + radeon_lock_cursor(crtc, false); 363 + } 359 364 }
+1
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
··· 1054 1054 DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); 1055 1055 } 1056 1056 } 1057 + radeon_cursor_reset(crtc); 1057 1058 return 0; 1058 1059 } 1059 1060
+1
drivers/gpu/drm/radeon/radeon_mode.h
··· 818 818 int32_t hot_y); 819 819 extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, 820 820 int x, int y); 821 + extern void radeon_cursor_reset(struct drm_crtc *crtc); 821 822 822 823 extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, 823 824 unsigned int flags,