diff options
author | Dave Airlie <airlied@redhat.com> | 2018-07-26 22:31:07 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-07-26 22:31:48 -0400 |
commit | 6d52aacd92c60331ec8c3117522f4301b5195e28 (patch) | |
tree | 0f2584c46d269f9537bd2fe4e018313c1bb0056d /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |
parent | daa9897560e20f397af602b7384a014546fc422c (diff) | |
parent | 586092ab4b768b01b3184d9a2541e2cf9a8d9740 (diff) |
Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next
Updates for 4.19. Mostly bug fixes and cleanups. Highlights:
- Internal API cleanup in GPU scheduler
- Decouple i2c and aux abstractions in DC
- Update maintainers
- Misc cleanups
- Misc bug fixes
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180725215326.2709-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 204 |
1 files changed, 135 insertions, 69 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 386a7b34d2f4..ec53d8f96d06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1926,7 +1926,7 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) | |||
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | /** | 1928 | /** |
1929 | * amdgpu_device_ip_suspend - run suspend for hardware IPs | 1929 | * amdgpu_device_ip_suspend_phase1 - run suspend for hardware IPs (phase 1) |
1930 | * | 1930 | * |
1931 | * @adev: amdgpu_device pointer | 1931 | * @adev: amdgpu_device pointer |
1932 | * | 1932 | * |
@@ -1936,7 +1936,55 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) | |||
1936 | * in each IP into a state suitable for suspend. | 1936 | * in each IP into a state suitable for suspend. |
1937 | * Returns 0 on success, negative error code on failure. | 1937 | * Returns 0 on success, negative error code on failure. |
1938 | */ | 1938 | */ |
1939 | int amdgpu_device_ip_suspend(struct amdgpu_device *adev) | 1939 | static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev) |
1940 | { | ||
1941 | int i, r; | ||
1942 | |||
1943 | if (amdgpu_sriov_vf(adev)) | ||
1944 | amdgpu_virt_request_full_gpu(adev, false); | ||
1945 | |||
1946 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | ||
1947 | if (!adev->ip_blocks[i].status.valid) | ||
1948 | continue; | ||
1949 | /* displays are handled separately */ | ||
1950 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) { | ||
1951 | /* ungate blocks so that suspend can properly shut them down */ | ||
1952 | if (adev->ip_blocks[i].version->funcs->set_clockgating_state) { | ||
1953 | r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, | ||
1954 | AMD_CG_STATE_UNGATE); | ||
1955 | if (r) { | ||
1956 | DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", | ||
1957 | adev->ip_blocks[i].version->funcs->name, r); | ||
1958 | } | ||
1959 | } | ||
1960 | /* XXX handle errors */ | ||
1961 | r = adev->ip_blocks[i].version->funcs->suspend(adev); | ||
1962 | /* XXX handle errors */ | ||
1963 | if (r) { | ||
1964 | DRM_ERROR("suspend of IP block <%s> failed %d\n", | ||
1965 | adev->ip_blocks[i].version->funcs->name, r); | ||
1966 | } | ||
1967 | } | ||
1968 | } | ||
1969 | |||
1970 | if (amdgpu_sriov_vf(adev)) | ||
1971 | amdgpu_virt_release_full_gpu(adev, false); | ||
1972 | |||
1973 | return 0; | ||
1974 | } | ||
1975 | |||
1976 | /** | ||
1977 | * amdgpu_device_ip_suspend_phase2 - run suspend for hardware IPs (phase 2) | ||
1978 | * | ||
1979 | * @adev: amdgpu_device pointer | ||
1980 | * | ||
1981 | * Main suspend function for hardware IPs. The list of all the hardware | ||
1982 | * IPs that make up the asic is walked, clockgating is disabled and the | ||
1983 | * suspend callbacks are run. suspend puts the hardware and software state | ||
1984 | * in each IP into a state suitable for suspend. | ||
1985 | * Returns 0 on success, negative error code on failure. | ||
1986 | */ | ||
1987 | static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) | ||
1940 | { | 1988 | { |
1941 | int i, r; | 1989 | int i, r; |
1942 | 1990 | ||
@@ -1957,6 +2005,9 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) | |||
1957 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 2005 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
1958 | if (!adev->ip_blocks[i].status.valid) | 2006 | if (!adev->ip_blocks[i].status.valid) |
1959 | continue; | 2007 | continue; |
2008 | /* displays are handled in phase1 */ | ||
2009 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) | ||
2010 | continue; | ||
1960 | /* ungate blocks so that suspend can properly shut them down */ | 2011 | /* ungate blocks so that suspend can properly shut them down */ |
1961 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_SMC && | 2012 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_SMC && |
1962 | adev->ip_blocks[i].version->funcs->set_clockgating_state) { | 2013 | adev->ip_blocks[i].version->funcs->set_clockgating_state) { |
@@ -1982,6 +2033,29 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) | |||
1982 | return 0; | 2033 | return 0; |
1983 | } | 2034 | } |
1984 | 2035 | ||
2036 | /** | ||
2037 | * amdgpu_device_ip_suspend - run suspend for hardware IPs | ||
2038 | * | ||
2039 | * @adev: amdgpu_device pointer | ||
2040 | * | ||
2041 | * Main suspend function for hardware IPs. The list of all the hardware | ||
2042 | * IPs that make up the asic is walked, clockgating is disabled and the | ||
2043 | * suspend callbacks are run. suspend puts the hardware and software state | ||
2044 | * in each IP into a state suitable for suspend. | ||
2045 | * Returns 0 on success, negative error code on failure. | ||
2046 | */ | ||
2047 | int amdgpu_device_ip_suspend(struct amdgpu_device *adev) | ||
2048 | { | ||
2049 | int r; | ||
2050 | |||
2051 | r = amdgpu_device_ip_suspend_phase1(adev); | ||
2052 | if (r) | ||
2053 | return r; | ||
2054 | r = amdgpu_device_ip_suspend_phase2(adev); | ||
2055 | |||
2056 | return r; | ||
2057 | } | ||
2058 | |||
1985 | static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) | 2059 | static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) |
1986 | { | 2060 | { |
1987 | int i, r; | 2061 | int i, r; |
@@ -2004,7 +2078,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) | |||
2004 | continue; | 2078 | continue; |
2005 | 2079 | ||
2006 | r = block->version->funcs->hw_init(adev); | 2080 | r = block->version->funcs->hw_init(adev); |
2007 | DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"successed"); | 2081 | DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"succeeded"); |
2008 | if (r) | 2082 | if (r) |
2009 | return r; | 2083 | return r; |
2010 | } | 2084 | } |
@@ -2039,7 +2113,7 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev) | |||
2039 | continue; | 2113 | continue; |
2040 | 2114 | ||
2041 | r = block->version->funcs->hw_init(adev); | 2115 | r = block->version->funcs->hw_init(adev); |
2042 | DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"successed"); | 2116 | DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"succeeded"); |
2043 | if (r) | 2117 | if (r) |
2044 | return r; | 2118 | return r; |
2045 | } | 2119 | } |
@@ -2628,6 +2702,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) | |||
2628 | 2702 | ||
2629 | drm_kms_helper_poll_disable(dev); | 2703 | drm_kms_helper_poll_disable(dev); |
2630 | 2704 | ||
2705 | if (fbcon) | ||
2706 | amdgpu_fbdev_set_suspend(adev, 1); | ||
2707 | |||
2631 | if (!amdgpu_device_has_dc_support(adev)) { | 2708 | if (!amdgpu_device_has_dc_support(adev)) { |
2632 | /* turn off display hw */ | 2709 | /* turn off display hw */ |
2633 | drm_modeset_lock_all(dev); | 2710 | drm_modeset_lock_all(dev); |
@@ -2635,44 +2712,46 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) | |||
2635 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 2712 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
2636 | } | 2713 | } |
2637 | drm_modeset_unlock_all(dev); | 2714 | drm_modeset_unlock_all(dev); |
2638 | } | 2715 | /* unpin the front buffers and cursors */ |
2639 | 2716 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
2640 | amdgpu_amdkfd_suspend(adev); | 2717 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
2641 | 2718 | struct drm_framebuffer *fb = crtc->primary->fb; | |
2642 | /* unpin the front buffers and cursors */ | 2719 | struct amdgpu_bo *robj; |
2643 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 2720 | |
2644 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2721 | if (amdgpu_crtc->cursor_bo) { |
2645 | struct drm_framebuffer *fb = crtc->primary->fb; | 2722 | struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); |
2646 | struct amdgpu_bo *robj; | 2723 | r = amdgpu_bo_reserve(aobj, true); |
2647 | 2724 | if (r == 0) { | |
2648 | if (amdgpu_crtc->cursor_bo) { | 2725 | amdgpu_bo_unpin(aobj); |
2649 | struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | 2726 | amdgpu_bo_unreserve(aobj); |
2650 | r = amdgpu_bo_reserve(aobj, true); | 2727 | } |
2651 | if (r == 0) { | ||
2652 | amdgpu_bo_unpin(aobj); | ||
2653 | amdgpu_bo_unreserve(aobj); | ||
2654 | } | 2728 | } |
2655 | } | ||
2656 | 2729 | ||
2657 | if (fb == NULL || fb->obj[0] == NULL) { | 2730 | if (fb == NULL || fb->obj[0] == NULL) { |
2658 | continue; | 2731 | continue; |
2659 | } | 2732 | } |
2660 | robj = gem_to_amdgpu_bo(fb->obj[0]); | 2733 | robj = gem_to_amdgpu_bo(fb->obj[0]); |
2661 | /* don't unpin kernel fb objects */ | 2734 | /* don't unpin kernel fb objects */ |
2662 | if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { | 2735 | if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { |
2663 | r = amdgpu_bo_reserve(robj, true); | 2736 | r = amdgpu_bo_reserve(robj, true); |
2664 | if (r == 0) { | 2737 | if (r == 0) { |
2665 | amdgpu_bo_unpin(robj); | 2738 | amdgpu_bo_unpin(robj); |
2666 | amdgpu_bo_unreserve(robj); | 2739 | amdgpu_bo_unreserve(robj); |
2740 | } | ||
2667 | } | 2741 | } |
2668 | } | 2742 | } |
2669 | } | 2743 | } |
2744 | |||
2745 | amdgpu_amdkfd_suspend(adev); | ||
2746 | |||
2747 | r = amdgpu_device_ip_suspend_phase1(adev); | ||
2748 | |||
2670 | /* evict vram memory */ | 2749 | /* evict vram memory */ |
2671 | amdgpu_bo_evict_vram(adev); | 2750 | amdgpu_bo_evict_vram(adev); |
2672 | 2751 | ||
2673 | amdgpu_fence_driver_suspend(adev); | 2752 | amdgpu_fence_driver_suspend(adev); |
2674 | 2753 | ||
2675 | r = amdgpu_device_ip_suspend(adev); | 2754 | r = amdgpu_device_ip_suspend_phase2(adev); |
2676 | 2755 | ||
2677 | /* evict remaining vram memory | 2756 | /* evict remaining vram memory |
2678 | * This second call to evict vram is to evict the gart page table | 2757 | * This second call to evict vram is to evict the gart page table |
@@ -2691,11 +2770,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) | |||
2691 | DRM_ERROR("amdgpu asic reset failed\n"); | 2770 | DRM_ERROR("amdgpu asic reset failed\n"); |
2692 | } | 2771 | } |
2693 | 2772 | ||
2694 | if (fbcon) { | ||
2695 | console_lock(); | ||
2696 | amdgpu_fbdev_set_suspend(adev, 1); | ||
2697 | console_unlock(); | ||
2698 | } | ||
2699 | return 0; | 2773 | return 0; |
2700 | } | 2774 | } |
2701 | 2775 | ||
@@ -2720,15 +2794,12 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2720 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 2794 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
2721 | return 0; | 2795 | return 0; |
2722 | 2796 | ||
2723 | if (fbcon) | ||
2724 | console_lock(); | ||
2725 | |||
2726 | if (resume) { | 2797 | if (resume) { |
2727 | pci_set_power_state(dev->pdev, PCI_D0); | 2798 | pci_set_power_state(dev->pdev, PCI_D0); |
2728 | pci_restore_state(dev->pdev); | 2799 | pci_restore_state(dev->pdev); |
2729 | r = pci_enable_device(dev->pdev); | 2800 | r = pci_enable_device(dev->pdev); |
2730 | if (r) | 2801 | if (r) |
2731 | goto unlock; | 2802 | return r; |
2732 | } | 2803 | } |
2733 | 2804 | ||
2734 | /* post card */ | 2805 | /* post card */ |
@@ -2741,28 +2812,30 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2741 | r = amdgpu_device_ip_resume(adev); | 2812 | r = amdgpu_device_ip_resume(adev); |
2742 | if (r) { | 2813 | if (r) { |
2743 | DRM_ERROR("amdgpu_device_ip_resume failed (%d).\n", r); | 2814 | DRM_ERROR("amdgpu_device_ip_resume failed (%d).\n", r); |
2744 | goto unlock; | 2815 | return r; |
2745 | } | 2816 | } |
2746 | amdgpu_fence_driver_resume(adev); | 2817 | amdgpu_fence_driver_resume(adev); |
2747 | 2818 | ||
2748 | 2819 | ||
2749 | r = amdgpu_device_ip_late_init(adev); | 2820 | r = amdgpu_device_ip_late_init(adev); |
2750 | if (r) | 2821 | if (r) |
2751 | goto unlock; | 2822 | return r; |
2752 | 2823 | ||
2753 | /* pin cursors */ | 2824 | if (!amdgpu_device_has_dc_support(adev)) { |
2754 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 2825 | /* pin cursors */ |
2755 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2826 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
2756 | 2827 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | |
2757 | if (amdgpu_crtc->cursor_bo) { | 2828 | |
2758 | struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); | 2829 | if (amdgpu_crtc->cursor_bo) { |
2759 | r = amdgpu_bo_reserve(aobj, true); | 2830 | struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); |
2760 | if (r == 0) { | 2831 | r = amdgpu_bo_reserve(aobj, true); |
2761 | r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); | 2832 | if (r == 0) { |
2762 | if (r != 0) | 2833 | r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); |
2763 | DRM_ERROR("Failed to pin cursor BO (%d)\n", r); | 2834 | if (r != 0) |
2764 | amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); | 2835 | DRM_ERROR("Failed to pin cursor BO (%d)\n", r); |
2765 | amdgpu_bo_unreserve(aobj); | 2836 | amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); |
2837 | amdgpu_bo_unreserve(aobj); | ||
2838 | } | ||
2766 | } | 2839 | } |
2767 | } | 2840 | } |
2768 | } | 2841 | } |
@@ -2783,6 +2856,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2783 | } | 2856 | } |
2784 | drm_modeset_unlock_all(dev); | 2857 | drm_modeset_unlock_all(dev); |
2785 | } | 2858 | } |
2859 | amdgpu_fbdev_set_suspend(adev, 0); | ||
2786 | } | 2860 | } |
2787 | 2861 | ||
2788 | drm_kms_helper_poll_enable(dev); | 2862 | drm_kms_helper_poll_enable(dev); |
@@ -2806,15 +2880,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2806 | #ifdef CONFIG_PM | 2880 | #ifdef CONFIG_PM |
2807 | dev->dev->power.disable_depth--; | 2881 | dev->dev->power.disable_depth--; |
2808 | #endif | 2882 | #endif |
2809 | 2883 | return 0; | |
2810 | if (fbcon) | ||
2811 | amdgpu_fbdev_set_suspend(adev, 0); | ||
2812 | |||
2813 | unlock: | ||
2814 | if (fbcon) | ||
2815 | console_unlock(); | ||
2816 | |||
2817 | return r; | ||
2818 | } | 2884 | } |
2819 | 2885 | ||
2820 | /** | 2886 | /** |
@@ -3091,7 +3157,7 @@ static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev) | |||
3091 | * @adev: amdgpu device pointer | 3157 | * @adev: amdgpu device pointer |
3092 | * | 3158 | * |
3093 | * attempt to do soft-reset or full-reset and reinitialize Asic | 3159 | * attempt to do soft-reset or full-reset and reinitialize Asic |
3094 | * return 0 means successed otherwise failed | 3160 | * return 0 means succeeded otherwise failed |
3095 | */ | 3161 | */ |
3096 | static int amdgpu_device_reset(struct amdgpu_device *adev) | 3162 | static int amdgpu_device_reset(struct amdgpu_device *adev) |
3097 | { | 3163 | { |
@@ -3169,7 +3235,7 @@ out: | |||
3169 | * @from_hypervisor: request from hypervisor | 3235 | * @from_hypervisor: request from hypervisor |
3170 | * | 3236 | * |
3171 | * do VF FLR and reinitialize Asic | 3237 | * do VF FLR and reinitialize Asic |
3172 | * return 0 means successed otherwise failed | 3238 | * return 0 means succeeded otherwise failed |
3173 | */ | 3239 | */ |
3174 | static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, | 3240 | static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, |
3175 | bool from_hypervisor) | 3241 | bool from_hypervisor) |
@@ -3294,7 +3360,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, | |||
3294 | dev_info(adev->dev, "GPU reset(%d) failed\n", atomic_read(&adev->gpu_reset_counter)); | 3360 | dev_info(adev->dev, "GPU reset(%d) failed\n", atomic_read(&adev->gpu_reset_counter)); |
3295 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); | 3361 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); |
3296 | } else { | 3362 | } else { |
3297 | dev_info(adev->dev, "GPU reset(%d) successed!\n",atomic_read(&adev->gpu_reset_counter)); | 3363 | dev_info(adev->dev, "GPU reset(%d) succeeded!\n",atomic_read(&adev->gpu_reset_counter)); |
3298 | } | 3364 | } |
3299 | 3365 | ||
3300 | amdgpu_vf_error_trans_all(adev); | 3366 | amdgpu_vf_error_trans_all(adev); |