diff options
Diffstat (limited to 'drivers/gpu')
| -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 | ||
