diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 105 |
1 files changed, 89 insertions, 16 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index efcacb827de7..2d792cdc094c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/debugfs.h> | 31 | #include <linux/debugfs.h> |
32 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
33 | #include <drm/drm_crtc_helper.h> | 33 | #include <drm/drm_crtc_helper.h> |
34 | #include <drm/drm_atomic_helper.h> | ||
34 | #include <drm/amdgpu_drm.h> | 35 | #include <drm/amdgpu_drm.h> |
35 | #include <linux/vgaarb.h> | 36 | #include <linux/vgaarb.h> |
36 | #include <linux/vga_switcheroo.h> | 37 | #include <linux/vga_switcheroo.h> |
@@ -2046,6 +2047,52 @@ static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) | |||
2046 | } | 2047 | } |
2047 | } | 2048 | } |
2048 | 2049 | ||
2050 | bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) | ||
2051 | { | ||
2052 | switch (asic_type) { | ||
2053 | #if defined(CONFIG_DRM_AMD_DC) | ||
2054 | case CHIP_BONAIRE: | ||
2055 | case CHIP_HAWAII: | ||
2056 | case CHIP_KAVERI: | ||
2057 | case CHIP_CARRIZO: | ||
2058 | case CHIP_STONEY: | ||
2059 | case CHIP_POLARIS11: | ||
2060 | case CHIP_POLARIS10: | ||
2061 | case CHIP_POLARIS12: | ||
2062 | case CHIP_TONGA: | ||
2063 | case CHIP_FIJI: | ||
2064 | #if defined(CONFIG_DRM_AMD_DC_PRE_VEGA) | ||
2065 | return amdgpu_dc != 0; | ||
2066 | #endif | ||
2067 | case CHIP_KABINI: | ||
2068 | case CHIP_MULLINS: | ||
2069 | return amdgpu_dc > 0; | ||
2070 | case CHIP_VEGA10: | ||
2071 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | ||
2072 | case CHIP_RAVEN: | ||
2073 | #endif | ||
2074 | return amdgpu_dc != 0; | ||
2075 | #endif | ||
2076 | default: | ||
2077 | return false; | ||
2078 | } | ||
2079 | } | ||
2080 | |||
2081 | /** | ||
2082 | * amdgpu_device_has_dc_support - check if dc is supported | ||
2083 | * | ||
2084 | * @adev: amdgpu_device_pointer | ||
2085 | * | ||
2086 | * Returns true for supported, false for not supported | ||
2087 | */ | ||
2088 | bool amdgpu_device_has_dc_support(struct amdgpu_device *adev) | ||
2089 | { | ||
2090 | if (amdgpu_sriov_vf(adev)) | ||
2091 | return false; | ||
2092 | |||
2093 | return amdgpu_device_asic_has_dc_support(adev->asic_type); | ||
2094 | } | ||
2095 | |||
2049 | /** | 2096 | /** |
2050 | * amdgpu_device_init - initialize the driver | 2097 | * amdgpu_device_init - initialize the driver |
2051 | * | 2098 | * |
@@ -2100,7 +2147,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2100 | adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; | 2147 | adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; |
2101 | adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; | 2148 | adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; |
2102 | 2149 | ||
2103 | |||
2104 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", | 2150 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", |
2105 | amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, | 2151 | amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, |
2106 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); | 2152 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); |
@@ -2242,7 +2288,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2242 | goto failed; | 2288 | goto failed; |
2243 | } | 2289 | } |
2244 | /* init i2c buses */ | 2290 | /* init i2c buses */ |
2245 | amdgpu_atombios_i2c_init(adev); | 2291 | if (!amdgpu_device_has_dc_support(adev)) |
2292 | amdgpu_atombios_i2c_init(adev); | ||
2246 | } | 2293 | } |
2247 | 2294 | ||
2248 | /* Fence driver */ | 2295 | /* Fence driver */ |
@@ -2378,7 +2425,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
2378 | adev->accel_working = false; | 2425 | adev->accel_working = false; |
2379 | cancel_delayed_work_sync(&adev->late_init_work); | 2426 | cancel_delayed_work_sync(&adev->late_init_work); |
2380 | /* free i2c buses */ | 2427 | /* free i2c buses */ |
2381 | amdgpu_i2c_fini(adev); | 2428 | if (!amdgpu_device_has_dc_support(adev)) |
2429 | amdgpu_i2c_fini(adev); | ||
2382 | amdgpu_atombios_fini(adev); | 2430 | amdgpu_atombios_fini(adev); |
2383 | kfree(adev->bios); | 2431 | kfree(adev->bios); |
2384 | adev->bios = NULL; | 2432 | adev->bios = NULL; |
@@ -2429,12 +2477,14 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) | |||
2429 | 2477 | ||
2430 | drm_kms_helper_poll_disable(dev); | 2478 | drm_kms_helper_poll_disable(dev); |
2431 | 2479 | ||
2432 | /* turn off display hw */ | 2480 | if (!amdgpu_device_has_dc_support(adev)) { |
2433 | drm_modeset_lock_all(dev); | 2481 | /* turn off display hw */ |
2434 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 2482 | drm_modeset_lock_all(dev); |
2435 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 2483 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
2484 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | ||
2485 | } | ||
2486 | drm_modeset_unlock_all(dev); | ||
2436 | } | 2487 | } |
2437 | drm_modeset_unlock_all(dev); | ||
2438 | 2488 | ||
2439 | amdgpu_amdkfd_suspend(adev); | 2489 | amdgpu_amdkfd_suspend(adev); |
2440 | 2490 | ||
@@ -2577,13 +2627,25 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2577 | 2627 | ||
2578 | /* blat the mode back in */ | 2628 | /* blat the mode back in */ |
2579 | if (fbcon) { | 2629 | if (fbcon) { |
2580 | drm_helper_resume_force_mode(dev); | 2630 | if (!amdgpu_device_has_dc_support(adev)) { |
2581 | /* turn on display hw */ | 2631 | /* pre DCE11 */ |
2582 | drm_modeset_lock_all(dev); | 2632 | drm_helper_resume_force_mode(dev); |
2583 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 2633 | |
2584 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | 2634 | /* turn on display hw */ |
2635 | drm_modeset_lock_all(dev); | ||
2636 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
2637 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | ||
2638 | } | ||
2639 | drm_modeset_unlock_all(dev); | ||
2640 | } else { | ||
2641 | /* | ||
2642 | * There is no equivalent atomic helper to turn on | ||
2643 | * display, so we defined our own function for this, | ||
2644 | * once suspend resume is supported by the atomic | ||
2645 | * framework this will be reworked | ||
2646 | */ | ||
2647 | amdgpu_dm_display_resume(adev); | ||
2585 | } | 2648 | } |
2586 | drm_modeset_unlock_all(dev); | ||
2587 | } | 2649 | } |
2588 | 2650 | ||
2589 | drm_kms_helper_poll_enable(dev); | 2651 | drm_kms_helper_poll_enable(dev); |
@@ -2600,7 +2662,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2600 | #ifdef CONFIG_PM | 2662 | #ifdef CONFIG_PM |
2601 | dev->dev->power.disable_depth++; | 2663 | dev->dev->power.disable_depth++; |
2602 | #endif | 2664 | #endif |
2603 | drm_helper_hpd_irq_event(dev); | 2665 | if (!amdgpu_device_has_dc_support(adev)) |
2666 | drm_helper_hpd_irq_event(dev); | ||
2667 | else | ||
2668 | drm_kms_helper_hotplug_event(dev); | ||
2604 | #ifdef CONFIG_PM | 2669 | #ifdef CONFIG_PM |
2605 | dev->dev->power.disable_depth--; | 2670 | dev->dev->power.disable_depth--; |
2606 | #endif | 2671 | #endif |
@@ -2900,6 +2965,7 @@ give_up_reset: | |||
2900 | */ | 2965 | */ |
2901 | int amdgpu_gpu_reset(struct amdgpu_device *adev) | 2966 | int amdgpu_gpu_reset(struct amdgpu_device *adev) |
2902 | { | 2967 | { |
2968 | struct drm_atomic_state *state = NULL; | ||
2903 | int i, r; | 2969 | int i, r; |
2904 | int resched; | 2970 | int resched; |
2905 | bool need_full_reset, vram_lost = false; | 2971 | bool need_full_reset, vram_lost = false; |
@@ -2913,6 +2979,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) | |||
2913 | 2979 | ||
2914 | /* block TTM */ | 2980 | /* block TTM */ |
2915 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); | 2981 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); |
2982 | /* store modesetting */ | ||
2983 | if (amdgpu_device_has_dc_support(adev)) | ||
2984 | state = drm_atomic_helper_suspend(adev->ddev); | ||
2916 | 2985 | ||
2917 | /* block scheduler */ | 2986 | /* block scheduler */ |
2918 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 2987 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
@@ -3029,7 +3098,11 @@ out: | |||
3029 | } | 3098 | } |
3030 | } | 3099 | } |
3031 | 3100 | ||
3032 | drm_helper_resume_force_mode(adev->ddev); | 3101 | if (amdgpu_device_has_dc_support(adev)) { |
3102 | r = drm_atomic_helper_resume(adev->ddev, state); | ||
3103 | amdgpu_dm_display_resume(adev); | ||
3104 | } else | ||
3105 | drm_helper_resume_force_mode(adev->ddev); | ||
3033 | 3106 | ||
3034 | ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched); | 3107 | ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched); |
3035 | if (r) { | 3108 | if (r) { |