From 1aa695a68e16cdcdcf2ed0b72cc2b9ffdd76e3ab Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 6 Apr 2014 22:09:28 -0400 Subject: [PATCH] drm/radeon: fix runpm handling on APUs (v2) Don't try and runtime suspend the APU in PX systems. We only want to power down the dGPU. v2: fix harder bugs: https://bugs.freedesktop.org/show_bug.cgi?id=75127 https://bugzilla.kernel.org/show_bug.cgi?id=72701 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_device.c | 12 +++++++++++- drivers/gpu/drm/radeon/radeon_drv.c | 17 +++++++++++++++++ drivers/gpu/drm/radeon/radeon_kms.c | 3 ++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 2e72dcd..f580206 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -108,6 +108,15 @@ bool radeon_is_px(void); static inline bool radeon_is_px(void) { return false; } #endif +bool radeon_is_igp(struct drm_device *dev) +{ + struct radeon_device *rdev = dev->dev_private; + + if (rdev->flags & RADEON_IS_IGP) + return true; + return false; +} + /** * radeon_program_register_sequence - program an array of registers. * @@ -1303,7 +1312,8 @@ int radeon_device_init(struct radeon_device *rdev, if (radeon_runtime_pm == 1) runtime = true; - if ((radeon_runtime_pm == -1) && radeon_is_px()) + if ((radeon_runtime_pm == -1) && radeon_is_px() && + ((rdev->flags & RADEON_IS_IGP) == 0)) 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 2dc2cc4..12f5751 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,6 +114,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime); +extern bool radeon_is_igp(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); @@ -414,6 +415,12 @@ static int radeon_pmops_runtime_suspend(struct device *dev) return -EBUSY; } + if (radeon_runtime_pm == -1 && radeon_is_px() && + radeon_is_igp(dev)) { + pm_runtime_forbid(dev); + return -EBUSY; + } + drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); @@ -439,6 +446,10 @@ static int radeon_pmops_runtime_resume(struct device *dev) if (radeon_runtime_pm == -1 && !radeon_is_px()) return -EINVAL; + if (radeon_runtime_pm == -1 && radeon_is_px() && + radeon_is_igp(dev)) + return -EINVAL; + drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; pci_set_power_state(pdev, PCI_D0); @@ -473,6 +484,12 @@ static int radeon_pmops_runtime_idle(struct device *dev) return -EBUSY; } + if (radeon_runtime_pm == -1 && radeon_is_px() && + radeon_is_igp(dev)) { + pm_runtime_forbid(dev); + return -EBUSY; + } + list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) { if (crtc->enabled) { DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 3e49342..43de4bc 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -138,7 +138,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) } if ((radeon_runtime_pm == 1) || - ((radeon_runtime_pm == -1) && radeon_is_px())) { + ((radeon_runtime_pm == -1) && radeon_is_px() && + ((rdev->flags & RADEON_IS_IGP) == 0))) { pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); pm_runtime_set_active(dev->dev); -- 1.8.3.1