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: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
efbeed96f7
commit
5669fcacc5
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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);
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user