aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c16
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h19
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c8
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c383
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h3
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c9
6 files changed, 42 insertions, 396 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 256e22963ae4..0d215e38606a 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -154,6 +154,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
154 if (I915_NEED_GFX_HWS(dev)) 154 if (I915_NEED_GFX_HWS(dev))
155 i915_free_hws(dev); 155 i915_free_hws(dev);
156 156
157 dev_priv->sarea = NULL;
158 dev_priv->sarea_priv = NULL;
159
157 return 0; 160 return 0;
158} 161}
159 162
@@ -442,7 +445,7 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
442 445
443 BEGIN_LP_RING(4); 446 BEGIN_LP_RING(4);
444 OUT_RING(MI_STORE_DWORD_INDEX); 447 OUT_RING(MI_STORE_DWORD_INDEX);
445 OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); 448 OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
446 OUT_RING(dev_priv->counter); 449 OUT_RING(dev_priv->counter);
447 OUT_RING(0); 450 OUT_RING(0);
448 ADVANCE_LP_RING(); 451 ADVANCE_LP_RING();
@@ -573,7 +576,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
573 576
574 BEGIN_LP_RING(4); 577 BEGIN_LP_RING(4);
575 OUT_RING(MI_STORE_DWORD_INDEX); 578 OUT_RING(MI_STORE_DWORD_INDEX);
576 OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); 579 OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
577 OUT_RING(dev_priv->counter); 580 OUT_RING(dev_priv->counter);
578 OUT_RING(0); 581 OUT_RING(0);
579 ADVANCE_LP_RING(); 582 ADVANCE_LP_RING();
@@ -608,7 +611,6 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
608 struct drm_file *file_priv) 611 struct drm_file *file_priv)
609{ 612{
610 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 613 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
611 u32 *hw_status = dev_priv->hw_status_page;
612 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 614 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
613 dev_priv->sarea_priv; 615 dev_priv->sarea_priv;
614 drm_i915_batchbuffer_t *batch = data; 616 drm_i915_batchbuffer_t *batch = data;
@@ -634,7 +636,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
634 mutex_unlock(&dev->struct_mutex); 636 mutex_unlock(&dev->struct_mutex);
635 637
636 if (sarea_priv) 638 if (sarea_priv)
637 sarea_priv->last_dispatch = (int)hw_status[5]; 639 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
638 return ret; 640 return ret;
639} 641}
640 642
@@ -642,7 +644,6 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
642 struct drm_file *file_priv) 644 struct drm_file *file_priv)
643{ 645{
644 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 646 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
645 u32 *hw_status = dev_priv->hw_status_page;
646 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 647 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
647 dev_priv->sarea_priv; 648 dev_priv->sarea_priv;
648 drm_i915_cmdbuffer_t *cmdbuf = data; 649 drm_i915_cmdbuffer_t *cmdbuf = data;
@@ -670,7 +671,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
670 } 671 }
671 672
672 if (sarea_priv) 673 if (sarea_priv)
673 sarea_priv->last_dispatch = (int)hw_status[5]; 674 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
674 return 0; 675 return 0;
675} 676}
676 677
@@ -849,8 +850,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
849 * be lost or delayed 850 * be lost or delayed
850 */ 851 */
851 if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev)) 852 if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev))
852 if (pci_enable_msi(dev->pdev)) 853 pci_enable_msi(dev->pdev);
853 DRM_ERROR("failed to enable MSI\n");
854 854
855 intel_opregion_init(dev); 855 intel_opregion_init(dev);
856 856
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 572dcd0e3e0d..ef1c0b8f8d07 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -88,13 +88,6 @@ struct mem_block {
88 struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ 88 struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
89}; 89};
90 90
91typedef struct _drm_i915_vbl_swap {
92 struct list_head head;
93 drm_drawable_t drw_id;
94 unsigned int pipe;
95 unsigned int sequence;
96} drm_i915_vbl_swap_t;
97
98struct opregion_header; 91struct opregion_header;
99struct opregion_acpi; 92struct opregion_acpi;
100struct opregion_swsci; 93struct opregion_swsci;
@@ -146,10 +139,6 @@ typedef struct drm_i915_private {
146 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; 139 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
147 int vblank_pipe; 140 int vblank_pipe;
148 141
149 spinlock_t swaps_lock;
150 drm_i915_vbl_swap_t vbl_swaps;
151 unsigned int swaps_pending;
152
153 struct intel_opregion opregion; 142 struct intel_opregion opregion;
154 143
155 /* Register state */ 144 /* Register state */
@@ -157,6 +146,7 @@ typedef struct drm_i915_private {
157 u32 saveDSPACNTR; 146 u32 saveDSPACNTR;
158 u32 saveDSPBCNTR; 147 u32 saveDSPBCNTR;
159 u32 saveDSPARB; 148 u32 saveDSPARB;
149 u32 saveRENDERSTANDBY;
160 u32 savePIPEACONF; 150 u32 savePIPEACONF;
161 u32 savePIPEBCONF; 151 u32 savePIPEBCONF;
162 u32 savePIPEASRC; 152 u32 savePIPEASRC;
@@ -241,9 +231,6 @@ typedef struct drm_i915_private {
241 u8 saveDACDATA[256*3]; /* 256 3-byte colors */ 231 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
242 u8 saveCR[37]; 232 u8 saveCR[37];
243 233
244 /** Work task for vblank-related ring access */
245 struct work_struct vblank_work;
246
247 struct { 234 struct {
248 struct drm_mm gtt_space; 235 struct drm_mm gtt_space;
249 236
@@ -444,7 +431,6 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
444void i915_user_irq_get(struct drm_device *dev); 431void i915_user_irq_get(struct drm_device *dev);
445void i915_user_irq_put(struct drm_device *dev); 432void i915_user_irq_put(struct drm_device *dev);
446 433
447extern void i915_vblank_work_handler(struct work_struct *work);
448extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 434extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
449extern void i915_driver_irq_preinstall(struct drm_device * dev); 435extern void i915_driver_irq_preinstall(struct drm_device * dev);
450extern int i915_driver_irq_postinstall(struct drm_device *dev); 436extern int i915_driver_irq_postinstall(struct drm_device *dev);
@@ -622,8 +608,9 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
622 * The area from dword 0x20 to 0x3ff is available for driver usage. 608 * The area from dword 0x20 to 0x3ff is available for driver usage.
623 */ 609 */
624#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) 610#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
625#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5) 611#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX)
626#define I915_GEM_HWS_INDEX 0x20 612#define I915_GEM_HWS_INDEX 0x20
613#define I915_BREADCRUMB_INDEX 0x21
627 614
628extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); 615extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
629 616
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b0ec73fa6a93..6b4a2bd20640 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1455,11 +1455,9 @@ i915_gem_object_set_domain_range(struct drm_gem_object *obj,
1455 read_domains, write_domain); 1455 read_domains, write_domain);
1456 1456
1457 /* Wait on any GPU rendering to the object to be flushed. */ 1457 /* Wait on any GPU rendering to the object to be flushed. */
1458 if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) { 1458 ret = i915_gem_object_wait_rendering(obj);
1459 ret = i915_gem_object_wait_rendering(obj); 1459 if (ret)
1460 if (ret) 1460 return ret;
1461 return ret;
1462 }
1463 1461
1464 if (obj_priv->page_cpu_valid == NULL) { 1462 if (obj_priv->page_cpu_valid == NULL) {
1465 obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, 1463 obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 26f48932a51e..82752d6177a4 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -80,211 +80,6 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
80 return 0; 80 return 0;
81} 81}
82 82
83/**
84 * Emit blits for scheduled buffer swaps.
85 *
86 * This function will be called with the HW lock held.
87 * Because this function must grab the ring mutex (dev->struct_mutex),
88 * it can no longer run at soft irq time. We'll fix this when we do
89 * the DRI2 swap buffer work.
90 */
91static void i915_vblank_tasklet(struct drm_device *dev)
92{
93 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
94 unsigned long irqflags;
95 struct list_head *list, *tmp, hits, *hit;
96 int nhits, nrects, slice[2], upper[2], lower[2], i;
97 unsigned counter[2];
98 struct drm_drawable_info *drw;
99 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
100 u32 cpp = dev_priv->cpp;
101 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
102 XY_SRC_COPY_BLT_WRITE_ALPHA |
103 XY_SRC_COPY_BLT_WRITE_RGB)
104 : XY_SRC_COPY_BLT_CMD;
105 u32 src_pitch = sarea_priv->pitch * cpp;
106 u32 dst_pitch = sarea_priv->pitch * cpp;
107 u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
108 RING_LOCALS;
109
110 mutex_lock(&dev->struct_mutex);
111
112 if (IS_I965G(dev) && sarea_priv->front_tiled) {
113 cmd |= XY_SRC_COPY_BLT_DST_TILED;
114 dst_pitch >>= 2;
115 }
116 if (IS_I965G(dev) && sarea_priv->back_tiled) {
117 cmd |= XY_SRC_COPY_BLT_SRC_TILED;
118 src_pitch >>= 2;
119 }
120
121 counter[0] = drm_vblank_count(dev, 0);
122 counter[1] = drm_vblank_count(dev, 1);
123
124 DRM_DEBUG("\n");
125
126 INIT_LIST_HEAD(&hits);
127
128 nhits = nrects = 0;
129
130 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
131
132 /* Find buffer swaps scheduled for this vertical blank */
133 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
134 drm_i915_vbl_swap_t *vbl_swap =
135 list_entry(list, drm_i915_vbl_swap_t, head);
136 int pipe = vbl_swap->pipe;
137
138 if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
139 continue;
140
141 list_del(list);
142 dev_priv->swaps_pending--;
143 drm_vblank_put(dev, pipe);
144
145 spin_unlock(&dev_priv->swaps_lock);
146 spin_lock(&dev->drw_lock);
147
148 drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
149
150 list_for_each(hit, &hits) {
151 drm_i915_vbl_swap_t *swap_cmp =
152 list_entry(hit, drm_i915_vbl_swap_t, head);
153 struct drm_drawable_info *drw_cmp =
154 drm_get_drawable_info(dev, swap_cmp->drw_id);
155
156 /* Make sure both drawables are still
157 * around and have some rectangles before
158 * we look inside to order them for the
159 * blts below.
160 */
161 if (drw_cmp && drw_cmp->num_rects > 0 &&
162 drw && drw->num_rects > 0 &&
163 drw_cmp->rects[0].y1 > drw->rects[0].y1) {
164 list_add_tail(list, hit);
165 break;
166 }
167 }
168
169 spin_unlock(&dev->drw_lock);
170
171 /* List of hits was empty, or we reached the end of it */
172 if (hit == &hits)
173 list_add_tail(list, hits.prev);
174
175 nhits++;
176
177 spin_lock(&dev_priv->swaps_lock);
178 }
179
180 if (nhits == 0) {
181 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
182 mutex_unlock(&dev->struct_mutex);
183 return;
184 }
185
186 spin_unlock(&dev_priv->swaps_lock);
187
188 i915_kernel_lost_context(dev);
189
190 if (IS_I965G(dev)) {
191 BEGIN_LP_RING(4);
192
193 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
194 OUT_RING(0);
195 OUT_RING(((sarea_priv->width - 1) & 0xffff) | ((sarea_priv->height - 1) << 16));
196 OUT_RING(0);
197 ADVANCE_LP_RING();
198 } else {
199 BEGIN_LP_RING(6);
200
201 OUT_RING(GFX_OP_DRAWRECT_INFO);
202 OUT_RING(0);
203 OUT_RING(0);
204 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
205 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
206 OUT_RING(0);
207
208 ADVANCE_LP_RING();
209 }
210
211 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
212
213 upper[0] = upper[1] = 0;
214 slice[0] = max(sarea_priv->pipeA_h / nhits, 1);
215 slice[1] = max(sarea_priv->pipeB_h / nhits, 1);
216 lower[0] = sarea_priv->pipeA_y + slice[0];
217 lower[1] = sarea_priv->pipeB_y + slice[0];
218
219 spin_lock(&dev->drw_lock);
220
221 /* Emit blits for buffer swaps, partitioning both outputs into as many
222 * slices as there are buffer swaps scheduled in order to avoid tearing
223 * (based on the assumption that a single buffer swap would always
224 * complete before scanout starts).
225 */
226 for (i = 0; i++ < nhits;
227 upper[0] = lower[0], lower[0] += slice[0],
228 upper[1] = lower[1], lower[1] += slice[1]) {
229 if (i == nhits)
230 lower[0] = lower[1] = sarea_priv->height;
231
232 list_for_each(hit, &hits) {
233 drm_i915_vbl_swap_t *swap_hit =
234 list_entry(hit, drm_i915_vbl_swap_t, head);
235 struct drm_clip_rect *rect;
236 int num_rects, pipe;
237 unsigned short top, bottom;
238
239 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
240
241 /* The drawable may have been destroyed since
242 * the vblank swap was queued
243 */
244 if (!drw)
245 continue;
246
247 rect = drw->rects;
248 pipe = swap_hit->pipe;
249 top = upper[pipe];
250 bottom = lower[pipe];
251
252 for (num_rects = drw->num_rects; num_rects--; rect++) {
253 int y1 = max(rect->y1, top);
254 int y2 = min(rect->y2, bottom);
255
256 if (y1 >= y2)
257 continue;
258
259 BEGIN_LP_RING(8);
260
261 OUT_RING(cmd);
262 OUT_RING(ropcpp | dst_pitch);
263 OUT_RING((y1 << 16) | rect->x1);
264 OUT_RING((y2 << 16) | rect->x2);
265 OUT_RING(sarea_priv->front_offset);
266 OUT_RING((y1 << 16) | rect->x1);
267 OUT_RING(src_pitch);
268 OUT_RING(sarea_priv->back_offset);
269
270 ADVANCE_LP_RING();
271 }
272 }
273 }
274
275 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
276 mutex_unlock(&dev->struct_mutex);
277
278 list_for_each_safe(hit, tmp, &hits) {
279 drm_i915_vbl_swap_t *swap_hit =
280 list_entry(hit, drm_i915_vbl_swap_t, head);
281
282 list_del(hit);
283
284 drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
285 }
286}
287
288/* Called from drm generic code, passed a 'crtc', which 83/* Called from drm generic code, passed a 'crtc', which
289 * we use as a pipe index 84 * we use as a pipe index
290 */ 85 */
@@ -322,40 +117,6 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
322 return count; 117 return count;
323} 118}
324 119
325void
326i915_vblank_work_handler(struct work_struct *work)
327{
328 drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
329 vblank_work);
330 struct drm_device *dev = dev_priv->dev;
331 unsigned long irqflags;
332
333 if (dev->lock.hw_lock == NULL) {
334 i915_vblank_tasklet(dev);
335 return;
336 }
337
338 spin_lock_irqsave(&dev->tasklet_lock, irqflags);
339 dev->locked_tasklet_func = i915_vblank_tasklet;
340 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
341
342 /* Try to get the lock now, if this fails, the lock
343 * holder will execute the tasklet during unlock
344 */
345 if (!drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT))
346 return;
347
348 dev->lock.lock_time = jiffies;
349 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
350
351 spin_lock_irqsave(&dev->tasklet_lock, irqflags);
352 dev->locked_tasklet_func = NULL;
353 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
354
355 i915_vblank_tasklet(dev);
356 drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT);
357}
358
359irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) 120irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
360{ 121{
361 struct drm_device *dev = (struct drm_device *) arg; 122 struct drm_device *dev = (struct drm_device *) arg;
@@ -433,9 +194,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
433 if (iir & I915_ASLE_INTERRUPT) 194 if (iir & I915_ASLE_INTERRUPT)
434 opregion_asle_intr(dev); 195 opregion_asle_intr(dev);
435 196
436 if (vblank && dev_priv->swaps_pending > 0)
437 schedule_work(&dev_priv->vblank_work);
438
439 return IRQ_HANDLED; 197 return IRQ_HANDLED;
440} 198}
441 199
@@ -454,12 +212,10 @@ static int i915_emit_irq(struct drm_device * dev)
454 if (dev_priv->sarea_priv) 212 if (dev_priv->sarea_priv)
455 dev_priv->sarea_priv->last_enqueue = dev_priv->counter; 213 dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
456 214
457 BEGIN_LP_RING(6); 215 BEGIN_LP_RING(4);
458 OUT_RING(MI_STORE_DWORD_INDEX); 216 OUT_RING(MI_STORE_DWORD_INDEX);
459 OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); 217 OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
460 OUT_RING(dev_priv->counter); 218 OUT_RING(dev_priv->counter);
461 OUT_RING(0);
462 OUT_RING(0);
463 OUT_RING(MI_USER_INTERRUPT); 219 OUT_RING(MI_USER_INTERRUPT);
464 ADVANCE_LP_RING(); 220 ADVANCE_LP_RING();
465 221
@@ -696,123 +452,21 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
696int i915_vblank_swap(struct drm_device *dev, void *data, 452int i915_vblank_swap(struct drm_device *dev, void *data,
697 struct drm_file *file_priv) 453 struct drm_file *file_priv)
698{ 454{
699 drm_i915_private_t *dev_priv = dev->dev_private; 455 /* The delayed swap mechanism was fundamentally racy, and has been
700 drm_i915_vblank_swap_t *swap = data; 456 * removed. The model was that the client requested a delayed flip/swap
701 drm_i915_vbl_swap_t *vbl_swap, *vbl_old; 457 * from the kernel, then waited for vblank before continuing to perform
702 unsigned int pipe, seqtype, curseq; 458 * rendering. The problem was that the kernel might wake the client
703 unsigned long irqflags; 459 * up before it dispatched the vblank swap (since the lock has to be
704 struct list_head *list; 460 * held while touching the ringbuffer), in which case the client would
705 int ret; 461 * clear and start the next frame before the swap occurred, and
706 462 * flicker would occur in addition to likely missing the vblank.
707 if (!dev_priv || !dev_priv->sarea_priv) { 463 *
708 DRM_ERROR("%s called with no initialization\n", __func__); 464 * In the absence of this ioctl, userland falls back to a correct path
709 return -EINVAL; 465 * of waiting for a vblank, then dispatching the swap on its own.
710 } 466 * Context switching to userland and back is plenty fast enough for
711 467 * meeting the requirements of vblank swapping.
712 if (dev_priv->sarea_priv->rotation) {
713 DRM_DEBUG("Rotation not supported\n");
714 return -EINVAL;
715 }
716
717 if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
718 _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) {
719 DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype);
720 return -EINVAL;
721 }
722
723 pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
724
725 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
726
727 if (!(dev_priv->vblank_pipe & (1 << pipe))) {
728 DRM_ERROR("Invalid pipe %d\n", pipe);
729 return -EINVAL;
730 }
731
732 spin_lock_irqsave(&dev->drw_lock, irqflags);
733
734 if (!drm_get_drawable_info(dev, swap->drawable)) {
735 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
736 DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
737 return -EINVAL;
738 }
739
740 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
741
742 /*
743 * We take the ref here and put it when the swap actually completes
744 * in the tasklet.
745 */ 468 */
746 ret = drm_vblank_get(dev, pipe); 469 return -EINVAL;
747 if (ret)
748 return ret;
749 curseq = drm_vblank_count(dev, pipe);
750
751 if (seqtype == _DRM_VBLANK_RELATIVE)
752 swap->sequence += curseq;
753
754 if ((curseq - swap->sequence) <= (1<<23)) {
755 if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) {
756 swap->sequence = curseq + 1;
757 } else {
758 DRM_DEBUG("Missed target sequence\n");
759 drm_vblank_put(dev, pipe);
760 return -EINVAL;
761 }
762 }
763
764 vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER);
765
766 if (!vbl_swap) {
767 DRM_ERROR("Failed to allocate memory to queue swap\n");
768 drm_vblank_put(dev, pipe);
769 return -ENOMEM;
770 }
771
772 vbl_swap->drw_id = swap->drawable;
773 vbl_swap->pipe = pipe;
774 vbl_swap->sequence = swap->sequence;
775
776 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
777
778 list_for_each(list, &dev_priv->vbl_swaps.head) {
779 vbl_old = list_entry(list, drm_i915_vbl_swap_t, head);
780
781 if (vbl_old->drw_id == swap->drawable &&
782 vbl_old->pipe == pipe &&
783 vbl_old->sequence == swap->sequence) {
784 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
785 drm_vblank_put(dev, pipe);
786 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
787 DRM_DEBUG("Already scheduled\n");
788 return 0;
789 }
790 }
791
792 if (dev_priv->swaps_pending >= 10) {
793 DRM_DEBUG("Too many swaps queued\n");
794 DRM_DEBUG(" pipe 0: %d pipe 1: %d\n",
795 drm_vblank_count(dev, 0),
796 drm_vblank_count(dev, 1));
797
798 list_for_each(list, &dev_priv->vbl_swaps.head) {
799 vbl_old = list_entry(list, drm_i915_vbl_swap_t, head);
800 DRM_DEBUG("\tdrw %x pipe %d seq %x\n",
801 vbl_old->drw_id, vbl_old->pipe,
802 vbl_old->sequence);
803 }
804 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
805 drm_vblank_put(dev, pipe);
806 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
807 return -EBUSY;
808 }
809
810 list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
811 dev_priv->swaps_pending++;
812
813 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
814
815 return 0;
816} 470}
817 471
818/* drm_dma.h hooks 472/* drm_dma.h hooks
@@ -831,11 +485,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
831 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 485 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
832 int ret, num_pipes = 2; 486 int ret, num_pipes = 2;
833 487
834 spin_lock_init(&dev_priv->swaps_lock);
835 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
836 INIT_WORK(&dev_priv->vblank_work, i915_vblank_work_handler);
837 dev_priv->swaps_pending = 0;
838
839 /* Set initial unmasked IRQs to just the selected vblank pipes. */ 488 /* Set initial unmasked IRQs to just the selected vblank pipes. */
840 dev_priv->irq_mask_reg = ~0; 489 dev_priv->irq_mask_reg = ~0;
841 490
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5c2d9f206d05..0e476eba36e6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -527,6 +527,9 @@
527#define C0DRB3 0x10206 527#define C0DRB3 0x10206
528#define C1DRB3 0x10606 528#define C1DRB3 0x10606
529 529
530/** GM965 GM45 render standby register */
531#define MCHBAR_RENDER_STANDBY 0x111B8
532
530/* 533/*
531 * Overlay regs 534 * Overlay regs
532 */ 535 */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 603fe742ccd4..5ddc6e595c0c 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -240,6 +240,10 @@ int i915_save_state(struct drm_device *dev)
240 240
241 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); 241 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
242 242
243 /* Render Standby */
244 if (IS_I965G(dev) && IS_MOBILE(dev))
245 dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
246
243 /* Display arbitration control */ 247 /* Display arbitration control */
244 dev_priv->saveDSPARB = I915_READ(DSPARB); 248 dev_priv->saveDSPARB = I915_READ(DSPARB);
245 249
@@ -365,6 +369,11 @@ int i915_restore_state(struct drm_device *dev)
365 369
366 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); 370 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
367 371
372 /* Render Standby */
373 if (IS_I965G(dev) && IS_MOBILE(dev))
374 I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
375
376 /* Display arbitration */
368 I915_WRITE(DSPARB, dev_priv->saveDSPARB); 377 I915_WRITE(DSPARB, dev_priv->saveDSPARB);
369 378
370 /* Pipe & plane A info */ 379 /* Pipe & plane A info */