drm/amdgpu: disable runpm if we are the primary adapter
If we are the primary adapter (i.e., the one used by the firwmare framebuffer), disable runtime pm. This fixes a regression caused by commit55285e21f0
which results in the displays waking up shortly after they go to sleep due to the device coming out of runtime suspend and sending a hotplug uevent. v2: squash in reworked fix from Evan Fixes:55285e21f0
("fbdev/efifb: Release PCI device's runtime PM ref during FB destroy") Bug: https://bugzilla.kernel.org/show_bug.cgi?id=215203 Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1840 Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9a45ac2320
commit
b95dc06af3
|
@ -1077,6 +1077,7 @@ struct amdgpu_device {
|
||||||
bool runpm;
|
bool runpm;
|
||||||
bool in_runpm;
|
bool in_runpm;
|
||||||
bool has_pr3;
|
bool has_pr3;
|
||||||
|
bool is_fw_fb;
|
||||||
|
|
||||||
bool pm_sysfs_en;
|
bool pm_sysfs_en;
|
||||||
bool ucode_sysfs_en;
|
bool ucode_sysfs_en;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <linux/mmu_notifier.h>
|
#include <linux/mmu_notifier.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/cc_platform.h>
|
#include <linux/cc_platform.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_irq.h"
|
#include "amdgpu_irq.h"
|
||||||
|
@ -1890,6 +1891,26 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
|
||||||
|
|
||||||
static const struct drm_driver amdgpu_kms_driver;
|
static const struct drm_driver amdgpu_kms_driver;
|
||||||
|
|
||||||
|
static bool amdgpu_is_fw_framebuffer(resource_size_t base,
|
||||||
|
resource_size_t size)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
#if IS_REACHABLE(CONFIG_FB)
|
||||||
|
struct apertures_struct *a;
|
||||||
|
|
||||||
|
a = alloc_apertures(1);
|
||||||
|
if (!a)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
a->ranges[0].base = base;
|
||||||
|
a->ranges[0].size = size;
|
||||||
|
|
||||||
|
found = is_firmware_framebuffer(a);
|
||||||
|
kfree(a);
|
||||||
|
#endif
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
static int amdgpu_pci_probe(struct pci_dev *pdev,
|
static int amdgpu_pci_probe(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
|
@ -1898,6 +1919,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
||||||
unsigned long flags = ent->driver_data;
|
unsigned long flags = ent->driver_data;
|
||||||
int ret, retry = 0, i;
|
int ret, retry = 0, i;
|
||||||
bool supports_atomic = false;
|
bool supports_atomic = false;
|
||||||
|
bool is_fw_fb;
|
||||||
|
resource_size_t base, size;
|
||||||
|
|
||||||
/* skip devices which are owned by radeon */
|
/* skip devices which are owned by radeon */
|
||||||
for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) {
|
for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) {
|
||||||
|
@ -1966,6 +1989,10 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
base = pci_resource_start(pdev, 0);
|
||||||
|
size = pci_resource_len(pdev, 0);
|
||||||
|
is_fw_fb = amdgpu_is_fw_framebuffer(base, size);
|
||||||
|
|
||||||
/* Get rid of things like offb */
|
/* Get rid of things like offb */
|
||||||
ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
|
ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1978,6 +2005,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
||||||
adev->dev = &pdev->dev;
|
adev->dev = &pdev->dev;
|
||||||
adev->pdev = pdev;
|
adev->pdev = pdev;
|
||||||
ddev = adev_to_drm(adev);
|
ddev = adev_to_drm(adev);
|
||||||
|
adev->is_fw_fb = is_fw_fb;
|
||||||
|
|
||||||
if (!supports_atomic)
|
if (!supports_atomic)
|
||||||
ddev->driver_features &= ~DRIVER_ATOMIC;
|
ddev->driver_features &= ~DRIVER_ATOMIC;
|
||||||
|
|
|
@ -206,6 +206,12 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
|
||||||
adev->runpm = true;
|
adev->runpm = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* XXX: disable runtime pm if we are the primary adapter
|
||||||
|
* to avoid displays being re-enabled after DPMS.
|
||||||
|
* This needs to be sorted out and fixed properly.
|
||||||
|
*/
|
||||||
|
if (adev->is_fw_fb)
|
||||||
|
adev->runpm = false;
|
||||||
if (adev->runpm)
|
if (adev->runpm)
|
||||||
dev_info(adev->dev, "Using BACO for runtime pm\n");
|
dev_info(adev->dev, "Using BACO for runtime pm\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue