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

drm/amdgpu/dce10: 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.

Port of radeon commits:
78b1a6010b46a69bcd47b723a80f92693f26d17b
3feba08d79c32777a845c3c8a4ab93092bdf6f19

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

+55 -23
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
··· 373 373 uint32_t crtc_offset; 374 374 struct drm_gem_object *cursor_bo; 375 375 uint64_t cursor_addr; 376 + int cursor_x; 377 + int cursor_y; 378 + int cursor_hot_x; 379 + int cursor_hot_y; 376 380 int cursor_width; 377 381 int cursor_height; 378 382 int max_cursor_width;
+51 -23
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
··· 2505 2505 WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp); 2506 2506 } 2507 2507 2508 - static void dce_v10_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, 2509 - uint64_t gpu_addr) 2510 - { 2511 - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2512 - struct amdgpu_device *adev = crtc->dev->dev_private; 2513 - 2514 - WREG32(mmCUR_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, 2515 - upper_32_bits(gpu_addr)); 2516 - WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, 2517 - lower_32_bits(gpu_addr)); 2518 - } 2519 - 2520 - static int dce_v10_0_crtc_cursor_move(struct drm_crtc *crtc, 2521 - int x, int y) 2508 + static int dce_v10_0_cursor_move_locked(struct drm_crtc *crtc, 2509 + int x, int y) 2522 2510 { 2523 2511 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2524 2512 struct amdgpu_device *adev = crtc->dev->dev_private; ··· 2526 2538 y = 0; 2527 2539 } 2528 2540 2529 - dce_v10_0_lock_cursor(crtc, true); 2530 2541 WREG32(mmCUR_POSITION + amdgpu_crtc->crtc_offset, (x << 16) | y); 2531 2542 WREG32(mmCUR_HOT_SPOT + amdgpu_crtc->crtc_offset, (xorigin << 16) | yorigin); 2532 2543 WREG32(mmCUR_SIZE + amdgpu_crtc->crtc_offset, 2533 2544 ((amdgpu_crtc->cursor_width - 1) << 16) | (amdgpu_crtc->cursor_height - 1)); 2534 - dce_v10_0_lock_cursor(crtc, false); 2545 + 2546 + amdgpu_crtc->cursor_x = x; 2547 + amdgpu_crtc->cursor_y = y; 2535 2548 2536 2549 return 0; 2537 2550 } 2538 2551 2539 - static int dce_v10_0_crtc_cursor_set(struct drm_crtc *crtc, 2540 - struct drm_file *file_priv, 2541 - uint32_t handle, 2542 - uint32_t width, 2543 - uint32_t height) 2552 + static void dce_v10_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, 2553 + uint64_t gpu_addr, int hot_x, int hot_y) 2554 + { 2555 + struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2556 + struct amdgpu_device *adev = crtc->dev->dev_private; 2557 + 2558 + WREG32(mmCUR_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, 2559 + upper_32_bits(gpu_addr)); 2560 + WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, 2561 + lower_32_bits(gpu_addr)); 2562 + 2563 + if (hot_x != amdgpu_crtc->cursor_hot_x || 2564 + hot_y != amdgpu_crtc->cursor_hot_y) { 2565 + int x, y; 2566 + 2567 + x = amdgpu_crtc->cursor_x + amdgpu_crtc->cursor_hot_x - hot_x; 2568 + y = amdgpu_crtc->cursor_y + amdgpu_crtc->cursor_hot_y - hot_y; 2569 + 2570 + dce_v10_0_cursor_move_locked(crtc, x, y); 2571 + 2572 + amdgpu_crtc->cursor_hot_x = hot_x; 2573 + amdgpu_crtc->cursor_hot_y = hot_y; 2574 + } 2575 + } 2576 + 2577 + static int dce_v10_0_crtc_cursor_move(struct drm_crtc *crtc, 2578 + int x, int y) 2579 + { 2580 + int ret; 2581 + 2582 + dce_v10_0_lock_cursor(crtc, true); 2583 + ret = dce_v10_0_cursor_move_locked(crtc, x, y); 2584 + dce_v10_0_lock_cursor(crtc, false); 2585 + 2586 + return ret; 2587 + } 2588 + 2589 + static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc, 2590 + struct drm_file *file_priv, 2591 + uint32_t handle, 2592 + uint32_t width, 2593 + uint32_t height, 2594 + int32_t hot_x, 2595 + int32_t hot_y) 2544 2596 { 2545 2597 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2546 2598 struct drm_gem_object *obj; ··· 2621 2593 amdgpu_crtc->cursor_height = height; 2622 2594 2623 2595 dce_v10_0_lock_cursor(crtc, true); 2624 - dce_v10_0_set_cursor(crtc, obj, gpu_addr); 2596 + dce_v10_0_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); 2625 2597 dce_v10_0_show_cursor(crtc); 2626 2598 dce_v10_0_lock_cursor(crtc, false); 2627 2599 ··· 2669 2641 } 2670 2642 2671 2643 static const struct drm_crtc_funcs dce_v10_0_crtc_funcs = { 2672 - .cursor_set = dce_v10_0_crtc_cursor_set, 2644 + .cursor_set2 = dce_v10_0_crtc_cursor_set2, 2673 2645 .cursor_move = dce_v10_0_crtc_cursor_move, 2674 2646 .gamma_set = dce_v10_0_crtc_gamma_set, 2675 2647 .set_config = amdgpu_crtc_set_config,