aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-02-22 19:26:09 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-02-22 19:26:09 -0500
commit8310509252c51e2a0e9effb50fefe7e098a67868 (patch)
treef46a109ecc3b266ff4e7d61ddbf1896fa4202597
parent09c50b4a52c01a1f450b8eec819089e228655bfb (diff)
parent5004417d840e6dcb0052061fd04569b9c9f037a8 (diff)
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: drm/i915: Add missing mutex_lock(&dev->struct_mutex) drm/i915: fix WC mapping in non-GEM i915 code. drm/i915: Fix regression in 95ca9d drm/i915: Retire requests from i915_gem_busy_ioctl. drm/i915: suspend/resume GEM when KMS is active drm/i915: Don't let a device flush to prepare buffers clear new write_domains. drm/i915: Cut two args to set_to_gpu_domain that confused this tricky path.
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c23
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c67
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1
5 files changed, 67 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 81f1cff56fd5..2d797ffe8137 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -202,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
202 dev_priv->ring.map.flags = 0; 202 dev_priv->ring.map.flags = 0;
203 dev_priv->ring.map.mtrr = 0; 203 dev_priv->ring.map.mtrr = 0;
204 204
205 drm_core_ioremap(&dev_priv->ring.map, dev); 205 drm_core_ioremap_wc(&dev_priv->ring.map, dev);
206 206
207 if (dev_priv->ring.map.handle == NULL) { 207 if (dev_priv->ring.map.handle == NULL) {
208 i915_dma_cleanup(dev); 208 i915_dma_cleanup(dev);
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
80static int i915_resume(struct drm_device *dev) 87static 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
95static struct vm_operations_struct i915_gem_vm_ops = { 116static 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);
618void i915_gem_cleanup_ringbuffer(struct drm_device *dev); 618void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
619int i915_gem_do_init(struct drm_device *dev, unsigned long start, 619int i915_gem_do_init(struct drm_device *dev, unsigned long start,
620 unsigned long end); 620 unsigned long end);
621int i915_gem_idle(struct drm_device *dev);
621int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 622int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
622int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, 623int 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 ac534c9a2f81..25b337438ca7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,10 +34,6 @@
34 34
35#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) 35#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
36 36
37static void
38i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
39 uint32_t read_domains,
40 uint32_t write_domain);
41static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); 37static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
42static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); 38static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
43static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); 39static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -2021,30 +2017,28 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
2021 * drm_agp_chipset_flush 2017 * drm_agp_chipset_flush
2022 */ 2018 */
2023static void 2019static void
2024i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, 2020i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
2025 uint32_t read_domains,
2026 uint32_t write_domain)
2027{ 2021{
2028 struct drm_device *dev = obj->dev; 2022 struct drm_device *dev = obj->dev;
2029 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2023 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2030 uint32_t invalidate_domains = 0; 2024 uint32_t invalidate_domains = 0;
2031 uint32_t flush_domains = 0; 2025 uint32_t flush_domains = 0;
2032 2026
2033 BUG_ON(read_domains & I915_GEM_DOMAIN_CPU); 2027 BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
2034 BUG_ON(write_domain == I915_GEM_DOMAIN_CPU); 2028 BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
2035 2029
2036#if WATCH_BUF 2030#if WATCH_BUF
2037 DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", 2031 DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2038 __func__, obj, 2032 __func__, obj,
2039 obj->read_domains, read_domains, 2033 obj->read_domains, obj->pending_read_domains,
2040 obj->write_domain, write_domain); 2034 obj->write_domain, obj->pending_write_domain);
2041#endif 2035#endif
2042 /* 2036 /*
2043 * If the object isn't moving to a new write domain, 2037 * If the object isn't moving to a new write domain,
2044 * let the object stay in multiple read domains 2038 * let the object stay in multiple read domains
2045 */ 2039 */
2046 if (write_domain == 0) 2040 if (obj->pending_write_domain == 0)
2047 read_domains |= obj->read_domains; 2041 obj->pending_read_domains |= obj->read_domains;
2048 else 2042 else
2049 obj_priv->dirty = 1; 2043 obj_priv->dirty = 1;
2050 2044
@@ -2054,15 +2048,17 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
2054 * any read domains which differ from the old 2048 * any read domains which differ from the old
2055 * write domain 2049 * write domain
2056 */ 2050 */
2057 if (obj->write_domain && obj->write_domain != read_domains) { 2051 if (obj->write_domain &&
2052 obj->write_domain != obj->pending_read_domains) {
2058 flush_domains |= obj->write_domain; 2053 flush_domains |= obj->write_domain;
2059 invalidate_domains |= read_domains & ~obj->write_domain; 2054 invalidate_domains |=
2055 obj->pending_read_domains & ~obj->write_domain;
2060 } 2056 }
2061 /* 2057 /*
2062 * Invalidate any read caches which may have 2058 * Invalidate any read caches which may have
2063 * stale data. That is, any new read domains. 2059 * stale data. That is, any new read domains.
2064 */ 2060 */
2065 invalidate_domains |= read_domains & ~obj->read_domains; 2061 invalidate_domains |= obj->pending_read_domains & ~obj->read_domains;
2066 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { 2062 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2067#if WATCH_BUF 2063#if WATCH_BUF
2068 DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", 2064 DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
@@ -2071,9 +2067,15 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
2071 i915_gem_clflush_object(obj); 2067 i915_gem_clflush_object(obj);
2072 } 2068 }
2073 2069
2074 if ((write_domain | flush_domains) != 0) 2070 /* The actual obj->write_domain will be updated with
2075 obj->write_domain = write_domain; 2071 * pending_write_domain after we emit the accumulated flush for all
2076 obj->read_domains = read_domains; 2072 * of our domain changes in execbuffers (which clears objects'
2073 * write_domains). So if we have a current write domain that we
2074 * aren't changing, set pending_write_domain to that.
2075 */
2076 if (flush_domains == 0 && obj->pending_write_domain == 0)
2077 obj->pending_write_domain = obj->write_domain;
2078 obj->read_domains = obj->pending_read_domains;
2077 2079
2078 dev->invalidate_domains |= invalidate_domains; 2080 dev->invalidate_domains |= invalidate_domains;
2079 dev->flush_domains |= flush_domains; 2081 dev->flush_domains |= flush_domains;
@@ -2583,9 +2585,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2583 struct drm_gem_object *obj = object_list[i]; 2585 struct drm_gem_object *obj = object_list[i];
2584 2586
2585 /* Compute new gpu domains and update invalidate/flush */ 2587 /* Compute new gpu domains and update invalidate/flush */
2586 i915_gem_object_set_to_gpu_domain(obj, 2588 i915_gem_object_set_to_gpu_domain(obj);
2587 obj->pending_read_domains,
2588 obj->pending_write_domain);
2589 } 2589 }
2590 2590
2591 i915_verify_inactive(dev, __FILE__, __LINE__); 2591 i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2604,6 +2604,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2604 (void)i915_add_request(dev, dev->flush_domains); 2604 (void)i915_add_request(dev, dev->flush_domains);
2605 } 2605 }
2606 2606
2607 for (i = 0; i < args->buffer_count; i++) {
2608 struct drm_gem_object *obj = object_list[i];
2609
2610 obj->write_domain = obj->pending_write_domain;
2611 }
2612
2607 i915_verify_inactive(dev, __FILE__, __LINE__); 2613 i915_verify_inactive(dev, __FILE__, __LINE__);
2608 2614
2609#if WATCH_COHERENCY 2615#if WATCH_COHERENCY
@@ -2866,6 +2872,13 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
2866 return -EBADF; 2872 return -EBADF;
2867 } 2873 }
2868 2874
2875 /* Update the active list for the hardware's current position.
2876 * Otherwise this only updates on a delayed timer or when irqs are
2877 * actually unmasked, and our working set ends up being larger than
2878 * required.
2879 */
2880 i915_gem_retire_requests(dev);
2881
2869 obj_priv = obj->driver_private; 2882 obj_priv = obj->driver_private;
2870 /* Don't count being on the flushing list against the object being 2883 /* Don't count being on the flushing list against the object being
2871 * done. Otherwise, a buffer left on the flushing list but not getting 2884 * done. Otherwise, a buffer left on the flushing list but not getting
@@ -2967,7 +2980,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
2967 return 0; 2980 return 0;
2968} 2981}
2969 2982
2970static int 2983int
2971i915_gem_idle(struct drm_device *dev) 2984i915_gem_idle(struct drm_device *dev)
2972{ 2985{
2973 drm_i915_private_t *dev_priv = dev->dev_private; 2986 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -3130,16 +3143,20 @@ static void
3130i915_gem_cleanup_hws(struct drm_device *dev) 3143i915_gem_cleanup_hws(struct drm_device *dev)
3131{ 3144{
3132 drm_i915_private_t *dev_priv = dev->dev_private; 3145 drm_i915_private_t *dev_priv = dev->dev_private;
3133 struct drm_gem_object *obj = dev_priv->hws_obj; 3146 struct drm_gem_object *obj;
3134 struct drm_i915_gem_object *obj_priv = obj->driver_private; 3147 struct drm_i915_gem_object *obj_priv;
3135 3148
3136 if (dev_priv->hws_obj == NULL) 3149 if (dev_priv->hws_obj == NULL)
3137 return; 3150 return;
3138 3151
3152 obj = dev_priv->hws_obj;
3153 obj_priv = obj->driver_private;
3154
3139 kunmap(obj_priv->page_list[0]); 3155 kunmap(obj_priv->page_list[0]);
3140 i915_gem_object_unpin(obj); 3156 i915_gem_object_unpin(obj);
3141 drm_gem_object_unreference(obj); 3157 drm_gem_object_unreference(obj);
3142 dev_priv->hws_obj = NULL; 3158 dev_priv->hws_obj = NULL;
3159
3143 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); 3160 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3144 dev_priv->hw_status_page = NULL; 3161 dev_priv->hw_status_page = NULL;
3145 3162
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4d2baf7b00be..65b635ce28c8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1008,6 +1008,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
1008 temp = CURSOR_MODE_DISABLE; 1008 temp = CURSOR_MODE_DISABLE;
1009 addr = 0; 1009 addr = 0;
1010 bo = NULL; 1010 bo = NULL;
1011 mutex_lock(&dev->struct_mutex);
1011 goto finish; 1012 goto finish;
1012 } 1013 }
1013 1014