Commit 5669fcac authored by Jesse Barnes's avatar Jesse Barnes Committed by Dave Airlie

drm/i915: suspend/resume GEM when KMS is active

In the KMS case, we need to suspend/resume GEM as well.  So on suspend, make
sure we idle GEM and stop any new rendering from coming in, and on resume,
re-init the framebuffer and clear the suspended flag.
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent efbeed96
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* *
*/ */
#include <linux/device.h>
#include "drmP.h" #include "drmP.h"
#include "drm.h" #include "drm.h"
#include "i915_drm.h" #include "i915_drm.h"
...@@ -66,6 +67,12 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) ...@@ -66,6 +67,12 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
i915_save_state(dev); i915_save_state(dev);
/* If KMS is active, we do the leavevt stuff here */
if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) {
dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n");
return -EBUSY;
}
intel_opregion_free(dev); intel_opregion_free(dev);
if (state.event == PM_EVENT_SUSPEND) { if (state.event == PM_EVENT_SUSPEND) {
...@@ -79,6 +86,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) ...@@ -79,6 +86,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
static int i915_resume(struct drm_device *dev) static int i915_resume(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
pci_set_power_state(dev->pdev, PCI_D0); pci_set_power_state(dev->pdev, PCI_D0);
pci_restore_state(dev->pdev); pci_restore_state(dev->pdev);
if (pci_enable_device(dev->pdev)) if (pci_enable_device(dev->pdev))
...@@ -89,7 +99,18 @@ static int i915_resume(struct drm_device *dev) ...@@ -89,7 +99,18 @@ static int i915_resume(struct drm_device *dev)
intel_opregion_init(dev); intel_opregion_init(dev);
return 0; /* KMS EnterVT equivalent */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
mutex_lock(&dev->struct_mutex);
dev_priv->mm.suspended = 0;
ret = i915_gem_init_ringbuffer(dev);
if (ret != 0)
ret = -1;
mutex_unlock(&dev->struct_mutex);
}
return ret;
} }
static struct vm_operations_struct i915_gem_vm_ops = { static struct vm_operations_struct i915_gem_vm_ops = {
......
...@@ -618,6 +618,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); ...@@ -618,6 +618,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start, int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end); unsigned long end);
int i915_gem_idle(struct drm_device *dev);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write); int write);
......
...@@ -2973,7 +2973,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) ...@@ -2973,7 +2973,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
return 0; return 0;
} }
static int int
i915_gem_idle(struct drm_device *dev) i915_gem_idle(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
......
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