aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 17:34:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 17:34:42 -0500
commitf6705bf959efac87bca76d40050d342f1d212587 (patch)
treee199b124c6067a92be7f4727538ffc721670fc28 /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
parentbec04432cb9036dedf89140c102b5ac03e4b3626 (diff)
parent49e37ba07a3ae697086c0a1a32c113a1f177d138 (diff)
Merge tag 'drm-for-v4.15-amd-dc' of git://people.freedesktop.org/~airlied/linux
Pull amdgpu DC display code for Vega from Dave Airlie: "This is the pull request for the AMD DC (display code) layer which is a requirement to program the display engines on the new Vega and Raven based GPUs. It also contains support for all amdgpu supported GPUs (CIK, VI, Polaris), which has to be enabled. It is also a kms atomic modesetting compatible driver (unlike the current in-tree display code). I've kept it separate from drm-next because it may have some things that cause you to reject it. Background story: AMD have an internal team creating a shared OS codebase for display at hw bring up time using information from their hardware teams. This process doesn't lead to the most Linux friendly/looking code but we have worked together on cleaning a lot of it up and dealing with sparse/smatch/checkpatch, and having their team internally adhere to Linux coding standards. This tree is a complete history rebased since they started opening it, we decided not to squash it down as the history may have some value. Some of the commits therefore might not reach kernel standards, and we are steadily training people in AMD to better write commit msgs. There is a major bunch of generated bandwidth calculation and verification code that comes from their hardware team. On Vega and before this is float calculations, on Raven (DCN10) this is double based. They do the required things to do FP in the kernel, and I could understand this might raise some issues. Rewriting the bandwidth would be a major undertaken in reverification, it's non-trivial to work out if a display can handle the complete set of mode information thrown at it. Future story: There is a TODO list with this, and it address most of the remaining things that would be nice to refine/remove. The DCN10 code is still under development internally and they push out a lot of patches quite regularly and are supporting this code base with their display team. I think we've reached the point where keeping it out of tree is going to motivate distributions to start carrying the code, so I'd prefer we get it in tree. I think this code is slightly better than STAGING quality but not massively so, I'd really like to see that float/double magic gone and fixed point used, but AMD don't seem to think the accuracy and revalidation of the code is worth the effort" * tag 'drm-for-v4.15-amd-dc' of git://people.freedesktop.org/~airlied/linux: (1110 commits) drm/amd/display: fix MST link training fail division by 0 drm/amd/display: Fix formatting for null pointer dereference fix drm/amd/display: Remove dangling planes on dc commit state drm/amd/display: add flip_immediate to commit update for stream drm/amd/display: Miss register MST encoder cbs drm/amd/display: Fix warnings on S3 resume drm/amd/display: use num_timing_generator instead of pipe_count drm/amd/display: use configurable FBC option in dm drm/amd/display: fix AZ clock not enabled before program AZ endpoint amdgpu/dm: Don't use DRM_ERROR in amdgpu_dm_atomic_check amd/display: Fix potential null dereference in dce_calcs.c amdgpu/dm: Remove unused forward declaration drm/amdgpu: Remove unused dc_stream from amdgpu_crtc amdgpu/dc: Fix double unlock in amdgpu_dm_commit_planes amdgpu/dc: Fix missing null checks in amdgpu_dm.c amdgpu/dc: Fix potential null dereferences in amdgpu_dm.c amdgpu/dc: fix more indentation warnings amdgpu/dc: handle allocation failures in dc_commit_planes_to_stream. amdgpu/dc: fix indentation warning from smatch. amdgpu/dc: fix non-ansi function decls. ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c105
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
2050bool 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 */
2088bool 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 */
2901int amdgpu_gpu_reset(struct amdgpu_device *adev) 2966int 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) {