Skip to content

Commit

Permalink
drm/radeon: fix check for port PM availability
Browse files Browse the repository at this point in the history
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: d3ac31f (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+
  • Loading branch information
Alex Deucher committed Nov 29, 2016
1 parent 7ac33e4 commit bcfdd5d
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions drivers/gpu/drm/radeon/radeon_atpx_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
*/
static bool radeon_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;

Expand All @@ -493,7 +492,6 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)

radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx.handle = atpx_handle;
radeon_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
return true;
}

Expand Down Expand Up @@ -555,25 +553,34 @@ static bool radeon_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 |= (radeon_atpx_pci_probe_handle(pdev) == true);

parent_pdev = pci_upstream_bridge(pdev);
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
}

/* some newer PX laptops mark the dGPU as a non-VGA display device */
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
vga_count++;

has_atpx |= (radeon_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) {
acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
acpi_method_name);
radeon_atpx_priv.atpx_detected = true;
radeon_atpx_priv.bridge_pm_usable = d3_supported;
radeon_atpx_init();
return true;
}
Expand Down

0 comments on commit bcfdd5d

Please sign in to comment.