drm/radeon: fix runpm handling on APUs (v4)
Don't try and runtime suspend the APU in PX systems. We
only want to power down the dGPU.
v2: fix harder
v3: fix stupid typo
v4: consolidate runpm enablement to a single flag
bugs:
https://bugs.freedesktop.org/show_bug.cgi?id=75127
https://bugzilla.kernel.org/show_bug.cgi?id=72701
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f21db7a..7014bdd 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2321,6 +2321,7 @@
bool have_disp_power_ref;
};
+bool radeon_is_px(struct drm_device *dev);
int radeon_device_init(struct radeon_device *rdev,
struct drm_device *ddev,
struct pci_dev *pdev,
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index fa9a9c0..dedea72 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -59,7 +59,7 @@
u16 mux;
} __packed;
-bool radeon_is_px(void) {
+bool radeon_has_atpx(void) {
return radeon_atpx_priv.atpx_detected;
}
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 835516d..511fe26 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -102,11 +102,14 @@
"LAST",
};
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
-#else
-static inline bool radeon_is_px(void) { return false; }
-#endif
+bool radeon_is_px(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (rdev->flags & RADEON_IS_PX)
+ return true;
+ return false;
+}
/**
* radeon_program_register_sequence - program an array of registers.
@@ -1082,7 +1085,7 @@
{
struct drm_device *dev = pci_get_drvdata(pdev);
- if (radeon_is_px() && state == VGA_SWITCHEROO_OFF)
+ if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF)
return;
if (state == VGA_SWITCHEROO_ON) {
@@ -1301,9 +1304,7 @@
* ignore it */
vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
- if (radeon_runtime_pm == 1)
- runtime = true;
- if ((radeon_runtime_pm == -1) && radeon_is_px())
+ if (rdev->flags & RADEON_IS_PX)
runtime = true;
vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
if (runtime)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index d0eba48..25127ba 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -115,6 +115,7 @@
unsigned int flags,
int *vpos, int *hpos, ktime_t *stime,
ktime_t *etime);
+extern bool radeon_is_px(struct drm_device *dev);
extern const struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -144,11 +145,9 @@
#if defined(CONFIG_VGA_SWITCHEROO)
void radeon_register_atpx_handler(void);
void radeon_unregister_atpx_handler(void);
-bool radeon_is_px(void);
#else
static inline void radeon_register_atpx_handler(void) {}
static inline void radeon_unregister_atpx_handler(void) {}
-static inline bool radeon_is_px(void) { return false; }
#endif
int radeon_no_wb;
@@ -405,12 +404,7 @@
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (radeon_runtime_pm == 0) {
- pm_runtime_forbid(dev);
- return -EBUSY;
- }
-
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
+ if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
@@ -434,10 +428,7 @@
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (radeon_runtime_pm == 0)
- return -EINVAL;
-
- if (radeon_runtime_pm == -1 && !radeon_is_px())
+ if (!radeon_is_px(drm_dev))
return -EINVAL;
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
@@ -462,14 +453,7 @@
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct drm_crtc *crtc;
- if (radeon_runtime_pm == 0) {
- pm_runtime_forbid(dev);
- return -EBUSY;
- }
-
- /* are we PX enabled? */
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
- DRM_DEBUG_DRIVER("failing to power off - not px\n");
+ if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h
index 614ad54..9da5da4 100644
--- a/drivers/gpu/drm/radeon/radeon_family.h
+++ b/drivers/gpu/drm/radeon/radeon_family.h
@@ -115,6 +115,7 @@
RADEON_NEW_MEMMAP = 0x00400000UL,
RADEON_IS_PCI = 0x00800000UL,
RADEON_IS_IGPGART = 0x01000000UL,
+ RADEON_IS_PX = 0x02000000UL,
};
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 3e49342..9337820 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -35,9 +35,9 @@
#include <linux/pm_runtime.h>
#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
+bool radeon_has_atpx(void);
#else
-static inline bool radeon_is_px(void) { return false; }
+static inline bool radeon_has_atpx(void) { return false; }
#endif
/**
@@ -107,6 +107,13 @@
flags |= RADEON_IS_PCI;
}
+ if (radeon_runtime_pm == 1)
+ flags |= RADEON_IS_PX;
+ else if ((radeon_runtime_pm == -1) &&
+ radeon_has_atpx() &&
+ ((flags & RADEON_IS_IGP) == 0))
+ flags |= RADEON_IS_PX;
+
/* radeon_device_init should report only fatal error
* like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must
@@ -137,8 +144,7 @@
"Error during ACPI methods call\n");
}
- if ((radeon_runtime_pm == 1) ||
- ((radeon_runtime_pm == -1) && radeon_is_px())) {
+ if (radeon_is_px(dev)) {
pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_set_active(dev->dev);