Commit 90c4cde9 authored by Alex Deucher's avatar Alex Deucher Committed by Christian König

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=72701Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 57700ad1
...@@ -2321,6 +2321,7 @@ struct radeon_device { ...@@ -2321,6 +2321,7 @@ struct radeon_device {
bool have_disp_power_ref; bool have_disp_power_ref;
}; };
bool radeon_is_px(struct drm_device *dev);
int radeon_device_init(struct radeon_device *rdev, int radeon_device_init(struct radeon_device *rdev,
struct drm_device *ddev, struct drm_device *ddev,
struct pci_dev *pdev, struct pci_dev *pdev,
......
...@@ -59,7 +59,7 @@ struct atpx_mux { ...@@ -59,7 +59,7 @@ struct atpx_mux {
u16 mux; u16 mux;
} __packed; } __packed;
bool radeon_is_px(void) { bool radeon_has_atpx(void) {
return radeon_atpx_priv.atpx_detected; return radeon_atpx_priv.atpx_detected;
} }
......
...@@ -102,11 +102,14 @@ static const char radeon_family_name[][16] = { ...@@ -102,11 +102,14 @@ static const char radeon_family_name[][16] = {
"LAST", "LAST",
}; };
#if defined(CONFIG_VGA_SWITCHEROO) bool radeon_is_px(struct drm_device *dev)
bool radeon_is_px(void); {
#else struct radeon_device *rdev = dev->dev_private;
static inline bool radeon_is_px(void) { return false; }
#endif if (rdev->flags & RADEON_IS_PX)
return true;
return false;
}
/** /**
* radeon_program_register_sequence - program an array of registers. * radeon_program_register_sequence - program an array of registers.
...@@ -1082,7 +1085,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero ...@@ -1082,7 +1085,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
{ {
struct drm_device *dev = pci_get_drvdata(pdev); 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; return;
if (state == VGA_SWITCHEROO_ON) { if (state == VGA_SWITCHEROO_ON) {
...@@ -1301,9 +1304,7 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -1301,9 +1304,7 @@ int radeon_device_init(struct radeon_device *rdev,
* ignore it */ * ignore it */
vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
if (radeon_runtime_pm == 1) if (rdev->flags & RADEON_IS_PX)
runtime = true;
if ((radeon_runtime_pm == -1) && radeon_is_px())
runtime = true; runtime = true;
vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
if (runtime) if (runtime)
......
...@@ -115,6 +115,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, ...@@ -115,6 +115,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
unsigned int flags, unsigned int flags,
int *vpos, int *hpos, ktime_t *stime, int *vpos, int *hpos, ktime_t *stime,
ktime_t *etime); ktime_t *etime);
extern bool radeon_is_px(struct drm_device *dev);
extern const struct drm_ioctl_desc radeon_ioctls_kms[]; extern const struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl; extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma); int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
...@@ -144,11 +145,9 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); ...@@ -144,11 +145,9 @@ void radeon_debugfs_cleanup(struct drm_minor *minor);
#if defined(CONFIG_VGA_SWITCHEROO) #if defined(CONFIG_VGA_SWITCHEROO)
void radeon_register_atpx_handler(void); void radeon_register_atpx_handler(void);
void radeon_unregister_atpx_handler(void); void radeon_unregister_atpx_handler(void);
bool radeon_is_px(void);
#else #else
static inline void radeon_register_atpx_handler(void) {} static inline void radeon_register_atpx_handler(void) {}
static inline void radeon_unregister_atpx_handler(void) {} static inline void radeon_unregister_atpx_handler(void) {}
static inline bool radeon_is_px(void) { return false; }
#endif #endif
int radeon_no_wb; int radeon_no_wb;
...@@ -405,12 +404,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev) ...@@ -405,12 +404,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret; int ret;
if (radeon_runtime_pm == 0) { if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
if (radeon_runtime_pm == -1 && !radeon_is_px()) {
pm_runtime_forbid(dev); pm_runtime_forbid(dev);
return -EBUSY; return -EBUSY;
} }
...@@ -434,10 +428,7 @@ static int radeon_pmops_runtime_resume(struct device *dev) ...@@ -434,10 +428,7 @@ static int radeon_pmops_runtime_resume(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret; int ret;
if (radeon_runtime_pm == 0) if (!radeon_is_px(drm_dev))
return -EINVAL;
if (radeon_runtime_pm == -1 && !radeon_is_px())
return -EINVAL; return -EINVAL;
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
...@@ -462,14 +453,7 @@ static int radeon_pmops_runtime_idle(struct device *dev) ...@@ -462,14 +453,7 @@ static int radeon_pmops_runtime_idle(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct drm_crtc *crtc; struct drm_crtc *crtc;
if (radeon_runtime_pm == 0) { if (!radeon_is_px(drm_dev)) {
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");
pm_runtime_forbid(dev); pm_runtime_forbid(dev);
return -EBUSY; return -EBUSY;
} }
......
...@@ -115,6 +115,7 @@ enum radeon_chip_flags { ...@@ -115,6 +115,7 @@ enum radeon_chip_flags {
RADEON_NEW_MEMMAP = 0x00400000UL, RADEON_NEW_MEMMAP = 0x00400000UL,
RADEON_IS_PCI = 0x00800000UL, RADEON_IS_PCI = 0x00800000UL,
RADEON_IS_IGPGART = 0x01000000UL, RADEON_IS_IGPGART = 0x01000000UL,
RADEON_IS_PX = 0x02000000UL,
}; };
#endif #endif
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#if defined(CONFIG_VGA_SWITCHEROO) #if defined(CONFIG_VGA_SWITCHEROO)
bool radeon_is_px(void); bool radeon_has_atpx(void);
#else #else
static inline bool radeon_is_px(void) { return false; } static inline bool radeon_has_atpx(void) { return false; }
#endif #endif
/** /**
...@@ -107,6 +107,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) ...@@ -107,6 +107,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
flags |= RADEON_IS_PCI; 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 /* radeon_device_init should report only fatal error
* like memory allocation failure or iomapping failure, * like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must * or memory manager initialization failure, it must
...@@ -137,8 +144,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) ...@@ -137,8 +144,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
"Error during ACPI methods call\n"); "Error during ACPI methods call\n");
} }
if ((radeon_runtime_pm == 1) || if (radeon_is_px(dev)) {
((radeon_runtime_pm == -1) && radeon_is_px())) {
pm_runtime_use_autosuspend(dev->dev); pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000); pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_set_active(dev->dev); pm_runtime_set_active(dev->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment