diff options
| author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-02-17 18:13:31 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2009-02-22 19:06:23 -0500 |
| commit | 5669fcacc58bf3a7386057addffd280d75380858 (patch) | |
| tree | 03441b11a889764aed9a195cbbc9818ab7ed4c24 | |
| parent | efbeed96f7e20783b22d9529ef536b61f7ea8637 (diff) | |
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>
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 2 |
3 files changed, 24 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a31cbdbc3c54..0692622ee2b3 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | * | 27 | * |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | #include <linux/device.h> | ||
| 30 | #include "drmP.h" | 31 | #include "drmP.h" |
| 31 | #include "drm.h" | 32 | #include "drm.h" |
| 32 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
| @@ -66,6 +67,12 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
| 66 | 67 | ||
| 67 | i915_save_state(dev); | 68 | i915_save_state(dev); |
| 68 | 69 | ||
| 70 | /* If KMS is active, we do the leavevt stuff here */ | ||
| 71 | if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) { | ||
| 72 | dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n"); | ||
| 73 | return -EBUSY; | ||
| 74 | } | ||
| 75 | |||
| 69 | intel_opregion_free(dev); | 76 | intel_opregion_free(dev); |
| 70 | 77 | ||
| 71 | if (state.event == PM_EVENT_SUSPEND) { | 78 | if (state.event == PM_EVENT_SUSPEND) { |
| @@ -79,6 +86,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
| 79 | 86 | ||
| 80 | static int i915_resume(struct drm_device *dev) | 87 | static int i915_resume(struct drm_device *dev) |
| 81 | { | 88 | { |
| 89 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 90 | int ret = 0; | ||
| 91 | |||
| 82 | pci_set_power_state(dev->pdev, PCI_D0); | 92 | pci_set_power_state(dev->pdev, PCI_D0); |
| 83 | pci_restore_state(dev->pdev); | 93 | pci_restore_state(dev->pdev); |
| 84 | if (pci_enable_device(dev->pdev)) | 94 | if (pci_enable_device(dev->pdev)) |
| @@ -89,7 +99,18 @@ static int i915_resume(struct drm_device *dev) | |||
| 89 | 99 | ||
| 90 | intel_opregion_init(dev); | 100 | intel_opregion_init(dev); |
| 91 | 101 | ||
| 92 | return 0; | 102 | /* KMS EnterVT equivalent */ |
| 103 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
| 104 | mutex_lock(&dev->struct_mutex); | ||
| 105 | dev_priv->mm.suspended = 0; | ||
| 106 | |||
| 107 | ret = i915_gem_init_ringbuffer(dev); | ||
| 108 | if (ret != 0) | ||
| 109 | ret = -1; | ||
| 110 | mutex_unlock(&dev->struct_mutex); | ||
| 111 | } | ||
| 112 | |||
| 113 | return ret; | ||
| 93 | } | 114 | } |
| 94 | 115 | ||
| 95 | static struct vm_operations_struct i915_gem_vm_ops = { | 116 | static struct vm_operations_struct i915_gem_vm_ops = { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 135a08f615cd..17fa40858d26 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -618,6 +618,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); | |||
| 618 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 618 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
| 619 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 619 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
| 620 | unsigned long end); | 620 | unsigned long end); |
| 621 | int i915_gem_idle(struct drm_device *dev); | ||
| 621 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 622 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
| 622 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 623 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
| 623 | int write); | 624 | int write); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0f50574076b1..58c789da95a3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -2973,7 +2973,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) | |||
| 2973 | return 0; | 2973 | return 0; |
| 2974 | } | 2974 | } |
| 2975 | 2975 | ||
| 2976 | static int | 2976 | int |
| 2977 | i915_gem_idle(struct drm_device *dev) | 2977 | i915_gem_idle(struct drm_device *dev) |
| 2978 | { | 2978 | { |
| 2979 | drm_i915_private_t *dev_priv = dev->dev_private; | 2979 | drm_i915_private_t *dev_priv = dev->dev_private; |
