diff options
author | Dave Airlie <airlied@redhat.com> | 2016-11-23 20:16:44 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-11-23 20:16:44 -0500 |
commit | 7ad54c99be62ff2f96deb002cff8221dd6f57087 (patch) | |
tree | df3306d1b8d2fd5d1348b8456b4abc135247bf74 | |
parent | 9c763584b7c8911106bb77af7e648bef09af9d80 (diff) | |
parent | d3ac31f3b4bf9fade93d69770cb9c34912e017be (diff) |
Merge branch 'drm-fixes-4.9' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
one small powerplay fix and one regression fix for older PX systems and d3cold
* 'drm-fixes-4.9' of git://people.freedesktop.org/~agd5f/linux:
drm/radeon: fix power state when port pm is unavailable (v2)
drm/amdgpu: fix power state when port pm is unavailable
drm/amd/powerplay: avoid out of bounds access on array ps.
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atpx_handler.c | 9 |
3 files changed, 22 insertions, 8 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index dae35a96a694..02ca5dd978f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | |||
@@ -34,6 +34,7 @@ struct amdgpu_atpx { | |||
34 | 34 | ||
35 | static struct amdgpu_atpx_priv { | 35 | static struct amdgpu_atpx_priv { |
36 | bool atpx_detected; | 36 | bool atpx_detected; |
37 | bool bridge_pm_usable; | ||
37 | /* handle for device - and atpx */ | 38 | /* handle for device - and atpx */ |
38 | acpi_handle dhandle; | 39 | acpi_handle dhandle; |
39 | acpi_handle other_handle; | 40 | acpi_handle other_handle; |
@@ -205,7 +206,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) | |||
205 | atpx->is_hybrid = false; | 206 | atpx->is_hybrid = false; |
206 | if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { | 207 | if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { |
207 | printk("ATPX Hybrid Graphics\n"); | 208 | printk("ATPX Hybrid Graphics\n"); |
208 | atpx->functions.power_cntl = false; | 209 | /* |
210 | * Disable legacy PM methods only when pcie port PM is usable, | ||
211 | * otherwise the device might fail to power off or power on. | ||
212 | */ | ||
213 | atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable; | ||
209 | atpx->is_hybrid = true; | 214 | atpx->is_hybrid = true; |
210 | } | 215 | } |
211 | 216 | ||
@@ -480,6 +485,7 @@ static int amdgpu_atpx_power_state(enum vga_switcheroo_client_id id, | |||
480 | */ | 485 | */ |
481 | static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev) | 486 | static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev) |
482 | { | 487 | { |
488 | struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); | ||
483 | acpi_handle dhandle, atpx_handle; | 489 | acpi_handle dhandle, atpx_handle; |
484 | acpi_status status; | 490 | acpi_status status; |
485 | 491 | ||
@@ -494,6 +500,7 @@ static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
494 | } | 500 | } |
495 | amdgpu_atpx_priv.dhandle = dhandle; | 501 | amdgpu_atpx_priv.dhandle = dhandle; |
496 | amdgpu_atpx_priv.atpx.handle = atpx_handle; | 502 | amdgpu_atpx_priv.atpx.handle = atpx_handle; |
503 | amdgpu_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3; | ||
497 | return true; | 504 | return true; |
498 | } | 505 | } |
499 | 506 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 13f2b705ea49..08cd0bd3ebe5 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |||
@@ -2984,19 +2984,19 @@ static int smu7_get_pp_table_entry_callback_func_v0(struct pp_hwmgr *hwmgr, | |||
2984 | if (!(data->mc_micro_code_feature & DISABLE_MC_LOADMICROCODE) && memory_clock > data->highest_mclk) | 2984 | if (!(data->mc_micro_code_feature & DISABLE_MC_LOADMICROCODE) && memory_clock > data->highest_mclk) |
2985 | data->highest_mclk = memory_clock; | 2985 | data->highest_mclk = memory_clock; |
2986 | 2986 | ||
2987 | performance_level = &(ps->performance_levels | ||
2988 | [ps->performance_level_count++]); | ||
2989 | |||
2990 | PP_ASSERT_WITH_CODE( | 2987 | PP_ASSERT_WITH_CODE( |
2991 | (ps->performance_level_count < smum_get_mac_definition(hwmgr->smumgr, SMU_MAX_LEVELS_GRAPHICS)), | 2988 | (ps->performance_level_count < smum_get_mac_definition(hwmgr->smumgr, SMU_MAX_LEVELS_GRAPHICS)), |
2992 | "Performance levels exceeds SMC limit!", | 2989 | "Performance levels exceeds SMC limit!", |
2993 | return -EINVAL); | 2990 | return -EINVAL); |
2994 | 2991 | ||
2995 | PP_ASSERT_WITH_CODE( | 2992 | PP_ASSERT_WITH_CODE( |
2996 | (ps->performance_level_count <= | 2993 | (ps->performance_level_count < |
2997 | hwmgr->platform_descriptor.hardwareActivityPerformanceLevels), | 2994 | hwmgr->platform_descriptor.hardwareActivityPerformanceLevels), |
2998 | "Performance levels exceeds Driver limit!", | 2995 | "Performance levels exceeds Driver limit, Skip!", |
2999 | return -EINVAL); | 2996 | return 0); |
2997 | |||
2998 | performance_level = &(ps->performance_levels | ||
2999 | [ps->performance_level_count++]); | ||
3000 | 3000 | ||
3001 | /* Performance levels are arranged from low to high. */ | 3001 | /* Performance levels are arranged from low to high. */ |
3002 | performance_level->memory_clock = memory_clock; | 3002 | performance_level->memory_clock = memory_clock; |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 2fdcd04bc93f..4129b12521a6 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -34,6 +34,7 @@ struct radeon_atpx { | |||
34 | 34 | ||
35 | static struct radeon_atpx_priv { | 35 | static struct radeon_atpx_priv { |
36 | bool atpx_detected; | 36 | bool atpx_detected; |
37 | bool bridge_pm_usable; | ||
37 | /* handle for device - and atpx */ | 38 | /* handle for device - and atpx */ |
38 | acpi_handle dhandle; | 39 | acpi_handle dhandle; |
39 | struct radeon_atpx atpx; | 40 | struct radeon_atpx atpx; |
@@ -203,7 +204,11 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx) | |||
203 | atpx->is_hybrid = false; | 204 | atpx->is_hybrid = false; |
204 | if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { | 205 | if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { |
205 | printk("ATPX Hybrid Graphics\n"); | 206 | printk("ATPX Hybrid Graphics\n"); |
206 | atpx->functions.power_cntl = false; | 207 | /* |
208 | * Disable legacy PM methods only when pcie port PM is usable, | ||
209 | * otherwise the device might fail to power off or power on. | ||
210 | */ | ||
211 | atpx->functions.power_cntl = !radeon_atpx_priv.bridge_pm_usable; | ||
207 | atpx->is_hybrid = true; | 212 | atpx->is_hybrid = true; |
208 | } | 213 | } |
209 | 214 | ||
@@ -474,6 +479,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
474 | */ | 479 | */ |
475 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 480 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
476 | { | 481 | { |
482 | struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); | ||
477 | acpi_handle dhandle, atpx_handle; | 483 | acpi_handle dhandle, atpx_handle; |
478 | acpi_status status; | 484 | acpi_status status; |
479 | 485 | ||
@@ -487,6 +493,7 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
487 | 493 | ||
488 | radeon_atpx_priv.dhandle = dhandle; | 494 | radeon_atpx_priv.dhandle = dhandle; |
489 | radeon_atpx_priv.atpx.handle = atpx_handle; | 495 | radeon_atpx_priv.atpx.handle = atpx_handle; |
496 | radeon_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3; | ||
490 | return true; | 497 | return true; |
491 | } | 498 | } |
492 | 499 | ||