summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2016-11-26 15:05:01 +0100
committerAlex Deucher <alexander.deucher@amd.com>2016-11-29 15:23:39 +0100
commit7ac33e47d5769632010e537964c7e45498f8dc26 (patch)
tree9257fdb265c32ad3a3c54541586efaae0407b1f1
parentdrm/amd/powerplay: initialize the soft_regs offset in struct smu7_hwmgr (diff)
downloadlinux-7ac33e47d5769632010e537964c7e45498f8dc26.tar.xz
linux-7ac33e47d5769632010e537964c7e45498f8dc26.zip
drm/amdgpu: fix check for port PM availability
The ATPX method does not always exist on the dGPU, it may be located at the iGPU. The parent device of the iGPU is the root port for which bridge_d3 is false. This accidentally enables the legacy PM method which conflicts with port PM and prevented the dGPU from powering on. Fixes: 1db4496f167b ("drm/amdgpu: fix power state when port pm is unavailable") Reported-and-tested-by: Mike Lothian <mike@fireburn.co.uk> Signed-off-by: Peter Wu <peter@lekensteyn.nl> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: <stable@vger.kernel.org> # 4.8+
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index 02ca5dd978f6..6c343a933182 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -485,7 +485,6 @@ static int amdgpu_atpx_power_state(enum vga_switcheroo_client_id id,
*/
static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
acpi_handle dhandle, atpx_handle;
acpi_status status;
@@ -500,7 +499,6 @@ static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
}
amdgpu_atpx_priv.dhandle = dhandle;
amdgpu_atpx_priv.atpx.handle = atpx_handle;
- amdgpu_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
return true;
}
@@ -562,17 +560,25 @@ static bool amdgpu_atpx_detect(void)
struct pci_dev *pdev = NULL;
bool has_atpx = false;
int vga_count = 0;
+ bool d3_supported = false;
+ struct pci_dev *parent_pdev;
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
vga_count++;
has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
+
+ parent_pdev = pci_upstream_bridge(pdev);
+ d3_supported |= parent_pdev && parent_pdev->bridge_d3;
}
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
vga_count++;
has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
+
+ parent_pdev = pci_upstream_bridge(pdev);
+ d3_supported |= parent_pdev && parent_pdev->bridge_d3;
}
if (has_atpx && vga_count == 2) {
@@ -580,6 +586,7 @@ static bool amdgpu_atpx_detect(void)
printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
acpi_method_name);
amdgpu_atpx_priv.atpx_detected = true;
+ amdgpu_atpx_priv.bridge_pm_usable = d3_supported;
amdgpu_atpx_init();
return true;
}