aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index c13c51af0b68..e2c3c5ec42d1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -14,6 +14,16 @@
14 14
15#include "amd_acpi.h" 15#include "amd_acpi.h"
16 16
17#define AMDGPU_PX_QUIRK_FORCE_ATPX (1 << 0)
18
19struct amdgpu_px_quirk {
20 u32 chip_vendor;
21 u32 chip_device;
22 u32 subsys_vendor;
23 u32 subsys_device;
24 u32 px_quirk_flags;
25};
26
17struct amdgpu_atpx_functions { 27struct amdgpu_atpx_functions {
18 bool px_params; 28 bool px_params;
19 bool power_cntl; 29 bool power_cntl;
@@ -35,6 +45,7 @@ struct amdgpu_atpx {
35static struct amdgpu_atpx_priv { 45static struct amdgpu_atpx_priv {
36 bool atpx_detected; 46 bool atpx_detected;
37 bool bridge_pm_usable; 47 bool bridge_pm_usable;
48 unsigned int quirks;
38 /* handle for device - and atpx */ 49 /* handle for device - and atpx */
39 acpi_handle dhandle; 50 acpi_handle dhandle;
40 acpi_handle other_handle; 51 acpi_handle other_handle;
@@ -205,13 +216,19 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
205 216
206 atpx->is_hybrid = false; 217 atpx->is_hybrid = false;
207 if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { 218 if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
208 printk("ATPX Hybrid Graphics\n"); 219 if (amdgpu_atpx_priv.quirks & AMDGPU_PX_QUIRK_FORCE_ATPX) {
209 /* 220 printk("ATPX Hybrid Graphics, forcing to ATPX\n");
210 * Disable legacy PM methods only when pcie port PM is usable, 221 atpx->functions.power_cntl = true;
211 * otherwise the device might fail to power off or power on. 222 atpx->is_hybrid = false;
212 */ 223 } else {
213 atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable; 224 printk("ATPX Hybrid Graphics\n");
214 atpx->is_hybrid = true; 225 /*
226 * Disable legacy PM methods only when pcie port PM is usable,
227 * otherwise the device might fail to power off or power on.
228 */
229 atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;
230 atpx->is_hybrid = true;
231 }
215 } 232 }
216 233
217 atpx->dgpu_req_power_for_displays = false; 234 atpx->dgpu_req_power_for_displays = false;
@@ -547,6 +564,30 @@ static const struct vga_switcheroo_handler amdgpu_atpx_handler = {
547 .get_client_id = amdgpu_atpx_get_client_id, 564 .get_client_id = amdgpu_atpx_get_client_id,
548}; 565};
549 566
567static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
568 /* HG _PR3 doesn't seem to work on this A+A weston board */
569 { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
570 { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
571 { 0, 0, 0, 0, 0 },
572};
573
574static void amdgpu_atpx_get_quirks(struct pci_dev *pdev)
575{
576 const struct amdgpu_px_quirk *p = amdgpu_px_quirk_list;
577
578 /* Apply PX quirks */
579 while (p && p->chip_device != 0) {
580 if (pdev->vendor == p->chip_vendor &&
581 pdev->device == p->chip_device &&
582 pdev->subsystem_vendor == p->subsys_vendor &&
583 pdev->subsystem_device == p->subsys_device) {
584 amdgpu_atpx_priv.quirks |= p->px_quirk_flags;
585 break;
586 }
587 ++p;
588 }
589}
590
550/** 591/**
551 * amdgpu_atpx_detect - detect whether we have PX 592 * amdgpu_atpx_detect - detect whether we have PX
552 * 593 *
@@ -570,6 +611,7 @@ static bool amdgpu_atpx_detect(void)
570 611
571 parent_pdev = pci_upstream_bridge(pdev); 612 parent_pdev = pci_upstream_bridge(pdev);
572 d3_supported |= parent_pdev && parent_pdev->bridge_d3; 613 d3_supported |= parent_pdev && parent_pdev->bridge_d3;
614 amdgpu_atpx_get_quirks(pdev);
573 } 615 }
574 616
575 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { 617 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
@@ -579,6 +621,7 @@ static bool amdgpu_atpx_detect(void)
579 621
580 parent_pdev = pci_upstream_bridge(pdev); 622 parent_pdev = pci_upstream_bridge(pdev);
581 d3_supported |= parent_pdev && parent_pdev->bridge_d3; 623 d3_supported |= parent_pdev && parent_pdev->bridge_d3;
624 amdgpu_atpx_get_quirks(pdev);
582 } 625 }
583 626
584 if (has_atpx && vga_count == 2) { 627 if (has_atpx && vga_count == 2) {