mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 11:19:37 +00:00
drm/amdgpu: add atpx quirk handling (v2)
Add quirks for handling PX/HG systems. In this case, add a quirk for a weston dGPU that only seems to properly power down using ATPX power control rather than HG (_PR3). v2: append a new weston XT Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com> (v2) Reviewed-and-Tested-by: Junwei Zhang <Jerry.Zhang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
f2e5262f75
commit
052c299080
1 changed files with 50 additions and 7 deletions
|
@ -14,6 +14,16 @@
|
|||
|
||||
#include "amd_acpi.h"
|
||||
|
||||
#define AMDGPU_PX_QUIRK_FORCE_ATPX (1 << 0)
|
||||
|
||||
struct amdgpu_px_quirk {
|
||||
u32 chip_vendor;
|
||||
u32 chip_device;
|
||||
u32 subsys_vendor;
|
||||
u32 subsys_device;
|
||||
u32 px_quirk_flags;
|
||||
};
|
||||
|
||||
struct amdgpu_atpx_functions {
|
||||
bool px_params;
|
||||
bool power_cntl;
|
||||
|
@ -35,6 +45,7 @@ struct amdgpu_atpx {
|
|||
static struct amdgpu_atpx_priv {
|
||||
bool atpx_detected;
|
||||
bool bridge_pm_usable;
|
||||
unsigned int quirks;
|
||||
/* handle for device - and atpx */
|
||||
acpi_handle dhandle;
|
||||
acpi_handle other_handle;
|
||||
|
@ -205,6 +216,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
|
|||
|
||||
atpx->is_hybrid = false;
|
||||
if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
|
||||
if (amdgpu_atpx_priv.quirks & AMDGPU_PX_QUIRK_FORCE_ATPX) {
|
||||
printk("ATPX Hybrid Graphics, forcing to ATPX\n");
|
||||
atpx->functions.power_cntl = true;
|
||||
atpx->is_hybrid = false;
|
||||
} else {
|
||||
printk("ATPX Hybrid Graphics\n");
|
||||
/*
|
||||
* Disable legacy PM methods only when pcie port PM is usable,
|
||||
|
@ -213,6 +229,7 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
|
|||
atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;
|
||||
atpx->is_hybrid = true;
|
||||
}
|
||||
}
|
||||
|
||||
atpx->dgpu_req_power_for_displays = false;
|
||||
if (valid_bits & ATPX_DGPU_REQ_POWER_FOR_DISPLAYS)
|
||||
|
@ -547,6 +564,30 @@ static const struct vga_switcheroo_handler amdgpu_atpx_handler = {
|
|||
.get_client_id = amdgpu_atpx_get_client_id,
|
||||
};
|
||||
|
||||
static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
|
||||
/* HG _PR3 doesn't seem to work on this A+A weston board */
|
||||
{ 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static void amdgpu_atpx_get_quirks(struct pci_dev *pdev)
|
||||
{
|
||||
const struct amdgpu_px_quirk *p = amdgpu_px_quirk_list;
|
||||
|
||||
/* Apply PX quirks */
|
||||
while (p && p->chip_device != 0) {
|
||||
if (pdev->vendor == p->chip_vendor &&
|
||||
pdev->device == p->chip_device &&
|
||||
pdev->subsystem_vendor == p->subsys_vendor &&
|
||||
pdev->subsystem_device == p->subsys_device) {
|
||||
amdgpu_atpx_priv.quirks |= p->px_quirk_flags;
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_atpx_detect - detect whether we have PX
|
||||
*
|
||||
|
@ -570,6 +611,7 @@ static bool amdgpu_atpx_detect(void)
|
|||
|
||||
parent_pdev = pci_upstream_bridge(pdev);
|
||||
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
|
||||
amdgpu_atpx_get_quirks(pdev);
|
||||
}
|
||||
|
||||
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
|
||||
|
@ -579,6 +621,7 @@ static bool amdgpu_atpx_detect(void)
|
|||
|
||||
parent_pdev = pci_upstream_bridge(pdev);
|
||||
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
|
||||
amdgpu_atpx_get_quirks(pdev);
|
||||
}
|
||||
|
||||
if (has_atpx && vga_count == 2) {
|
||||
|
|
Loading…
Reference in a new issue