aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2016-11-28 17:23:40 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-11-29 09:24:13 -0500
commitbcfdd5d5105087e6f33dfeb08a1ca6b2c0287b61 (patch)
treebcfa18ced0e36b5a44356096480a750b693a2409
parent7ac33e47d5769632010e537964c7e45498f8dc26 (diff)
drm/radeon: 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. Ported from amdgpu commit: drm/amdgpu: fix check for port PM availability from Peter Wu. Fixes: d3ac31f3b4bf9fad (drm/radeon: fix power state when port pm is unavailable (v2)) Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: Peter Wu <peter@lekensteyn.nl> Cc: <stable@vger.kernel.org> # 4.8+
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 4129b12521a6..0ae13cd2adda 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -479,7 +479,6 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
479 */ 479 */
480static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) 480static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
481{ 481{
482 struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
483 acpi_handle dhandle, atpx_handle; 482 acpi_handle dhandle, atpx_handle;
484 acpi_status status; 483 acpi_status status;
485 484
@@ -493,7 +492,6 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
493 492
494 radeon_atpx_priv.dhandle = dhandle; 493 radeon_atpx_priv.dhandle = dhandle;
495 radeon_atpx_priv.atpx.handle = atpx_handle; 494 radeon_atpx_priv.atpx.handle = atpx_handle;
496 radeon_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
497 return true; 495 return true;
498} 496}
499 497
@@ -555,11 +553,16 @@ static bool radeon_atpx_detect(void)
555 struct pci_dev *pdev = NULL; 553 struct pci_dev *pdev = NULL;
556 bool has_atpx = false; 554 bool has_atpx = false;
557 int vga_count = 0; 555 int vga_count = 0;
556 bool d3_supported = false;
557 struct pci_dev *parent_pdev;
558 558
559 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 559 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
560 vga_count++; 560 vga_count++;
561 561
562 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); 562 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
563
564 parent_pdev = pci_upstream_bridge(pdev);
565 d3_supported |= parent_pdev && parent_pdev->bridge_d3;
563 } 566 }
564 567
565 /* some newer PX laptops mark the dGPU as a non-VGA display device */ 568 /* some newer PX laptops mark the dGPU as a non-VGA display device */
@@ -567,6 +570,9 @@ static bool radeon_atpx_detect(void)
567 vga_count++; 570 vga_count++;
568 571
569 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); 572 has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
573
574 parent_pdev = pci_upstream_bridge(pdev);
575 d3_supported |= parent_pdev && parent_pdev->bridge_d3;
570 } 576 }
571 577
572 if (has_atpx && vga_count == 2) { 578 if (has_atpx && vga_count == 2) {
@@ -574,6 +580,7 @@ static bool radeon_atpx_detect(void)
574 printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n", 580 printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
575 acpi_method_name); 581 acpi_method_name);
576 radeon_atpx_priv.atpx_detected = true; 582 radeon_atpx_priv.atpx_detected = true;
583 radeon_atpx_priv.bridge_pm_usable = d3_supported;
577 radeon_atpx_init(); 584 radeon_atpx_init();
578 return true; 585 return true;
579 } 586 }