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 /drivers/gpu/drm | |
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>
Diffstat (limited to 'drivers/gpu/drm')
-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; |