diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index aaa6561e9fc8..d7f88f33cd73 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | |||
@@ -2449,11 +2449,23 @@ static int dce_v8_0_cursor_move_locked(struct drm_crtc *crtc, | |||
2449 | return 0; | 2449 | return 0; |
2450 | } | 2450 | } |
2451 | 2451 | ||
2452 | static void dce_v8_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | 2452 | static int dce_v8_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, |
2453 | uint64_t gpu_addr, int hot_x, int hot_y) | 2453 | int hot_x, int hot_y) |
2454 | { | 2454 | { |
2455 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2455 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
2456 | struct amdgpu_device *adev = crtc->dev->dev_private; | 2456 | struct amdgpu_device *adev = crtc->dev->dev_private; |
2457 | struct amdgpu_bo *aobj = gem_to_amdgpu_bo(obj); | ||
2458 | uint64_t gpu_addr; | ||
2459 | int ret; | ||
2460 | |||
2461 | ret = amdgpu_bo_reserve(aobj, false); | ||
2462 | if (unlikely(ret != 0)) | ||
2463 | goto fail; | ||
2464 | |||
2465 | ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); | ||
2466 | amdgpu_bo_unreserve(aobj); | ||
2467 | if (ret) | ||
2468 | goto fail; | ||
2457 | 2469 | ||
2458 | WREG32(mmCUR_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, | 2470 | WREG32(mmCUR_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, |
2459 | upper_32_bits(gpu_addr)); | 2471 | upper_32_bits(gpu_addr)); |
@@ -2472,6 +2484,13 @@ static void dce_v8_0_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *ob | |||
2472 | amdgpu_crtc->cursor_hot_x = hot_x; | 2484 | amdgpu_crtc->cursor_hot_x = hot_x; |
2473 | amdgpu_crtc->cursor_hot_y = hot_y; | 2485 | amdgpu_crtc->cursor_hot_y = hot_y; |
2474 | } | 2486 | } |
2487 | |||
2488 | return 0; | ||
2489 | |||
2490 | fail: | ||
2491 | drm_gem_object_unreference_unlocked(obj); | ||
2492 | |||
2493 | return ret; | ||
2475 | } | 2494 | } |
2476 | 2495 | ||
2477 | static int dce_v8_0_crtc_cursor_move(struct drm_crtc *crtc, | 2496 | static int dce_v8_0_crtc_cursor_move(struct drm_crtc *crtc, |
@@ -2496,8 +2515,6 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc, | |||
2496 | { | 2515 | { |
2497 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2516 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
2498 | struct drm_gem_object *obj; | 2517 | struct drm_gem_object *obj; |
2499 | struct amdgpu_bo *robj; | ||
2500 | uint64_t gpu_addr; | ||
2501 | int ret; | 2518 | int ret; |
2502 | 2519 | ||
2503 | if (!handle) { | 2520 | if (!handle) { |
@@ -2519,41 +2536,56 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc, | |||
2519 | return -ENOENT; | 2536 | return -ENOENT; |
2520 | } | 2537 | } |
2521 | 2538 | ||
2522 | robj = gem_to_amdgpu_bo(obj); | ||
2523 | ret = amdgpu_bo_reserve(robj, false); | ||
2524 | if (unlikely(ret != 0)) | ||
2525 | goto fail; | ||
2526 | ret = amdgpu_bo_pin_restricted(robj, AMDGPU_GEM_DOMAIN_VRAM, | ||
2527 | 0, 0, &gpu_addr); | ||
2528 | amdgpu_bo_unreserve(robj); | ||
2529 | if (ret) | ||
2530 | goto fail; | ||
2531 | |||
2532 | amdgpu_crtc->cursor_width = width; | 2539 | amdgpu_crtc->cursor_width = width; |
2533 | amdgpu_crtc->cursor_height = height; | 2540 | amdgpu_crtc->cursor_height = height; |
2534 | 2541 | ||
2535 | dce_v8_0_lock_cursor(crtc, true); | 2542 | dce_v8_0_lock_cursor(crtc, true); |
2536 | dce_v8_0_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); | 2543 | ret = dce_v8_0_set_cursor(crtc, obj, hot_x, hot_y); |
2537 | dce_v8_0_show_cursor(crtc); | 2544 | if (ret) |
2545 | DRM_ERROR("dce_v8_0_set_cursor returned %d, not changing cursor\n", | ||
2546 | ret); | ||
2547 | else | ||
2548 | dce_v8_0_show_cursor(crtc); | ||
2538 | dce_v8_0_lock_cursor(crtc, false); | 2549 | dce_v8_0_lock_cursor(crtc, false); |
2539 | 2550 | ||
2540 | unpin: | 2551 | unpin: |
2541 | if (amdgpu_crtc->cursor_bo) { | 2552 | if (amdgpu_crtc->cursor_bo) { |
2542 | robj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | 2553 | struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); |
2543 | ret = amdgpu_bo_reserve(robj, false); | 2554 | ret = amdgpu_bo_reserve(aobj, false); |
2544 | if (likely(ret == 0)) { | 2555 | if (likely(ret == 0)) { |
2545 | amdgpu_bo_unpin(robj); | 2556 | amdgpu_bo_unpin(aobj); |
2546 | amdgpu_bo_unreserve(robj); | 2557 | amdgpu_bo_unreserve(aobj); |
2547 | } | 2558 | } |
2548 | drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo); | 2559 | if (amdgpu_crtc->cursor_bo != obj) |
2560 | drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo); | ||
2549 | } | 2561 | } |
2550 | 2562 | ||
2551 | amdgpu_crtc->cursor_bo = obj; | 2563 | amdgpu_crtc->cursor_bo = obj; |
2552 | return 0; | 2564 | return 0; |
2553 | fail: | 2565 | } |
2554 | drm_gem_object_unreference_unlocked(obj); | ||
2555 | 2566 | ||
2556 | return ret; | 2567 | static void dce_v8_0_cursor_reset(struct drm_crtc *crtc) |
2568 | { | ||
2569 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | ||
2570 | int ret; | ||
2571 | |||
2572 | if (amdgpu_crtc->cursor_bo) { | ||
2573 | dce_v8_0_lock_cursor(crtc, true); | ||
2574 | |||
2575 | dce_v8_0_cursor_move_locked(crtc, amdgpu_crtc->cursor_x, | ||
2576 | amdgpu_crtc->cursor_y); | ||
2577 | |||
2578 | ret = dce_v8_0_set_cursor(crtc, amdgpu_crtc->cursor_bo, | ||
2579 | amdgpu_crtc->cursor_hot_x, | ||
2580 | amdgpu_crtc->cursor_hot_y); | ||
2581 | if (ret) | ||
2582 | DRM_ERROR("dce_v8_0_set_cursor returned %d, not showing " | ||
2583 | "cursor\n", ret); | ||
2584 | else | ||
2585 | dce_v8_0_show_cursor(crtc); | ||
2586 | |||
2587 | dce_v8_0_lock_cursor(crtc, false); | ||
2588 | } | ||
2557 | } | 2589 | } |
2558 | 2590 | ||
2559 | static void dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, | 2591 | static void dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, |
@@ -2721,6 +2753,7 @@ static int dce_v8_0_crtc_mode_set(struct drm_crtc *crtc, | |||
2721 | dce_v8_0_crtc_do_set_base(crtc, old_fb, x, y, 0); | 2753 | dce_v8_0_crtc_do_set_base(crtc, old_fb, x, y, 0); |
2722 | amdgpu_atombios_crtc_overscan_setup(crtc, mode, adjusted_mode); | 2754 | amdgpu_atombios_crtc_overscan_setup(crtc, mode, adjusted_mode); |
2723 | amdgpu_atombios_crtc_scaler_setup(crtc); | 2755 | amdgpu_atombios_crtc_scaler_setup(crtc); |
2756 | dce_v8_0_cursor_reset(crtc); | ||
2724 | /* update the hw version fpr dpm */ | 2757 | /* update the hw version fpr dpm */ |
2725 | amdgpu_crtc->hw_mode = *adjusted_mode; | 2758 | amdgpu_crtc->hw_mode = *adjusted_mode; |
2726 | 2759 | ||